aboutsummaryrefslogtreecommitdiffstats
path: root/infrastructure
diff options
context:
space:
mode:
Diffstat (limited to 'infrastructure')
-rw-r--r--infrastructure/.gitignore5
-rw-r--r--infrastructure/ace/.gitignore1
-rw-r--r--infrastructure/ace/README69
-rwxr-xr-xinfrastructure/ace/bin/make337
-rwxr-xr-xinfrastructure/ace/bin/serve45
-rw-r--r--infrastructure/ace/blog.txt390
-rw-r--r--infrastructure/ace/build/.gitignore2
-rw-r--r--infrastructure/ace/build/index.html47
-rw-r--r--infrastructure/ace/build/jquery-1.2.1.js2992
-rw-r--r--infrastructure/ace/build/testcode.js36
-rw-r--r--infrastructure/ace/easysync-notes.txt129
l---------infrastructure/ace/lib/rhino-js-1.7r1.jar1
l---------infrastructure/ace/lib/yuicompressor-2.4-appjet.jar1
-rw-r--r--infrastructure/ace/notes.txt195
-rw-r--r--infrastructure/ace/www/ace2_common.js115
-rw-r--r--infrastructure/ace/www/ace2_common_dev.js296
-rw-r--r--infrastructure/ace/www/ace2_inner.js4778
-rw-r--r--infrastructure/ace/www/ace2_outer.js214
-rw-r--r--infrastructure/ace/www/ace2_wrapper.js226
-rw-r--r--infrastructure/ace/www/bbtree.js372
-rw-r--r--infrastructure/ace/www/changesettracker.js170
-rw-r--r--infrastructure/ace/www/colorutils.js91
-rw-r--r--infrastructure/ace/www/contentcollector.js509
-rw-r--r--infrastructure/ace/www/cssmanager.js88
-rw-r--r--infrastructure/ace/www/dev.html39
-rw-r--r--infrastructure/ace/www/domline.js210
-rw-r--r--infrastructure/ace/www/easy_sync.js923
-rw-r--r--infrastructure/ace/www/easysync2.js1968
-rw-r--r--infrastructure/ace/www/easysync2_tests.js877
-rw-r--r--infrastructure/ace/www/editor.css109
-rw-r--r--infrastructure/ace/www/firebug/errorIcon.pngbin0 -> 457 bytes
-rw-r--r--infrastructure/ace/www/firebug/firebug.css209
-rw-r--r--infrastructure/ace/www/firebug/firebug.html23
-rw-r--r--infrastructure/ace/www/firebug/firebug.js688
-rw-r--r--infrastructure/ace/www/firebug/firebugx.js26
-rw-r--r--infrastructure/ace/www/firebug/infoIcon.pngbin0 -> 524 bytes
-rw-r--r--infrastructure/ace/www/firebug/warningIcon.pngbin0 -> 516 bytes
-rw-r--r--infrastructure/ace/www/index.html50
-rw-r--r--infrastructure/ace/www/inner.css48
-rw-r--r--infrastructure/ace/www/jquery-1.2.1.js2992
-rw-r--r--infrastructure/ace/www/lang_html.js1685
-rw-r--r--infrastructure/ace/www/lang_js.js102
-rw-r--r--infrastructure/ace/www/lexer_support.js1068
-rw-r--r--infrastructure/ace/www/linestylefilter.js247
-rw-r--r--infrastructure/ace/www/magicdom.js293
-rw-r--r--infrastructure/ace/www/multilang_lexer.js349
-rw-r--r--infrastructure/ace/www/processing.js1714
-rw-r--r--infrastructure/ace/www/profiler.js117
-rw-r--r--infrastructure/ace/www/skiplist.js347
-rw-r--r--infrastructure/ace/www/spanlist.js279
-rw-r--r--infrastructure/ace/www/syntax-new.css35
-rw-r--r--infrastructure/ace/www/syntax.css32
-rw-r--r--infrastructure/ace/www/test.html11
-rw-r--r--infrastructure/ace/www/testcode.js36
-rw-r--r--infrastructure/ace/www/toSource.js274
-rw-r--r--infrastructure/ace/www/undomodule.js258
-rw-r--r--infrastructure/ace/www/virtual_lines.js287
-rwxr-xr-xinfrastructure/bin/classpath.sh21
-rwxr-xr-xinfrastructure/bin/comp.sh199
-rw-r--r--infrastructure/bin/compilecache.sh64
-rwxr-xr-xinfrastructure/bin/jscomp.sh23
-rwxr-xr-xinfrastructure/bin/makejar.sh74
-rwxr-xr-xinfrastructure/bin/makesars.sh23
-rwxr-xr-xinfrastructure/bin/run.sh20
-rw-r--r--infrastructure/com.etherpad.openofficeservice/importexport.scala189
-rw-r--r--infrastructure/com.etherpad/easysync2support.scala167
-rw-r--r--infrastructure/com.etherpad/licensing.scala169
-rw-r--r--infrastructure/com.etherpad/main.scala23
-rw-r--r--infrastructure/framework-src/modules/atomfeed.js72
-rw-r--r--infrastructure/framework-src/modules/blob.js50
-rw-r--r--infrastructure/framework-src/modules/cache_utils.js36
-rw-r--r--infrastructure/framework-src/modules/comet.js91
-rw-r--r--infrastructure/framework-src/modules/dateutils.js48
-rw-r--r--infrastructure/framework-src/modules/dispatch.js149
-rw-r--r--infrastructure/framework-src/modules/ejs.js471
-rw-r--r--infrastructure/framework-src/modules/email.js53
-rw-r--r--infrastructure/framework-src/modules/exceptionutils.js210
-rw-r--r--infrastructure/framework-src/modules/execution.js58
-rw-r--r--infrastructure/framework-src/modules/fastJSON.js27
-rw-r--r--infrastructure/framework-src/modules/faststatic.js318
-rw-r--r--infrastructure/framework-src/modules/fileutils.js108
-rw-r--r--infrastructure/framework-src/modules/funhtml.js158
-rw-r--r--infrastructure/framework-src/modules/global/appjet.js107
-rw-r--r--infrastructure/framework-src/modules/global/request.js312
-rw-r--r--infrastructure/framework-src/modules/global/response.js294
-rw-r--r--infrastructure/framework-src/modules/image.js110
-rw-r--r--infrastructure/framework-src/modules/jsutils.js195
-rw-r--r--infrastructure/framework-src/modules/netutils.js88
-rw-r--r--infrastructure/framework-src/modules/process.js91
-rw-r--r--infrastructure/framework-src/modules/profiler.js48
-rw-r--r--infrastructure/framework-src/modules/sessions.js156
-rw-r--r--infrastructure/framework-src/modules/sqlbase/persistent_vars.js57
-rw-r--r--infrastructure/framework-src/modules/sqlbase/sqlbase.js205
-rw-r--r--infrastructure/framework-src/modules/sqlbase/sqlcommon.js99
-rw-r--r--infrastructure/framework-src/modules/sqlbase/sqlobj.js505
-rw-r--r--infrastructure/framework-src/modules/stringutils.js399
-rw-r--r--infrastructure/framework-src/modules/sync.js81
-rw-r--r--infrastructure/framework-src/modules/timer.js29
-rw-r--r--infrastructure/framework-src/modules/varz.js52
-rw-r--r--infrastructure/framework-src/modules/yuicompressor.js85
-rw-r--r--infrastructure/framework-src/oncomet.js38
-rw-r--r--infrastructure/framework-src/onerror.js24
-rw-r--r--infrastructure/framework-src/onprint.js19
-rw-r--r--infrastructure/framework-src/onrequest.js24
-rw-r--r--infrastructure/framework-src/onreset.js19
-rw-r--r--infrastructure/framework-src/onsars.js27
-rw-r--r--infrastructure/framework-src/onscheduledtask.js33
-rw-r--r--infrastructure/framework-src/onshutdown.js19
-rw-r--r--infrastructure/framework-src/onstartup.js19
-rw-r--r--infrastructure/framework-src/onsyntaxerror.js17
-rw-r--r--infrastructure/framework-src/postamble.js19
-rw-r--r--infrastructure/framework-src/preamble.js325
-rw-r--r--infrastructure/framework-src/syntaxerror.js32
-rw-r--r--infrastructure/lib/activation.jarbin0 -> 56290 bytes
-rw-r--r--infrastructure/lib/c3p0-0.9.1.2.jarbin0 -> 610790 bytes
-rw-r--r--infrastructure/lib/commons-lang-2.4.jarbin0 -> 261809 bytes
-rw-r--r--infrastructure/lib/derby-10.5.1.1.jarbin0 -> 2513361 bytes
-rw-r--r--infrastructure/lib/derbytools.jarbin0 -> 155796 bytes
-rw-r--r--infrastructure/lib/dnsjava-2.0.6.jarbin0 -> 268823 bytes
-rw-r--r--infrastructure/lib/jetty-6.1.20.jarbin0 -> 533605 bytes
-rw-r--r--infrastructure/lib/jetty-sslengine-6.1.20.jarbin0 -> 18285 bytes
-rw-r--r--infrastructure/lib/jetty-util-6.1.20.jarbin0 -> 176016 bytes
-rw-r--r--infrastructure/lib/json.jarbin0 -> 42335 bytes
-rw-r--r--infrastructure/lib/mail.jarbin0 -> 356519 bytes
-rw-r--r--infrastructure/lib/manifest2
-rw-r--r--infrastructure/lib/rhino-js-1.7r1.jarbin0 -> 769000 bytes
-rw-r--r--infrastructure/lib/sanselan-0.94aj.jarbin0 -> 390426 bytes
-rw-r--r--infrastructure/lib/servlet-api-2.5-20081211.jarbin0 -> 134190 bytes
-rw-r--r--infrastructure/lib/tagsoup-1.2.jarbin0 -> 90023 bytes
-rw-r--r--infrastructure/lib/yuicompressor-2.4-appjet.jarbin0 -> 574932 bytes
-rw-r--r--infrastructure/net.appjet.ajstdlib/ajstdlib.scala253
-rw-r--r--infrastructure/net.appjet.ajstdlib/sqlbase.scala563
-rw-r--r--infrastructure/net.appjet.ajstdlib/streaming-client.js920
-rw-r--r--infrastructure/net.appjet.ajstdlib/streaming-iframe.html76
-rw-r--r--infrastructure/net.appjet.ajstdlib/streaming.scala892
-rw-r--r--infrastructure/net.appjet.ajstdlib/timer.scala85
-rw-r--r--infrastructure/net.appjet.bodylock/bodylock.scala291
-rw-r--r--infrastructure/net.appjet.bodylock/compressor.scala269
-rw-r--r--infrastructure/net.appjet.common.cli/cli.scala56
-rw-r--r--infrastructure/net.appjet.common.sars/sars.scala348
-rw-r--r--infrastructure/net.appjet.common.sars/sha1.scala40
-rw-r--r--infrastructure/net.appjet.common/rhino/rhinospect.scala58
-rw-r--r--infrastructure/net.appjet.common/util/BCrypt.java752
-rw-r--r--infrastructure/net.appjet.common/util/BetterFile.java280
-rw-r--r--infrastructure/net.appjet.common/util/ClassReload.java263
-rw-r--r--infrastructure/net.appjet.common/util/ExpiringMapping.java163
-rw-r--r--infrastructure/net.appjet.common/util/HttpServletRequestFactory.java306
-rw-r--r--infrastructure/net.appjet.common/util/LenientFormatter.java2809
-rw-r--r--infrastructure/net.appjet.common/util/LimitedSizeMapping.java28
-rw-r--r--infrastructure/net.appjet.oui/ConfigParam.java25
-rw-r--r--infrastructure/net.appjet.oui/FastJSON.scala171
-rw-r--r--infrastructure/net.appjet.oui/GeneratedConfigParam.java23
-rw-r--r--infrastructure/net.appjet.oui/config.scala240
-rw-r--r--infrastructure/net.appjet.oui/dynamicvar.scala49
-rw-r--r--infrastructure/net.appjet.oui/encryption.scala267
-rw-r--r--infrastructure/net.appjet.oui/execution.scala654
-rw-r--r--infrastructure/net.appjet.oui/files.scala355
-rw-r--r--infrastructure/net.appjet.oui/logging.scala530
-rw-r--r--infrastructure/net.appjet.oui/main.scala386
-rw-r--r--infrastructure/net.appjet.oui/monitoring.scala125
-rw-r--r--infrastructure/net.appjet.oui/network.scala50
-rw-r--r--infrastructure/net.appjet.oui/servermodel.scala209
-rw-r--r--infrastructure/net.appjet.oui/stats.scala220
-rw-r--r--infrastructure/net.appjet.oui/synchronizer.scala69
-rw-r--r--infrastructure/net.appjet.oui/util.scala153
-rw-r--r--infrastructure/rhino1_7R1/apiClasses.properties65
-rw-r--r--infrastructure/rhino1_7R1/build-date1
-rw-r--r--infrastructure/rhino1_7R1/build.properties65
-rw-r--r--infrastructure/rhino1_7R1/build.xml310
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/build.xml61
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/ClassDefinitionException.java53
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/NotAFunctionException.java52
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/PropertyException.java54
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.java367
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.java335
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.java350
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/QName.java321
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java3092
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.java269
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.java754
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.java1617
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.java171
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.java724
-rw-r--r--infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.java125
-rw-r--r--infrastructure/rhino1_7R1/examples/Control.java100
-rw-r--r--infrastructure/rhino1_7R1/examples/Counter.java59
-rw-r--r--infrastructure/rhino1_7R1/examples/CounterTest.java82
-rw-r--r--infrastructure/rhino1_7R1/examples/DynamicScopes.java204
-rw-r--r--infrastructure/rhino1_7R1/examples/E4X/e4x_example.js223
-rw-r--r--infrastructure/rhino1_7R1/examples/File.java348
-rw-r--r--infrastructure/rhino1_7R1/examples/Foo.java169
-rw-r--r--infrastructure/rhino1_7R1/examples/Matrix.java279
-rw-r--r--infrastructure/rhino1_7R1/examples/NervousText.html53
-rw-r--r--infrastructure/rhino1_7R1/examples/NervousText.js109
-rw-r--r--infrastructure/rhino1_7R1/examples/PrimitiveWrapFactory.java72
-rw-r--r--infrastructure/rhino1_7R1/examples/RunScript.java78
-rw-r--r--infrastructure/rhino1_7R1/examples/RunScript2.java69
-rw-r--r--infrastructure/rhino1_7R1/examples/RunScript3.java88
-rw-r--r--infrastructure/rhino1_7R1/examples/RunScript4.java78
-rw-r--r--infrastructure/rhino1_7R1/examples/Shell.java345
-rw-r--r--infrastructure/rhino1_7R1/examples/SwingApplication.js111
-rw-r--r--infrastructure/rhino1_7R1/examples/checkParam.js137
-rw-r--r--infrastructure/rhino1_7R1/examples/enum.js69
-rw-r--r--infrastructure/rhino1_7R1/examples/jsdoc.js556
-rw-r--r--infrastructure/rhino1_7R1/examples/liveConnect.js57
-rw-r--r--infrastructure/rhino1_7R1/examples/unique.js56
-rw-r--r--infrastructure/rhino1_7R1/javadoc/allclasses-frame.html89
-rw-r--r--infrastructure/rhino1_7R1/javadoc/allclasses-noframe.html89
-rw-r--r--infrastructure/rhino1_7R1/javadoc/constant-values.html424
-rw-r--r--infrastructure/rhino1_7R1/javadoc/deprecated-list.html386
-rw-r--r--infrastructure/rhino1_7R1/javadoc/help-doc.html217
-rw-r--r--infrastructure/rhino1_7R1/javadoc/index-all.html1566
-rw-r--r--infrastructure/rhino1_7R1/javadoc/index.html37
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Callable.html224
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassCache.html445
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassShutter.html247
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/CompilerEnvirons.html669
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Context.html3581
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextAction.html214
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.Listener.html236
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.html935
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EcmaError.html455
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ErrorReporter.html299
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EvaluatorException.html405
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Function.html297
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/FunctionObject.html774
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/GeneratedClassLoader.html236
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ImporterTopLevel.html583
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/JavaScriptException.html375
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RefCallable.html233
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RhinoException.html544
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Script.html231
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Scriptable.html756
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ScriptableObject.html2604
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/SecurityController.html507
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Synchronizer.html331
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrapFactory.html400
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrappedException.html323
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Wrapper.html214
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/DebuggableScript.html455
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-frame.html32
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-summary.html156
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-tree.html149
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/ClassCompiler.html461
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-frame.html32
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-summary.html155
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-tree.html151
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-frame.html100
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-summary.html294
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-tree.html185
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableInputStream.html373
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableOutputStream.html458
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-frame.html34
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-summary.html161
-rw-r--r--infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-tree.html163
-rw-r--r--infrastructure/rhino1_7R1/javadoc/overview-frame.html48
-rw-r--r--infrastructure/rhino1_7R1/javadoc/overview-summary.html161
-rw-r--r--infrastructure/rhino1_7R1/javadoc/overview-tree.html196
-rw-r--r--infrastructure/rhino1_7R1/javadoc/package-list4
-rw-r--r--infrastructure/rhino1_7R1/javadoc/resources/inherit.gifbin0 -> 57 bytes
-rw-r--r--infrastructure/rhino1_7R1/javadoc/serialized-form.html1652
-rw-r--r--infrastructure/rhino1_7R1/javadoc/stylesheet.css29
-rw-r--r--infrastructure/rhino1_7R1/lib/jsr173_1.0_api.jarbin0 -> 23630 bytes
-rw-r--r--infrastructure/rhino1_7R1/lib/xbean.jarbin0 -> 2664574 bytes
-rw-r--r--infrastructure/rhino1_7R1/src/build.xml98
-rw-r--r--infrastructure/rhino1_7R1/src/manifest3
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java274
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java3038
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java311
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java553
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java59
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java220
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java89
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java233
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java109
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java2526
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java59
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java594
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java60
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java1271
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java918
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java113
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java88
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java266
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java160
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java106
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java118
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java123
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java84
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java117
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java569
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java66
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java1607
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java55
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java189
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java734
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java318
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java225
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java156
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java221
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java4643
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java192
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java1129
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java935
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java117
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java486
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java136
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java362
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java1727
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java170
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java154
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java1604
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java227
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java169
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java281
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java790
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java260
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java168
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java320
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java85
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java576
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java1002
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java199
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java187
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java399
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java244
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java316
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java221
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java983
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java207
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java1394
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java565
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java388
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java697
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java2554
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java223
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java64
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java59
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java71
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java306
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java73
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java241
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java3830
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java342
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java2428
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java198
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java211
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java80
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java151
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java81
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java436
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java1500
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java659
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java60
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java120
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java183
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java183
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java93
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java58
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java136
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java91
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java61
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java119
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java69
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java84
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java157
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java87
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java615
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java214
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java5031
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java134
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java149
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java311
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java133
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java510
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java2782
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java289
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java541
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java75
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties778
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties329
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java112
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java207
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java132
-rw-r--r--infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java128
-rw-r--r--infrastructure/rhino1_7R1/testsrc/base.skip685
-rw-r--r--infrastructure/rhino1_7R1/testsrc/build.xml183
-rw-r--r--infrastructure/rhino1_7R1/testsrc/opt1.skip26
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/JsDriver.java838
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java346
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/StandardTests.java212
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/results.html105
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/Bug409702Test.java49
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/JavaAcessibilityTest.java99
-rw-r--r--infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/PrivateAccessClass.java89
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/build.xml103
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/ToolErrorReporter.java225
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java1560
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java71
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Main.java431
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/ScopeProvider.java52
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java3547
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/build.xml126
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/CodePrinter.java212
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/FileBody.java191
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/IdValuePair.java58
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java612
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/SwitchGenerator.java491
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java395
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties268
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ConsoleTextArea.java300
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Environment.java141
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Global.java1038
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JSConsole.java225
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java240
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Main.java638
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/QuitAction.java50
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/SecurityProxy.java48
-rw-r--r--infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ShellContextFactory.java114
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/build.xml165
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java367
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java381
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java734
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLCtor.java280
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java606
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java765
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java469
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java812
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java125
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlNode.java869
-rw-r--r--infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlProcessor.java445
-rw-r--r--infrastructure/yuicompressor/lib/jargs-1.0.jarbin0 -> 11406 bytes
-rw-r--r--infrastructure/yuicompressor/lib/rhino-yuicompressor.jarbin0 -> 538064 bytes
-rwxr-xr-xinfrastructure/yuicompressor/make.sh27
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/Bootstrap.java22
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java188
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JarClassLoader.java158
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java1307
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java55
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java28
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java169
-rw-r--r--infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/YUICompressor.java232
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java916
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java.orig910
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java2170
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java.orig2159
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java420
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java.orig417
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java1381
-rw-r--r--infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java.orig1398
450 files changed, 177521 insertions, 0 deletions
diff --git a/infrastructure/.gitignore b/infrastructure/.gitignore
new file mode 100644
index 0000000..8cde493
--- /dev/null
+++ b/infrastructure/.gitignore
@@ -0,0 +1,5 @@
+appjet/
+build/
+buildjs/
+buildcache/
+main.js \ No newline at end of file
diff --git a/infrastructure/ace/.gitignore b/infrastructure/ace/.gitignore
new file mode 100644
index 0000000..4083037
--- /dev/null
+++ b/infrastructure/ace/.gitignore
@@ -0,0 +1 @@
+local
diff --git a/infrastructure/ace/README b/infrastructure/ace/README
new file mode 100644
index 0000000..275684f
--- /dev/null
+++ b/infrastructure/ace/README
@@ -0,0 +1,69 @@
+=====
+ACE2 (originally AppJet Code Editor)
+=====
+
+(This doc started Dec 2009 by dgreenspan.)
+
+ACE2 is EtherPad's editor, a content-editable-based rich text editor
+that supports IE6+, FF(2?/)3+, Safari(3?/)4+. It supports
+collaborative editing using operation transforms (easysync2),
+undo/redo, copy/paste.
+
+The name "ACE2" is because this is a rewrite of aiba's original
+content-editable AppJet Code Editor.
+
+== Building it
+
+In this directory, run `bin/make normal etherpad` (requires scala),
+which generates `build/ace2.js` and copies this and other files into
+the etherpad source tree. To have the script keep running and
+automatically rebuild when source files change, run `bin/make auto
+etherpad`.
+
+The original reason for the build process was that ACE needs to
+construct two nested iframes on the client, and to do this without
+incurring round-trips to the server, it programmatically loads code
+into the outer iframe that loads code into the inner iframe; so the
+bulk of ACE's code is compressed into a string literal (twice). Later
+on, refactoring meant that the source is also divided into more than a
+dozen files that the build script combines, and some are also
+server-side EtherPad modules or client-side libraries (or both).
+
+The master copy of the operational transform (OT) library, easysync2,
+lives here.
+
+In the early days it was possible to run ACE in a sort of development
+mode, without the compression and iframe injection, by running it out
+of the 'www' directory, but this is no longer possible.
+
+== Browser support
+
+We went out of our way to support IE6+. IE's design-mode is quite
+robust, though there are some differences in manipulation of the
+selection and insertion point and in the DOM representation we had to
+use.
+
+We don't support Opera. Opera is a problematic case, because
+apparently JS running in different iframes is run concurrently, not
+linearized into a single event thread. This seems to be a rather
+obscure fact and is almost difficult to believe. As if iframes don't
+complicate scripting enough!
+
+== Syntax highlighting
+
+Though syntax highlighting predated rich text as the original
+motivation for the design of ACE, support was eventually dropped in
+EtherPad. At first the plan was to generalize it to other programming
+languages, but the task was deprioritized (and difficult), and during
+subsequent optimization and refactoring of ACE, calls to the
+incremental lexer were stripped out because they complicated things.
+
+One plan for multi-language syntax highlighting, never implemented,
+was to calculate syntax highlighting on the server as a sort of "style
+overlay" and feed updates to the client along with updates to the
+document text.
+
+== Changeset format
+
+See easysync-notes.txt for some notes on the changeset format, which
+was redesigned with the advent of rich text.
diff --git a/infrastructure/ace/bin/make b/infrastructure/ace/bin/make
new file mode 100755
index 0000000..dad11ff
--- /dev/null
+++ b/infrastructure/ace/bin/make
@@ -0,0 +1,337 @@
+#!/bin/sh
+exec scala -classpath lib/yuicompressor-2.4-appjet.jar:lib/rhino-js-1.7r1.jar $0 $@
+!#
+
+import java.io._;
+
+def superpack(input: String): String = {
+ // this function is self-contained; takes a string, returns an expression
+ // that evaluates to that string
+ // XXX (This compresses well but decompression is too slow)
+
+ // constraints on special chars:
+ // - this string must be able to go in a character class
+ // - each char must be able to go in single quotes
+ val specialChars = "-~@%$#*^_`()|abcdefghijklmnopqrstuvwxyz=!+,.;:?{}";
+ val specialCharsSet:Set[Char] = Set(specialChars:_*);
+ def containsSpecialChar(str: String) = str.exists(specialCharsSet.contains(_));
+
+ val toks:Array[String] = (
+ "@|[a-zA-Z0-9]+|[^@a-zA-Z0-9]{1,3}").r.findAllIn(input).collect.toArray;
+
+ val stringCounts = {
+ val m = new scala.collection.mutable.HashMap[String,Int];
+ def incrementCount(s: String) = { m(s) = m.getOrElse(s, 0) + 1; }
+ for(s <- toks) incrementCount(s);
+ m;
+ }
+
+ val estimatedSavings = scala.util.Sorting.stableSort(
+ for((s,n) <- stringCounts.toArray; savings = s.length*n
+ if (savings > 8 || containsSpecialChar(s)))
+ yield (s,n,savings),
+ (x:(String,Int,Int))=> -x._3);
+
+ def strLast(str: String, n: Int) = str.substring(str.length - n, str.length);
+ // order of encodeNames is very important!
+ val encodeNames = for(n <- 0 until (36*36); c <- specialChars) yield c.toString+strLast("0"+Integer.toString(n, 36).toUpperCase, 2);
+
+ val thingsToReplace:Seq[String] = estimatedSavings.map(_._1);
+ assert(encodeNames.length >= thingsToReplace.length);
+
+ val replacements = Map(thingsToReplace.elements.zipWithIndex.map({
+ case (str, i) => (str, encodeNames(i));
+ }).collect:_*);
+ def encode(tk: String) = if (replacements.contains(tk)) replacements(tk) else tk;
+
+ val afterReplace = toks.map(encode(_)).mkString.replaceAll(
+ "(["+specialChars+"])(?=..[^0-9A-Z])(00|0)", "$1");
+
+ def makeSingleQuotedContents(str: String): String = {
+ str.replace("\\", "\\\\").replace("'", "\\'").replace("<", "\\x3c").replace("\n", "\\n").
+ replace("\r", "\\n").replace("\t", "\\t");
+ }
+
+ val expansionMap = new scala.collection.mutable.HashMap[Char,scala.collection.mutable.ArrayBuffer[String]];
+ for(i <- 0 until thingsToReplace.length; sc = encodeNames(i).charAt(0);
+ e = thingsToReplace(i)) {
+ expansionMap.getOrElseUpdate(sc, new scala.collection.mutable.ArrayBuffer[String]) +=
+ (if (e == "@") "" else e);
+ }
+ val expansionMapLiteral = "{"+(for((sc,strs) <- expansionMap) yield {
+ "'"+sc+"':'"+makeSingleQuotedContents(strs.mkString("@"))+"'";
+ }).mkString(",")+"}";
+
+ val expr = ("(function(m){m="+expansionMapLiteral+
+ ";for(var k in m){if(m.hasOwnProperty(k))m[k]=m[k].split('@')};return '"+
+ makeSingleQuotedContents(afterReplace)+
+ "'.replace(/(["+specialChars+
+ "])([0-9A-Z]{0,2})/g,function(a,b,c){return m[b][parseInt(c||'0',36)]||'@'})}())");
+ /*val expr = ("(function(m){m="+expansionMapLiteral+
+ ";for(var k in m){if(m.hasOwnProperty(k))m[k]=m[k].split('@')};"+
+ "var result=[];var i=0;var s='"+makeSingleQuotedContents(afterReplace)+
+ "';var len=s.length;while (i<len) {var x=s.charAt(i); var L=m[x],a = s.charAt(i+1),b = s.charAt(i+2);if (L) { var c;if (!(a >= 'A' && a <= 'Z' || a >= '0' && a <= '9')) {c=L[0];i++} else if (!(b >= 'A' && b <= 'Z' || b >= '0' && b <= '9')) {c = L[parseInt(a,36)]; i+=2} else {c = L[parseInt(a+b,36)]; i+=3}; result.push(c||'@'); } else {result.push(x); i++} }; return result.join(''); }())");*/
+
+ def evaluateString(js: String): String = {
+ import org.mozilla.javascript._;
+ ContextFactory.getGlobal.call(new ContextAction {
+ def run(cx: Context) = {
+ val scope = cx.initStandardObjects;
+ cx.evaluateString(scope, js, "<cmd>", 1, null) } }).asInstanceOf[String];
+ }
+
+ def putFile(str: String, path: String): Unit = {
+ import java.io._;
+ val writer = new FileWriter(path);
+ writer.write(str);
+ writer.close;
+ }
+
+ val exprOut = evaluateString(expr);
+ if (exprOut != input) {
+ putFile(input, "/tmp/superpack.input");
+ putFile(expr, "/tmp/superpack.expr");
+ putFile(exprOut, "/tmp/superpack.output");
+ error("Superpacked string does not evaluate to original string; check /tmp/superpack.*");
+ }
+
+ val singleLiteral = "'"+makeSingleQuotedContents(input)+"'";
+ if (singleLiteral.length < expr.length) {
+ singleLiteral;
+ }
+ else {
+ expr;
+ }
+}
+
+def doMake {
+
+ lazy val isEtherPad = (args.length >= 2 && args(1) == "etherpad");
+ lazy val isNoHelma = (args.length >= 2 && args(1) == "nohelma");
+
+ def getFile(path:String): String = {
+ val builder = new StringBuilder(1000);
+ val reader = new BufferedReader(new FileReader(path));
+ val buf = new Array[Char](1024);
+ var numRead = 0;
+ while({ numRead = reader.read(buf); numRead } != -1) {
+ builder.append(buf, 0, numRead);
+ }
+ reader.close;
+ return builder.toString;
+ }
+
+ def putFile(str: String, path: String): Unit = {
+ val writer = new FileWriter(path);
+ writer.write(str);
+ writer.close;
+ }
+
+ def writeToString(func:(Writer=>Unit)): String = {
+ val writer = new StringWriter;
+ func(writer);
+ return writer.toString;
+ }
+
+ def compressJS(code: String, wrap: Boolean): String = {
+ import yuicompressor.org.mozilla.javascript.{ErrorReporter, EvaluatorException};
+ object MyErrorReporter extends ErrorReporter {
+ def warning(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+ if (message startsWith "Try to use a single 'var' statement per scope.") return;
+ if (line < 0) System.err.println("\n[WARNING] " + message);
+ else System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+ }
+ def error(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+ if (line < 0) System.err.println("\n[ERROR] " + message);
+ else System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+ }
+ def runtimeError(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int): EvaluatorException = {
+ error(message, sourceName, line, lineSource, lineOffset);
+ return new EvaluatorException(message);
+ }
+ }
+
+ val munge = true;
+ val verbose = false;
+ val optimize = true;
+ val compressor = new com.yahoo.platform.yui.compressor.JavaScriptCompressor(new StringReader(code), MyErrorReporter);
+ return writeToString(compressor.compress(_, if (wrap) 100 else -1, munge, verbose, true, !optimize));
+ }
+
+ def compressCSS(code: String, wrap: Boolean): String = {
+ val compressor = new com.yahoo.platform.yui.compressor.CssCompressor(new StringReader(code));
+ return writeToString(compressor.compress(_, if (wrap) 100 else -1));
+ }
+
+ import java.util.regex.{Pattern, Matcher, MatchResult};
+
+ def stringReplace(orig: String, regex: String, groupReferences:Boolean, func:(MatchResult=>String)): String = {
+ val buf = new StringBuffer;
+ val m = Pattern.compile(regex).matcher(orig);
+ while (m.find) {
+ var str = func(m);
+ if (! groupReferences) {
+ str = str.replace("\\", "\\\\").replace("$", "\\$");
+ }
+ m.appendReplacement(buf, str);
+ }
+ m.appendTail(buf);
+ return buf.toString;
+ }
+
+ def stringToExpression(str: String): String = {
+ var contents = str.replace("\\", "\\\\").replace("'", "\\'").replace("<", "\\x3c").replace("\n", "\\n").
+ replace("\r", "\\n").replace("\t", "\\t");
+ contents = contents.replace("\\/", "\\\\x2f"); // for Norton Internet Security
+ val result = "'"+contents+"'";
+ result;
+ }
+
+ val srcDir = "www";
+ val destDir = "build";
+ var code = getFile(srcDir+"/ace2_outer.js");
+
+ val useCompression = true; //if (isEtherPad) false else true;
+
+ code = stringReplace(code, "\\$\\$INCLUDE_([A-Z_]+)\\([\"']([^\"']+)[\"']\\)", false, (m:MatchResult) => {
+ val includeType = m.group(1);
+ val paths = m.group(2);
+ val pathsArray = paths.replaceAll("""/\*.*?\*/""", "").split(" +").filter(_.length > 0);
+ def getSubcode = pathsArray.map(p => getFile(srcDir+"/"+p)).mkString("\n");
+ val doPack = (stringToExpression _);
+ includeType match {
+ case "JS" => {
+ var subcode = getSubcode;
+ subcode = subcode.replaceAll("var DEBUG=true;//\\$\\$[^\n\r]*", "var DEBUG=false;");
+ if (useCompression) subcode = compressJS(subcode, true);
+ "('\\x3cscript type=\"text/javascript\">//<!--\\n'+" + doPack(subcode) +
+ "+'//-->\\n</script>')";
+ }
+ case "CSS" => {
+ var subcode = getSubcode;
+ if (useCompression) subcode = compressCSS(subcode, false);
+ "('<style type=\"text/css\">'+" + doPack(subcode) + "+'</style>')";
+ }
+ case "JS_Q" => {
+ var subcode = getSubcode
+ subcode = subcode.replaceAll("var DEBUG=true;//\\$\\$[^\n\r]*", "var DEBUG=false;");
+ if (useCompression) subcode = compressJS(subcode, true);
+ "('(\\'\\\\x3cscript type=\"text/javascript\">//<!--\\\\n\\'+'+" +
+ doPack(stringToExpression(subcode)) +
+ "+'+\\'//-->\\\\n\\\\x3c/script>\\')')";
+ }
+ case "CSS_Q" => {
+ var subcode = getSubcode;
+ if (useCompression) subcode = compressCSS(subcode, false);
+ "('(\\'<style type=\"text/css\">\\'+'+" + doPack(stringToExpression(subcode)) +
+ "+'+\\'\\\\x3c/style>\\')')";
+ }
+ case ("JS_DEV" | "CSS_DEV") => "''";
+ case ("JS_Q_DEV" | "CSS_Q_DEV") => "'\\'\\''";
+ //case _ => "$$INCLUDE_"+includeType+"(\"../www/"+path+"\")";
+ }
+ });
+
+ if (useCompression) code = compressJS(code, true);
+
+ putFile(code, destDir+"/ace2bare.js");
+
+ //var wrapper = getFile(srcDir+"/ace2_wrapper.js");
+ //if (useCompression) wrapper = compressJS(wrapper, true);
+ putFile(/*wrapper+"\n"+*/code, destDir+"/ace2.js");
+
+ var index = getFile(srcDir+"/index.html");
+ index = index.replaceAll("<!--\\s*DEBUG\\s*-->\\s*([\\s\\S]+?)\\s*<!--\\s*/DEBUG\\s*-->", "");
+ index = index.replaceAll("<!--\\s*PROD:\\s*([\\s\\S]+?)\\s*-->", "$1");
+ putFile(index, destDir+"/index.html");
+
+ putFile(getFile(srcDir+"/testcode.js"), destDir+"/testcode.js");
+
+ def copyFile(fromFile: String, toFile: String) {
+ if (0 != Runtime.getRuntime.exec("cp "+fromFile+" "+toFile).waitFor) {
+ printf("copy failed (%s -> %s).\n", fromFile, toFile);
+ }
+ }
+
+ def replaceFirstLine(txt: String, newFirstLine: String): String = {
+ var newlinePos = txt.indexOf('\n');
+ newFirstLine + txt.substring(newlinePos);
+ }
+
+ if (isEtherPad) {
+ copyFile("build/ace2.js", "../../etherpad/src/static/js/ace.js");
+
+ def copyFileToEtherpad(fromName: String, toName: String) {
+ var code = getFile(srcDir+"/"+fromName);
+ code = replaceFirstLine(code, "// DO NOT EDIT THIS FILE, edit "+
+ "infrastructure/ace/www/"+fromName);
+ code = code.replaceAll("""(?<=\n)\s*//\s*%APPJET%:\s*""", "");
+ putFile(code, "../../etherpad/src/etherpad/collab/ace/"+toName);
+ }
+ def copyFileToClientSide(fromName: String, toName: String) {
+ var code = getFile(srcDir+"/"+fromName);
+ code = replaceFirstLine(code, "// DO NOT EDIT THIS FILE, edit "+
+ "infrastructure/ace/www/"+fromName);
+ code = code.replaceAll("""(?<=\n)\s*//\s*%APPJET%:.*?\n""", "");
+ code = code.replaceAll("""(?<=\n)\s*//\s*%CLIENT FILE ENDS HERE%[\s\S]*""",
+ "");
+ putFile(code, "../../etherpad/src/static/js/"+toName);
+ }
+
+ copyFileToEtherpad("easy_sync.js", "easysync1.js");
+ copyFileToEtherpad("easysync2.js", "easysync2.js");
+ copyFileToEtherpad("contentcollector.js", "contentcollector.js");
+ copyFileToEtherpad("easysync2_tests.js", "easysync2_tests.js");
+ copyFileToClientSide("colorutils.js", "colorutils.js");
+ copyFileToClientSide("easysync2.js", "easysync2_client.js");
+ copyFileToEtherpad("linestylefilter.js", "linestylefilter.js");
+ copyFileToClientSide("linestylefilter.js", "linestylefilter_client.js");
+ copyFileToEtherpad("domline.js", "domline.js");
+ copyFileToClientSide("domline.js", "domline_client.js");
+ copyFileToClientSide("cssmanager.js", "cssmanager_client.js");
+ }
+ /*else if (! isNoHelma) {
+ copyFile("build/ace2.js", "../helma_apps/appjet/protectedStatic/js/ace.js");
+ }*/
+}
+
+def remakeLoop {
+
+ def getStamp: Long = {
+ return (new java.io.File("www").listFiles.
+ filter(! _.getName.endsWith("~")).
+ filter(! _.getName.endsWith("#")).
+ filter(! _.getName.startsWith(".")).map(_.lastModified).
+ reduceLeft(Math.max(_:Long,_:Long)));
+ }
+
+ var madeStamp:Long = 0;
+ var errorStamp:Long = 0;
+ while (true) {
+ Thread.sleep(500);
+ val s = getStamp;
+ if (s > madeStamp && s != errorStamp) {
+ Thread.sleep(1000);
+ if (getStamp == s) {
+ madeStamp = s;
+ print("Remaking... ");
+ try {
+ doMake;
+ println("OK");
+ }
+ catch { case e => {
+ println("ERROR");
+ errorStamp = s;
+ } }
+ }
+ }
+ }
+
+}
+
+if (args.length >= 1 && args(0) == "auto") {
+ remakeLoop;
+}
+else {
+ doMake;
+}
diff --git a/infrastructure/ace/bin/serve b/infrastructure/ace/bin/serve
new file mode 100755
index 0000000..e02e042
--- /dev/null
+++ b/infrastructure/ace/bin/serve
@@ -0,0 +1,45 @@
+#!/bin/bash
+scala -nocompdaemon -Dlog4j.mortbay.loglevel=WARN -classpath lib/jetty-6.1.7.jar:lib/jetty-util-6.1.7.jar:lib/servlet-api-2.5-6.1.3.jar $0 $@ &
+exit
+!#
+
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.mortbay.jetty.servlet.DefaultServlet;
+import javax.servlet.http.{HttpServletRequest, HttpServletResponse};
+
+object NonCachingDefaultServlet extends DefaultServlet() {
+
+ private def setHeaders(response:HttpServletResponse) {
+ response.setHeader("Cache-Control","no-cache"); // for HTTP 1.1
+ response.setHeader("Pragma","no-cache"); //for HTTP 1.0
+ response.setDateHeader ("Expires", 0); //for proxy server
+ response.setHeader("Cache-Control","no-store"); //HTTP 1.1
+ }
+
+ override def doGet(request:HttpServletRequest, response:HttpServletResponse) {
+ setHeaders(response);
+ super.doGet(request, response);
+ }
+
+ override def doHead(request:HttpServletRequest, response:HttpServletResponse) {
+ setHeaders(response);
+ super.doHead(request, response);
+ }
+}
+
+val port = if (args.length >= 1) args(0).toInt else 80;
+val dir = if (args.length >= 2) args(1) else "www";
+
+val server = new Server(port);
+
+val context = new Context(server, "/", Context.SESSIONS);
+context.setResourceBase(dir+"/");
+context.addServlet(new ServletHolder(NonCachingDefaultServlet), "/");
+context.setWelcomeFiles(Array[String]("index.html"));
+
+println("pid: "+java.lang.management.ManagementFactory.getRuntimeMXBean.getName.split("@")(0));
+
+server.start();
+server.join();
diff --git a/infrastructure/ace/blog.txt b/infrastructure/ace/blog.txt
new file mode 100644
index 0000000..0b095a2
--- /dev/null
+++ b/infrastructure/ace/blog.txt
@@ -0,0 +1,390 @@
+ACE.js: In-Browser Code Editing Finally Solved
+
+You may have seen them around -- "in-browser code editors" are text
+editors that run on the web in your browser, supporting editing,
+syntax highlighting, indentation, and other features familiar from a
+desktop editor/IDE like Emacs, Eclipse, or TextMate. Compared to
+desktop editors, the in-browser knock-offs I've seen leave me quite
+dissatisfied. I can deal with the lack of power-user features, but
+just in terms of basic usability, these web-based editors are
+sputtering at the starting line. On the whole, they feel unresponsive
+on small files, they slow to a crawl on large files, and they tend to
+have unaddressed quirks, artifacts, and differences from native
+appearance and behavior. Anyway, that's enough negativity; I have a
+lot of respect for the authors and their hard work, and in writing ACE
+I'm standing on their shoulders. But I was curious to see if I could
+take AppJet's editor to the next level and approach the speed and
+robustness of a desktop editor. After a few months of work, I'm proud
+to declare success.
+
+Here's a walk-through of ACE.js, our new in-browser code editor.
+ACE.js is a self-contained, cross-browser JavaScript file that allows
+a web page to embed scrolling panes of editable code. Typing text is
+snappy and there are no visual artifacts or clutter.
+Syntax-highlighting happens live, as you type. Amazingly, operations
+scale up well with document size. You can paste in 1,000 lines of
+text, or more, and after a second or two of thought, the editor is
+fully responsive again. While you keep typing, it unobtrusively
+finishes syntax-highlighting the whole buffer in a matter of seconds.
+Local edits to the text are just as fast on long documents as on short
+ones. Changes that require large-scale re-highlighting, like opening
+or closing a multi-line comment, affect the text in view almost
+instantaneously, and then ACE.js quitely goes to work on the rest of
+the document over the next few seconds without holding you up. ACE.js
+supports advanced features like Emacs-style unlimited undo, flashing
+matching parentheses as you type them or move across them, and basic
+auto-indentation. Full functionality is supported across Internet
+Explorer 6+, Firefox 2+, Safari 3+, and Camino 1.5+.
+
+I've emphasized "scalability" a lot so far, by which I mean efficiency
+and responsiveness in the face of large documents, because that's the
+aspect of ACE that so clearly sets it apart. But that's only one of
+three "axes" that the ultimate editor needs to excel on.
+
+The second is what I'll call "nativity", meaning how close the editor
+comes to the gold standard of the desktop editor experience. This
+includes responsiveness (some in-browser editors have sluggish typing
+even on small documents), but also things like undo, copy/paste,
+selection, arrow-keys, shift-arrow-keys, different input methods and
+devices, and so on.
+
+The third axis is "flexibility". How easy is it to add features? To
+support more languages for the incremental highlighting, different
+undo models, different indentation schemes, macros that expand as you
+type, auto-complete, go-to-line by number, and whatever else you can
+imagine.
+
+Why am I lecturing you on these theoretical principles? Well, there's
+an interesting insight that explains a lot about the existing crop of
+editors, and it isn't one you'd hit upon without spending a lot of
+time in the trenches (yes, specifically the trenches of writing an
+in-browser code editor). Based on the hodge-podge of facilities that
+browsers happen to make available, you basically end up with the
+following slogan: "scalability, nativity, flexibility, pick any two".
+Based on this, we can classify editors into three types, which I'll
+describe briefly from the point of view of someone writing an editor
+(like me); if you're not familiar with browser scripting, hopefully
+this won't be too hard to get through.
+
+Type I editors sacrifice scalability. The typical implementation is a
+text-area to handle the typing, covered by a block of colored text to
+handle the display. You (the person making the editor) get a boost in
+nativity at the start, because you inherit the browser's text
+handling, all the stuff I mentioned above, like undo and copy/paste.
+The degree of flexibility is also good, because you can style the
+colored text independently of the editing in the textarea, and you can
+manipulate the textarea easily, such as by assigning a new content
+string. Unfortunately, this scales quite badly with document size.
+The good Type I editors are slick and responsive, but pretty limited
+in how large files can get.
+
+Type II editors sacrifice nativity. This is the kind of editor where
+you manually manipulate document (DOM) nodes as the user types. You
+have to re-implement the desktop's native editing behavior from
+scratch, first putting in support for typing and selecting text (both
+by mouse and keyboard), and hopefully eventually supporting undo and
+copy/paste with other programs (through some elaborate hack). This
+type is attractive because it offers unlimited flexibility, and
+theoretical scalability. In practice, you end up with mostly
+flexibility, because getting the nativity right is such a huge task,
+and scalability takes a back seat to general responsiveness. Type II
+editors are fancy but feel slow and quirky.
+
+Type III editors, as you've probably guessed by now, are the category
+ACE falls into, and are the ones that sacrifice flexibility, the third
+axis, though in fact they make you work for all three axes. The crazy
+idea here, which seems to have originated with Dutch programmer Marijn
+Haverbeke, is to take advantage of a browser feature called "design
+mode" (or "content editable"), a mode which allows the user to
+directly edit an HTML document. This feature has quietly been added
+to all major browsers over time. In fact, it's what GMail uses to let
+users compose rich-text e-mail. The advantages of basing an editor on
+a design-mode buffer are that such a buffer has a full DOM (document
+model), which allows arbitrary styling and swapping of parts of the
+document, and that native editing operations (selection, copy/paste)
+are mapped by the browser onto operations on the DOM.
+
+What's the downside of a Type III editor? It's a nightmare to
+implement! GMail skirts the issue by only using hard-coded browser
+commands like "make the selection bold" or "insert unordered list".
+What happens if you stray from this set of basic commands, and access
+that alluring DOM directly, without careful preparation? Disaster!
+Building a robust, extensible editor on top of design mode is kind of
+like landing a man safely on the moon, where you design the
+spacecraft, the mission control computer, and the pressurized suit.
+You're constantly trying to insulate yourself from a hostile
+environment.
+
+More specifically, any change your editor makes to the design mode DOM
+causes the browser to instantly lose track of the selection range or
+insertion point if any, the undo history, and basically any other
+useful editing state. (This can be worked around with a lot of
+selection manipulation, though IE in particular lacks even a way to
+access the current selection relative to the DOM.) A simple edit like
+the user pressing the "enter" key to start a new line may cause the
+browser to insert a line break tag (BR), or split a block element into
+two, whatever it wishes. Pasted text is converted into HTML, through
+a somewhat arbitrary process, and inserted into the document. In
+fact, the DOM is constantly being modified by the browser in response
+to user actions (like typing), and you have to peek at it and
+efficiently make sense of it, determine what's changed, incorporate it
+into your representation, make any of your own changes (e.g. indent a
+line), modify the DOM to display your changes to the user, and have it
+all look like nothing special happened. A more Draconian policy for
+dealing with the browser, like trapping all mouse and key events,
+would just leave you with a Type II editor. The key is to treat the
+DOM as a hugely complicated I/O device between you and the browser,
+and carefully make rules to constrain it.
+
+You also deal with the fact that design mode's "native" behavior is
+HTML-oriented, not text-oriented, and the fact that it tends to have a
+lot of quirks and bugs. You don't get scalability for free, either,
+you need some clever data structures. For example, determining the
+absolute line number of the blinking insertion point is an
+order-of-document-size operation without the aid of efficient data
+structures that can be maintained as the document changes.
+
+The plus side is that once you've systematically beat design mode into
+submission, you can have an unmatched degree of scalability and
+nativity. From there, it's just a matter of keeping your layers of
+abstraction scalable, and being aware of "nativity"-style constraints
+(like responsiveness and events), and you can build up to flexibility,
+the crown jewel. The reward is how easy it is to add new editor
+features!
+
+Speaking of which, here is a list of current ACE features. Some of
+them are small and just required recognizing their benefit, while
+others are more significant. Some features, like "Emacs-style undo"
+and "highlight matching parentheses", are significant despite having
+been implemented in a couple hours each, and are signs of what's to
+come in the future of ACE.
+
+General
+ - Numbered lines
+ - Correct vert/horiz scroll-bar behavior
+ - Handles large documents (thousands of lines, but see "quirks")
+Browser support
+ - Internet Explorer 6+, Firefox 2+, Safari 3+, Camino 1.5+
+ - Text size scales with page when changed by user
+Syntax highlighting
+ - Correct JavaScript syntax (including regular expression subtleties)
+ - Extensible for other programming languages
+ - Incremental rehighlighting with minimal recalculation for each edit
+ - Highlight live as you type
+ - Moves highlighting task to background if not finished right away
+Editing
+ - Emacs-style unlimited undo
+ - Native copy/paste, within editor and with other programs
+ - Highlight matching (or mis-matched) parentheses, brackets, and braces
+ - Basic auto-indentation
+ - Multi-stroke international characters on Mac
+Interface
+ - Import/export text string
+ - Toggle editor between ACE and textarea
+ - Resize, focus, register key event handlers
+ - Multiple ACE editors allowed per page
+ - Packaged in one JavaScript file
+ - Can be created inside an iframe, any domain, any nesting
+Future
+ - Super-extensible
+ - More languages?
+ - Smarter auto-indentation?
+ - Indent/unindent selection?
+ - Auto-complete?
+ - Macros?
+ - User extensibility, a la Emacs??
+Bugs/Quirks
+ - Firefox 2/3: Document height and width are limited to 32767 pixels
+ (about 2,045 lines of text at default text size) due to Firefox bug,
+ not scheduled for resolution for FF3 launch
+
+======
+
+>> TO ADD:
+ - link to demo
+ - what to {say,ask} about {interest, use, licensing, source}?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ACE.js: In-Browser Code Editing Finally Solved
+
+You may have seen them around -- "in-browser code editors" are text
+editors that run over the web in a browser, supporting editing, syntax
+highlighting, indentation, and other features familiar from a desktop
+editor/IDE like Emacs, Eclipse, or TextMate. Compared to desktop
+editors, the in-browser knock-offs that I've seen leave me very
+dissatisfied. I can deal without the power-user features, but just in
+terms of basic usability, these web-based editors are sputtering at
+the starting line. On the whole, they feel unresponsive on small
+files, they slow to a crawl on large files, and they tend to have
+unaddressed quirks, artifacts, and differences from native appearance
+and behavior. Anyway, that's enough negativity; I have a lot of
+respect for the authors and their hard work, and in writing ACE I'm
+standing on their shoulders. But you see, I tend to approach projects
+like this with super-high standards, dangerously so even. Luckily,
+after months of work here at AppJet, there's a happy ending.
+
+[[="I tend to approach projects with super-high standards" is a bit awkward - sounds like tooting your own horn too much for my taste=]]
+
+Here's a walk-through of ACE.js, our new in-browser code editor. It's
+[[="it" the walkthrough? or "it" the browser?=]]
+written in self-contained, cross-browser JavaScript that can be
+dropped into any web page. It looks and feels a lot like a "native"
+editor, meaning typing is fast and there are no artifacts or clutter.
+It does syntax-highlighting live, as you type. Amazingly, it scales
+up with document size. You can paste in 1,000 lines of text, or more,
+and after a second or two of thought, the editor is fully responsive
+again. While you keep typing, it unobtrusively finishes
+syntax-highlighting the whole buffer in a matter of seconds. Local
+edits to the text are just as fast on long documents as on short ones.
+Changes that require large-scale re-highlighting, like opening or
+closing a multi-line comment, affect the text in view almost
+instantaneously, and then ACE quitely goes to work on the rest of the
+document over the next few seconds without holding you up. Advanced
+features include Emacs-style unlimited undo, flashing matching
+parentheses as you type them or move across them, and basic
+auto-indentation. Full functionality is supported on Internet
+Explorer 6+, Firefox 2+, Safari 3+, and Camino 1.5+.
+
+I've emphasized "scalability" a lot so far, by which I mean efficiency
+and responsiveness in the face of large documents, because that's the
+aspect of ACE that so clearly sets it apart. But that's only one of
+three "axes" that the ultimate editor needs to excel on.
+
+The second is what I'll call "nativity", meaning how close the editor
+comes to the gold standard of the desktop editor experience. This
+includes responsiveness (some in-browser editors have sluggish typing
+even on small documents), but also things like undo, copy/paste,
+selection, arrow-keys, shift-arrow-keys, different input methods and
+devices, and so on.
+
+The third axis is "flexibility". How easy is it to add features? To
+support more languages for the incremental highlighting, different
+undo models, different indentation schemes, macros that expand as you
+type, auto-complete, go-to-line by number, and whatever else you can
+imagine.
+
+Why am I lecturing you on these theoretical principles? Well, there's
+an interesting insight that explains a lot about the existing crop of
+editors, and it isn't one you'd hit upon without spending a lot of
+time in the trenches (yes, specifically the trenches of writing an
+in-browser code editor). Based on the hodge-podge of facilities that
+browsers happen to make available, you basically end up with the
+following slogan: "scalability, nativity, flexibility, pick any two".
+Based on this, we can classify editors into three types, which I'll
+describe briefly from the point of view of someone writing an editor
+(like me); if you're not familiar with browser scripting, hopefully
+this won't be too hard to get through.
+
+[[= I'm not a huge fan of "type I-II-III" nomenclature. It's totally opaque. And in this case, they don't even form a continuum, except for type III being better than I and II. =]]
+
+Type I editors sacrifice scalability. The typical implementation is a
+text-area to handle the typing, covered by a block of colored text to
+handle the display. You (the person making the editor) get a boost in
+nativity at the start, because you inherit the browser's text
+handling, all the stuff I mentioned above, like undo and copy/paste.
+The degree of flexibility is also good, because you can style the
+colored text independently of the editing in the textarea, and you can
+manipulate the textarea easily, such as by assigning a new content
+string. Unfortunately, this scales quite badly with document size.
+The good Type I editors are slick and responsive, but pretty limited
+in how large files can get.
+
+Type II editors sacrifice nativity. This is the kind of editor where
+you manually manipulate document (DOM) nodes as the user types. You
+have to re-implement the desktop's native editing behavior from
+scratch, first putting in support for typing and selecting text (both
+by mouse and keyboard), and hopefully eventually supporting undo and
+copy/paste with other programs (through some elaborate hack). This
+type is attractive because it offers unlimited flexibility, and
+theoretical scalability. In practice, you end up with mostly
+flexibility, because getting the nativity right is such a huge task,
+and scalability takes a back seat to general responsiveness. Type II
+editors are fancy but feel slow and quirky.
+
+Type III editors, as you've probably guessed by now, are the category
+ACE falls into, and are the ones that sacrifice flexibility, the third
+axis, though in fact they make you work for all three axes. The crazy
+idea here, which seems to have originated with Dutch programmer Marijn
+Haverbeke, is to take advantage of a browser feature called "design
+mode" (or "content editable"), a mode which allows the user to
+directly edit an HTML document. This feature has quietly been added
+to all major browsers over time. In fact, it's what GMail uses to let
+users compose rich-text e-mail. The advantages of basing an editor on
+a design-mode buffer are that such a buffer has a full DOM (document
+model), which allows arbitrary styling and swapping of parts of the
+document, and that native editing operations (selection, copy/paste)
+are mapped by the browser onto operations on the DOM.
+
+[[= It's not clear how Type III editors sacrifice flexibility =]]
+
+What's the downside of a Type III editor? It's a nightmare to
+implement! GMail skirts the issue by only using hard-coded browser
+commands like "make the selection bold" or "insert unordered list".
+What happens if you stray from this set of basic commands, and access
+that alluring DOM directly, without careful preparation? Disaster!
+Building a robust, extensible editor on top of design mode is kind of
+like landing a man safely on the moon, where you design the
+spacecraft, the mission control computer, and the pressurized suit.
+You're constantly trying to insulate yourself from a hostile
+environment.
+
+More specifically, any change your editor makes to the design mode DOM
+causes the browser to instantly lose track of the selection range or
+insertion point if any, the undo history, and basically any other
+useful editing state. (This can be worked around with a lot of
+selection manipulation, though IE in particular lacks even a way to
+access the current selection relative to the DOM.) A simple edit like
+the user pressing the "enter" key to start a new line may cause the
+browser to insert a line break tag (BR), or split a block element into
+two, whatever it wishes. Pasted text is converted into HTML, through
+a somewhat arbitrary process, and inserted into the document. In
+fact, the DOM is constantly being modified by the browser in response
+to user actions (like typing), and you have to peek at it and
+efficiently make sense of it, determine what's changed, incorporate it
+into your representation, make any of your own changes (e.g. indent a
+line), modify the DOM to display your changes to the user, and have it
+all look like nothing special happened. A more Draconian policy for
+dealing with the browser, like trapping all mouse and key events,
+would just leave you with a Type II editor. The key is to treat the
+DOM as a hugely complicated I/O device between you and the browser,
+and carefully make rules to constrain it. [[= Genius analgy, IMO. :) =]]
+
+You also deal with the fact that design mode's "native" behavior is
+HTML-oriented, not text-oriented, and the fact that it tends to have a
+lot of quirks and bugs. You don't get scalability for free, either,
+you need some clever data structures. For example, determining the
+absolute line number of the blinking insertion point is an
+order-of-document-size operation without the aid of efficient data
+structures that can be maintained as the document changes.
+
+The plus side is that once you've systematically beat design mode into
+submission, you can have an unmatched degree of scalability and
+nativity. From there, it's just a matter of keeping your layers of
+abstraction scalable, and being aware of "nativity"-style constraints
+(like responsiveness and events), and you can build up to flexibility,
+the crown jewel. The reward is how easy it is to add new editor
+features! [[= I'm kind of confused here. You said ACE is a type III editor, sacrificing flexibility, but now you say that ACE *has* flexibility. Huh? =]]
+
+Speaking of which, here is a list of current ACE features. Some of
+them are small and just required recognizing their benefit, while
+others are more significant. [[= awkward sentence =]] Some features, like "Emacs-style undo"
+and "highlight matching parentheses", are significant despite having
+been implemented in a couple hours each, and are signs of what's to
+come in the future of ACE.
diff --git a/infrastructure/ace/build/.gitignore b/infrastructure/ace/build/.gitignore
new file mode 100644
index 0000000..4dc709e
--- /dev/null
+++ b/infrastructure/ace/build/.gitignore
@@ -0,0 +1,2 @@
+ace2.js
+ace2bare.js
diff --git a/infrastructure/ace/build/index.html b/infrastructure/ace/build/index.html
new file mode 100644
index 0000000..b8c8505
--- /dev/null
+++ b/infrastructure/ace/build/index.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head>
+ <title>A Code Editor</title>
+ <script src="jquery-1.2.1.js"></script>
+
+ <script src="testcode.js"></script>
+ <script src="ace2.js"></script>
+ <script>
+ $(document).ready(function() {
+ var editor = new Ace2Editor();
+ editor.init("editorcontainer", getTestCode(), editorReady);
+
+ editor.setOnKeyPress(function (evt) {
+ if (evt.ctrlKey && evt.which == "s".charCodeAt(0)) {
+ alert("You tried to save.");
+ return false;
+ }
+ return true;
+ });
+
+ function editorReady() {
+ resizeEditor();
+ $(window).bind("resize", resizeEditor);
+ setTimeout(function() {editor.focus();}, 0);
+ }
+
+ function resizeEditor() {
+ $("#editorcontainer").get(0).style.height = "100%";
+ editor.getFrame().style.height = ((document.documentElement.clientHeight)-1)+"px";
+ editor.adjustSize();
+ }
+ });
+ </script>
+ <style>
+ html { overflow: hidden } /* for Win IE 6 */
+ body { margin:0; padding:0; border:0; overflow: hidden; }
+ #editorcontainer { height: 1000px; /* changed programmatically */ }
+ #editorcontainer iframe { width: 100%; height: 100%; border:0; padding:0; margin:0; }
+ </style>
+ </head>
+ <body>
+ <div id="editorcontainer"><!-- --></div>
+ </body>
+</html>
diff --git a/infrastructure/ace/build/jquery-1.2.1.js b/infrastructure/ace/build/jquery-1.2.1.js
new file mode 100644
index 0000000..b4eb132
--- /dev/null
+++ b/infrastructure/ace/build/jquery-1.2.1.js
@@ -0,0 +1,2992 @@
+(function(){
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+ var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(selector, context) {
+ // If the context is a namespace object, return a new object
+ return this instanceof jQuery ?
+ this.init(selector, context) :
+ new jQuery(selector, context);
+};
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+ var _$ = $;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function(selector, context) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle HTML strings
+ if ( typeof selector == "string" ) {
+ var m = quickExpr.exec(selector);
+ if ( m && (m[1] || !context) ) {
+ // HANDLE: $(html) -> $(array)
+ if ( m[1] )
+ selector = jQuery.clean( [ m[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var tmp = document.getElementById( m[3] );
+ if ( tmp )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( tmp.id != m[3] )
+ return jQuery().find( selector );
+ else {
+ this[0] = tmp;
+ this.length = 1;
+ return this;
+ }
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction(selector) )
+ return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object is passed as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ jquery: "1.2.1",
+
+ size: function() {
+ return this.length;
+ },
+
+ length: 0,
+
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[num];
+ },
+
+ pushStack: function( a ) {
+ var ret = jQuery(a);
+ ret.prevObject = this;
+ return ret;
+ },
+
+ setArray: function( a ) {
+ this.length = 0;
+ Array.prototype.push.apply( this, a );
+ return this;
+ },
+
+ each: function( fn, args ) {
+ return jQuery.each( this, fn, args );
+ },
+
+ index: function( obj ) {
+ var pos = -1;
+ this.each(function(i){
+ if ( this == obj ) pos = i;
+ });
+ return pos;
+ },
+
+ attr: function( key, value, type ) {
+ var obj = key;
+
+ // Look for the case where we're accessing a style value
+ if ( key.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+ else {
+ obj = {};
+ obj[ key ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(index){
+ // Set all the styles
+ for ( var prop in obj )
+ jQuery.attr(
+ type ? this.style : this,
+ prop, jQuery.prop(this, obj[prop], type, index, prop)
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function(e) {
+ if ( typeof e != "object" && e != null )
+ return this.empty().append( document.createTextNode( e ) );
+
+ var t = "";
+ jQuery.each( e || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ t += this.nodeType != 1 ?
+ this.nodeValue : jQuery.fn.text([ this ]);
+ });
+ });
+ return t;
+ },
+
+ wrapAll: function(html) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery(html, this[0].ownerDocument)
+ .clone()
+ .insertBefore(this[0])
+ .map(function(){
+ var elem = this;
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function(html) {
+ return this.each(function(){
+ jQuery(this).contents().wrapAll(html);
+ });
+ },
+
+ wrap: function(html) {
+ return this.each(function(){
+ jQuery(this).wrapAll(html);
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, 1, function(a){
+ this.appendChild( a );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, -1, function(a){
+ this.insertBefore( a, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, 1, function(a){
+ this.parentNode.insertBefore( a, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, -1, function(a){
+ this.parentNode.insertBefore( a, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery([]);
+ },
+
+ find: function(t) {
+ var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
+ return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
+ jQuery.unique( data ) : data );
+ },
+
+ clone: function(events) {
+ // Do the clone
+ var ret = this.map(function(){
+ return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if (events === true)
+ this.find("*").andSelf().each(function(i) {
+ var events = jQuery.data(this, "events");
+ for ( var type in events )
+ for ( var handler in events[type] )
+ jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function(t) {
+ return this.pushStack(
+ jQuery.isFunction( t ) &&
+ jQuery.grep(this, function(el, index){
+ return t.apply(el, [index]);
+ }) ||
+
+ jQuery.multiFilter(t,this) );
+ },
+
+ not: function(t) {
+ return this.pushStack(
+ t.constructor == String &&
+ jQuery.multiFilter(t, this, true) ||
+
+ jQuery.grep(this, function(a) {
+ return ( t.constructor == Array || t.jquery )
+ ? jQuery.inArray( a, t ) < 0
+ : a != t;
+ })
+ );
+ },
+
+ add: function(t) {
+ return this.pushStack( jQuery.merge(
+ this.get(),
+ t.constructor == String ?
+ jQuery(t).get() :
+ t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
+ t : [t] )
+ );
+ },
+
+ is: function(expr) {
+ return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+ },
+
+ hasClass: function(expr) {
+ return this.is("." + expr);
+ },
+
+ val: function( val ) {
+ if ( val == undefined ) {
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName(elem, "select") ) {
+ var index = elem.selectedIndex,
+ a = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[i];
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return val;
+
+ // Multi-Selects return an array
+ a.push(val);
+ }
+ }
+
+ return a;
+
+ // Everything else, we just grab the value
+ } else
+ return this[0].value.replace(/\r/g, "");
+ }
+ } else
+ return this.each(function(){
+ if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
+ this.checked = (jQuery.inArray(this.value, val) >= 0 ||
+ jQuery.inArray(this.name, val) >= 0);
+ else if ( jQuery.nodeName(this, "select") ) {
+ var tmp = val.constructor == Array ? val : [val];
+
+ jQuery("option", this).each(function(){
+ this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
+ jQuery.inArray(this.text, tmp) >= 0);
+ });
+
+ if ( !tmp.length )
+ this.selectedIndex = -1;
+ } else
+ this.value = val;
+ });
+ },
+
+ html: function( val ) {
+ return val == undefined ?
+ ( this.length ? this[0].innerHTML : null ) :
+ this.empty().append( val );
+ },
+
+ replaceWith: function( val ) {
+ return this.after( val ).remove();
+ },
+
+ eq: function(i){
+ return this.slice(i, i+1);
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function(fn) {
+ return this.pushStack(jQuery.map( this, function(elem,i){
+ return fn.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function(args, table, dir, fn) {
+ var clone = this.length > 1, a;
+
+ return this.each(function(){
+ if ( !a ) {
+ a = jQuery.clean(args, this.ownerDocument);
+ if ( dir < 0 )
+ a.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+
+ jQuery.each( a, function(){
+ var elem = clone ? this.cloneNode(true) : this;
+ if ( !evalScript(0, elem) )
+ fn.call( obj, elem );
+ });
+ });
+ }
+};
+
+function evalScript(i, elem){
+ var script = jQuery.nodeName(elem, "script");
+
+ if ( script ) {
+ if ( elem.src )
+ jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild(elem);
+
+ } else if ( elem.nodeType == 1 )
+ jQuery("script", elem).each(evalScript);
+
+ return script;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( al == 1 ) {
+ target = this;
+ a = 0;
+ }
+
+ var prop;
+
+ for ( ; a < al; a++ )
+ // Only deal with non-null/undefined values
+ if ( (prop = arguments[a]) != null )
+ // Extend the base object
+ for ( var i in prop ) {
+ // Prevent never-ending loop
+ if ( target == prop[i] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && typeof prop[i] == 'object' && target[i] )
+ jQuery.extend( target[i], prop[i] );
+
+ // Don't bring in undefined values
+ else if ( prop[i] != undefined )
+ target[i] = prop[i];
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+
+jQuery.extend({
+ noConflict: function(deep) {
+ window.$ = _$;
+ if ( deep )
+ window.jQuery = _jQuery;
+ return jQuery;
+ },
+
+ // This may seem like some crazy code, but trust me when I say that this
+ // is the only cross-browser way to do this. --John
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a XML document
+ isXMLDoc: function(elem) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ // Evaluates Async. in Safari 2 :-(
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+ if ( data ) {
+ if ( window.execScript )
+ window.execScript( data );
+ else if ( jQuery.browser.safari )
+ // safari doesn't provide a synchronous global eval
+ window.setTimeout( data, 0 );
+ else
+ eval.call( window, data );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ? jQuery.cache[ id ][ name ] : id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+ for ( name in jQuery.cache[ id ] ) break;
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( obj, fn, args ) {
+ if ( args ) {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.apply( obj[i], args );
+ else
+ for ( var i = 0, ol = obj.length; i < ol; i++ )
+ if ( fn.apply( obj[i], args ) === false ) break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.call( obj[i], i, obj[i] );
+ else
+ for ( var i = 0, ol = obj.length, val = obj[0];
+ i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ }
+
+ return obj;
+ },
+
+ prop: function(elem, value, type, index, prop){
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, [index] );
+
+ // exclude the following css properties to add px
+ var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, c ){
+ jQuery.each( (c || "").split(/\s+/), function(i, cur){
+ if ( !jQuery.className.has( elem.className, cur ) )
+ elem.className += ( elem.className ? " " : "" ) + cur;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, c ){
+ elem.className = c != undefined ?
+ jQuery.grep( elem.className.split(/\s+/), function(cur){
+ return !jQuery.className.has( c, cur );
+ }).join(" ") : "";
+ },
+
+ // internal only, use is(".class")
+ has: function( t, c ) {
+ return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ swap: function(e,o,f) {
+ for ( var i in o ) {
+ e.style["old"+i] = e.style[i];
+ e.style[i] = o[i];
+ }
+ f.apply( e, [] );
+ for ( var i in o )
+ e.style[i] = e.style["old"+i];
+ },
+
+ css: function(e,p) {
+ if ( p == "height" || p == "width" ) {
+ var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+
+ jQuery.each( d, function(){
+ old["padding" + this] = 0;
+ old["border" + this + "Width"] = 0;
+ });
+
+ jQuery.swap( e, old, function() {
+ if ( jQuery(e).is(':visible') ) {
+ oHeight = e.offsetHeight;
+ oWidth = e.offsetWidth;
+ } else {
+ e = jQuery(e.cloneNode(true))
+ .find(":radio").removeAttr("checked").end()
+ .css({
+ visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
+ }).appendTo(e.parentNode)[0];
+
+ var parPos = jQuery.css(e.parentNode,"position") || "static";
+ if ( parPos == "static" )
+ e.parentNode.style.position = "relative";
+
+ oHeight = e.clientHeight;
+ oWidth = e.clientWidth;
+
+ if ( parPos == "static" )
+ e.parentNode.style.position = "static";
+
+ e.parentNode.removeChild(e);
+ }
+ });
+
+ return p == "height" ? oHeight : oWidth;
+ }
+
+ return jQuery.curCSS( e, p );
+ },
+
+ curCSS: function(elem, prop, force) {
+ var ret, stack = [], swap = [];
+
+ // A helper method for determining if an element's values are broken
+ function color(a){
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle(a,null);
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ if (prop == "opacity" && jQuery.browser.msie) {
+ ret = jQuery.attr(elem.style, "opacity");
+ return ret == "" ? "1" : ret;
+ }
+
+ if (prop.match(/float/i))
+ prop = styleFloat;
+
+ if (!force && elem.style[prop])
+ ret = elem.style[prop];
+
+ else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+ if (prop.match(/float/i))
+ prop = "float";
+
+ prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+ var cur = document.defaultView.getComputedStyle(elem, null);
+
+ if ( cur && !color(elem) )
+ ret = cur.getPropertyValue(prop);
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( a = 0; a < stack.length; a++ )
+ if ( color(stack[a]) ) {
+ swap[a] = stack[a].style.display;
+ stack[a].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = prop == "display" && swap[stack.length-1] != null ?
+ "none" :
+ document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+ // Finally, revert the display styles back
+ for ( a = 0; a < swap.length; a++ )
+ if ( swap[a] != null )
+ stack[a].style.display = swap[a];
+ }
+
+ if ( prop == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if (elem.currentStyle) {
+ var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
+ ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
+ var style = elem.style.left;
+ var runtimeStyle = elem.runtimeStyle.left;
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function(a, doc) {
+ var r = [];
+ doc = doc || document;
+
+ jQuery.each( a, function(i,arg){
+ if ( !arg ) return;
+
+ if ( arg.constructor == Number )
+ arg = arg.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof arg == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+
+ var wrap =
+ // option or optgroup
+ !s.indexOf("<opt") &&
+ [1, "<select>", "</select>"] ||
+
+ !s.indexOf("<leg") &&
+ [1, "<fieldset>", "</fieldset>"] ||
+
+ s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [1, "<table>", "</table>"] ||
+
+ !s.indexOf("<tr") &&
+ [2, "<table><tbody>", "</tbody></table>"] ||
+
+ // <thead> matched above
+ (!s.indexOf("<td") || !s.indexOf("<th")) &&
+ [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+
+ !s.indexOf("<col") &&
+ [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [1, "div<div>", "</div>"] ||
+
+ [0,"",""];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + arg + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
+ tb = div.firstChild && div.firstChild.childNodes;
+
+ // String was a bare <thead> or <tfoot>
+ else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
+ tb = div.childNodes;
+
+ for ( var n = tb.length-1; n >= 0 ; --n )
+ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
+ tb[n].parentNode.removeChild(tb[n]);
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test(arg) )
+ div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ arg = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
+ return;
+
+ if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
+ r.push( arg );
+ else
+ r = jQuery.merge( r, arg );
+
+ });
+
+ return r;
+ },
+
+ attr: function(elem, name, value){
+ var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[name] ) {
+ if ( value != undefined ) elem[fix[name]] = value;
+ return elem[fix[name]];
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
+ return elem.getAttributeNode(name).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode )
+ throw "type property can't be changed";
+ elem.setAttribute( name, value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
+ (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
+ }
+ name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
+ if ( value != undefined ) elem[name] = value;
+ return elem[name];
+ }
+ },
+
+ trim: function(t){
+ return (t||"").replace(/^\s+|\s+$/g, "");
+ },
+
+ makeArray: function( a ) {
+ var r = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof a != "array" )
+ for ( var i = 0, al = a.length; i < al; i++ )
+ r.push( a[i] );
+ else
+ r = a.slice( 0 );
+
+ return r;
+ },
+
+ inArray: function( b, a ) {
+ for ( var i = 0, al = a.length; i < al; i++ )
+ if ( a[i] == b )
+ return i;
+ return -1;
+ },
+
+ merge: function(first, second) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[i]; i++ )
+ if ( second[i].nodeType != 8 )
+ first.push(second[i]);
+ } else
+ for ( var i = 0; second[i]; i++ )
+ first.push(second[i]);
+
+ return first;
+ },
+
+ unique: function(first) {
+ var r = [], done = {};
+
+ try {
+ for ( var i = 0, fl = first.length; i < fl; i++ ) {
+ var id = jQuery.data(first[i]);
+ if ( !done[id] ) {
+ done[id] = true;
+ r.push(first[i]);
+ }
+ }
+ } catch(e) {
+ r = first;
+ }
+
+ return r;
+ },
+
+ grep: function(elems, fn, inv) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, el = elems.length; i < el; i++ )
+ if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
+ result.push( elems[i] );
+
+ return result;
+ },
+
+ map: function(elems, fn) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, el = elems.length; i < el; i++ ) {
+ var val = fn(elems[i],i);
+
+ if ( val !== null && val != undefined ) {
+ if ( val.constructor != Array ) val = [val];
+ result = result.concat( val );
+ }
+ }
+
+ return result;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(userAgent),
+ opera: /opera/.test(userAgent),
+ msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+ mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+};
+
+var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength"
+ }
+});
+
+jQuery.each({
+ parent: "a.parentNode",
+ parents: "jQuery.dir(a,'parentNode')",
+ next: "jQuery.nth(a,2,'nextSibling')",
+ prev: "jQuery.nth(a,2,'previousSibling')",
+ nextAll: "jQuery.dir(a,'nextSibling')",
+ prevAll: "jQuery.dir(a,'previousSibling')",
+ siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
+ children: "jQuery.sibling(a.firstChild)",
+ contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
+}, function(i,n){
+ jQuery.fn[ i ] = function(a) {
+ var ret = jQuery.map(this,n);
+ if ( a && typeof a == "string" )
+ ret = jQuery.multiFilter(a,ret);
+ return this.pushStack( jQuery.unique(ret) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(i,n){
+ jQuery.fn[ i ] = function(){
+ var a = arguments;
+ return this.each(function(){
+ for ( var j = 0, al = a.length; j < al; j++ )
+ jQuery(a[j])[n]( this );
+ });
+ };
+});
+
+jQuery.each( {
+ removeAttr: function( key ) {
+ jQuery.attr( this, key, "" );
+ this.removeAttribute( key );
+ },
+ addClass: function(c){
+ jQuery.className.add(this,c);
+ },
+ removeClass: function(c){
+ jQuery.className.remove(this,c);
+ },
+ toggleClass: function( c ){
+ jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
+ },
+ remove: function(a){
+ if ( !a || jQuery.filter( a, [this] ).r.length ) {
+ jQuery.removeData( this );
+ this.parentNode.removeChild( this );
+ }
+ },
+ empty: function() {
+ // Clean up the cache
+ jQuery("*", this).each(function(){ jQuery.removeData(this); });
+
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(i,n){
+ jQuery.fn[ i ] = function() {
+ return this.each( n, arguments );
+ };
+});
+
+jQuery.each( [ "Height", "Width" ], function(i,name){
+ var n = name.toLowerCase();
+
+ jQuery.fn[ n ] = function(h) {
+ return this[0] == window ?
+ jQuery.browser.safari && self["inner" + name] ||
+ jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
+ document.body["client" + name] :
+
+ this[0] == document ?
+ Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
+
+ h == undefined ?
+ ( this.length ? jQuery.css( this[0], n ) : null ) :
+ this.css( n, h.constructor == String ? h : h + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
+ "#": "a.getAttribute('id')==m[2]",
+ ":": {
+ // Position Checks
+ lt: "i<m[3]-0",
+ gt: "i>m[3]-0",
+ nth: "m[3]-0==i",
+ eq: "m[3]-0==i",
+ first: "i==0",
+ last: "i==r.length-1",
+ even: "i%2==0",
+ odd: "i%2",
+
+ // Child Checks
+ "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
+ "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
+ "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+
+ // Parent Checks
+ parent: "a.firstChild",
+ empty: "!a.firstChild",
+
+ // Text Check
+ contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",
+
+ // Visibility
+ visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
+ hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+
+ // Form attributes
+ enabled: "!a.disabled",
+ disabled: "a.disabled",
+ checked: "a.checked",
+ selected: "a.selected||jQuery.attr(a,'selected')",
+
+ // Form elements
+ text: "'text'==a.type",
+ radio: "'radio'==a.type",
+ checkbox: "'checkbox'==a.type",
+ file: "'file'==a.type",
+ password: "'password'==a.type",
+ submit: "'submit'==a.type",
+ image: "'image'==a.type",
+ reset: "'reset'==a.type",
+ button: '"button"==a.type||jQuery.nodeName(a,"button")',
+ input: "/input|select|textarea|button/i.test(a.nodeName)",
+
+ // :has()
+ has: "jQuery.find(m[3],a).length",
+
+ // :header
+ header: "/h\\d/i.test(a.nodeName)",
+
+ // :animated
+ animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // Make sure that the context is a DOM Element
+ if ( context && !context.nodeType )
+ context = null;
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ var nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var nodeName = m[2], merge = {};
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ r = jQuery.filter(m[3], r, true).r;
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ test = /(\d*)n\+?(\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
+ first = (test[1] || 1) - 0, last = test[2] - 0;
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 1 ) {
+ if ( last == 0 || node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex + last) % first == 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var f = jQuery.expr[m[1]];
+ if ( typeof f != "string" )
+ f = jQuery.expr[m[1]][m[2]];
+
+ // Build a custom macro to enclose it
+ f = eval("false||function(a,i){return " + f + "}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, f, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(element, type, handler, data) {
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && element.setInterval != undefined )
+ element = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Init the element's event structure
+ var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
+
+ var handle = jQuery.data(element, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(element, arguments);
+
+ return val;
+ });
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // And bind the global event handler to the element
+ if (element.addEventListener)
+ element.addEventListener(type, handle, false);
+ else
+ element.attachEvent("on" + type, handle);
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ this.global[type] = true;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(element, type, handler) {
+ var events = jQuery.data(element, "events"), ret, index;
+
+ // Namespaced event handlers
+ if ( typeof type == "string" ) {
+ var parts = type.split(".");
+ type = parts[0];
+ }
+
+ if ( events ) {
+ // type is actually an event object here
+ if ( type && type.type ) {
+ handler = type.handler;
+ type = type.type;
+ }
+
+ if ( !type ) {
+ for ( type in events )
+ this.remove( element, type );
+
+ } else if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if (element.removeEventListener)
+ element.removeEventListener(type, jQuery.data(element, "handle"), false);
+ else
+ element.detachEvent("on" + type, jQuery.data(element, "handle"));
+ ret = null;
+ delete events[type];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ jQuery.removeData( element, "events" );
+ jQuery.removeData( element, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, element, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ // Handle a global trigger
+ if ( !element ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ evt = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( evt )
+ data.unshift( this.fix({ type: type, target: element }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
+ val = jQuery.data(element, "handle").apply( element, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( evt )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && extra.apply( element, data ) === false )
+ val = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
+ this.triggered = true;
+ element[ type ]();
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in c ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = c[j];
+ args[0].data = c[j].data;
+
+ // Filter the functions by class
+ if ( !parts[1] || c[j].type == parts[1] ) {
+ var tmp = c[j].apply( this, args );
+
+ if ( val !== false )
+ val = tmp;
+
+ if ( tmp === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target && event.srcElement )
+ event.target = event.srcElement;
+
+ // check if target is a textnode (safari)
+ if (jQuery.browser.safari && event.target.nodeType == 3)
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var e = document.documentElement, b = document.body;
+ event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
+ event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && (event.charCode || event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var a = arguments;
+
+ return this.click(function(e) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ e.preventDefault();
+
+ // and execute the function
+ return a[this.lastToggle].apply( this, [e] ) || false;
+ });
+ },
+
+ hover: function(f,g) {
+
+ // A private function for handling mouse 'hovering'
+ function handleHover(e) {
+ // Check if mouse(over|out) are still within the same parent element
+ var p = e.relatedTarget;
+
+ // Traverse up the tree
+ while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
+
+ // If we actually just moused on to a sub-element, ignore it
+ if ( p == this ) return false;
+
+ // Execute the right function
+ return (e.type == "mouseover" ? f : g).apply(this, [e]);
+ }
+
+ // Bind the function to the two event listeners
+ return this.mouseover(handleHover).mouseout(handleHover);
+ },
+
+ ready: function(f) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ f.apply( document, [jQuery] );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ /*
+ * All the code that makes DOM Ready work nicely.
+ */
+ isReady: false,
+ readyList: [],
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+ // Remove event listener to avoid memory leak
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // Remove script element used by IE hack
+ if( !window.frames.length ) // don't remove if frames are present (#1187)
+ jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+ }
+ }
+});
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i,o){
+
+ // Handle event binding
+ jQuery.fn[o] = function(f){
+ return f ? this.bind(o, f) : this.trigger(o);
+ };
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // If Mozilla is used
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used, use the excellent hack by Matthias Miller
+ // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
+ else if ( jQuery.browser.msie ) {
+
+ // Only works if you document.write() it
+ document.write("<scr" + "ipt id=__ie_init defer=true " +
+ "src=//:><\/script>");
+
+ // Use the defer script hack
+ var script = document.getElementById("__ie_init");
+
+ // script does not exist if jQuery is loaded dynamically
+ if ( script )
+ script.onreadystatechange = function() {
+ if ( this.readyState != "complete" ) return;
+ jQuery.ready();
+ };
+
+ // Clear from memory
+ script = null;
+
+ // If Safari is used
+ } else if ( jQuery.browser.safari )
+ // Continually check to see if the document.readyState is valid
+ jQuery.safariTimer = setInterval(function(){
+ // loaded and complete are both valid states
+ if ( document.readyState == "loaded" ||
+ document.readyState == "complete" ) {
+
+ // If either one are found, remove the timer
+ clearInterval( jQuery.safariTimer );
+ jQuery.safariTimer = null;
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ }, 10);
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ // Add delay to account for Safari's delay in globalEval
+ setTimeout(function(){
+ self.each( callback, [res.responseText, status, res] );
+ }, 13);
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=(\?|%3F)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = s.data.replace(jsre, "=" + jsonp);
+ s.url = s.url.replace(jsre, "=" + jsonp);
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime();
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script
+ if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+
+ // Handle Script loading
+ if ( !jsonp && (s.success || s.complete) ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async);
+
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock ? this.oldblock : "";
+ if ( jQuery.css(this,"display") == "none" )
+ this.style.display = "block";
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ if ( this.oldblock == "none" )
+ this.oldblock = "block";
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var opt = jQuery.speed(speed, easing, callback);
+
+ return this[ opt.queue === false ? "each" : "queue" ](function(){
+ opt = jQuery.extend({}, opt);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) ) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(){
+ var timers = jQuery.timers;
+
+ return this.each(function(){
+ for ( var i = 0; i < timers.length; i++ )
+ if ( timers[i].elem == this )
+ timers.splice(i--, 1);
+ }).dequeue();
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return;
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(){
+ return self.step();
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timers.length == 1 ) {
+ var timer = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length )
+ clearInterval( timer );
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(){
+ var t = (new Date()).getTime();
+
+ if ( t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var absolute = jQuery.css(elem, "position") == "absolute",
+ parent = elem.parentNode,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522;
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(
+ box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)
+ );
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ if ( msie ) {
+ var border = jQuery("html").css("borderWidth");
+ border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border;
+ add( -border, -border );
+ }
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table cells
+ if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
+ border( offsetParent );
+
+ // Safari <= 2 doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" )
+ absolute = true;
+
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Work around opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && absolute )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ return results;
+
+ function border(elem) {
+ add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+};
+})();
diff --git a/infrastructure/ace/build/testcode.js b/infrastructure/ace/build/testcode.js
new file mode 100644
index 0000000..f393335
--- /dev/null
+++ b/infrastructure/ace/build/testcode.js
@@ -0,0 +1,36 @@
+function getTestCode() {
+ var testCode = [
+'/* appjet:version 0.1 */',
+'(function(){',
+'/*',
+' * jQuery 1.2.1 - New Wave Javascript',
+' *',
+' * Copyright (c) 2007 John Resig (jquery.com)',
+' * Dual licensed under the MIT (MIT-LICENSE.txt)',
+' * and GPL (GPL-LICENSE.txt) licenses.',
+' *',
+' * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $',
+' * $Rev: 3353 $',
+' */',
+'',
+'// Map over jQuery in case of overwrite',
+'if ( typeof jQuery != "undefined" )',
+' var _jQuery = jQuery;',
+'',
+'var jQuery = window.jQuery = function(selector, context) {',
+' // If the context is a namespace object, return a new object',
+' return this instanceof jQuery ?',
+' this.init(selector, context) :',
+' new jQuery(selector, context);',
+'};',
+'',
+'// Map over the $ in case of overwrite',
+'if ( typeof $ != "undefined" )',
+' var _$ = $;',
+' ',
+'// Map the jQuery namespace to the \'$\' one',
+'window.$ = jQuery;',
+'',
+'var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;'].join('\n');
+ return testCode;
+}
diff --git a/infrastructure/ace/easysync-notes.txt b/infrastructure/ace/easysync-notes.txt
new file mode 100644
index 0000000..6808f40
--- /dev/null
+++ b/infrastructure/ace/easysync-notes.txt
@@ -0,0 +1,129 @@
+Goals:
+
+- no unicode (for efficient escaping, sightliness)
+- efficient operations for ACE and collab (attributed text, etc.)
+- good for time-slider
+- good for API
+- line-ending aware
+X more coherent (deleting or styling text merging with insertion)
+- server-side syntax highlighting?
+- unify author map with attribute pool
+- unify attributed text with changeset rep
+- not: reversible
+- force final newline of document to be preserved
+
+- Unicode bad:
+ - ugly (hard to read)
+ - more complex to parse
+ - harder to store and transmit correctly
+ - doesn't save all that much space anyway
+ - blows up in size when string-escaped
+ - embarrassing for API
+
+
+# Attributes:
+
+An "attribute" is a (key,value) pair such as (author,abc123456) or
+(bold,true). Sometimes an attribute is treated as an instruction to
+add that attribute, in which case an empty value means to remove it.
+So (bold,) removes the "bold" attribute. Attributes are interned and
+given numeric IDs, so the number "6" could represent "(bold,true)",
+for example. This mapping is stored in an attribute "pool" which may
+be shared by multiple changesets.
+
+Entries in the pool must be unique, so that attributes can be compared
+by their IDs. Attribute names cannot contain commas.
+
+A changeset looks something like the following:
+
+Z:5g>1|5=2p=v*4*5+1$x
+
+With the corresponding pool containing these entries:
+
+...
+4 -> (author,1059348573)
+5 -> (bold,true)
+...
+
+This changeset, together with the pool, represents inserting
+a bold letter "x" into the middle of a line. The string consists of:
+
+- a letter Z (the "magic character" and format version identifier)
+- a series of opcodes (punctuation) and numeric values in base 36 (the
+ alphanumerics)
+- a dollar sign ($)
+- a string of characters used by insertion operations (the "char bank")
+
+If we separate out the operations and convert the numbers to base 10, we get:
+
+Z :196 >1 |5=97 =31 *4 *5 +1 $"x"
+
+Here are descriptions of the operations, where capital letters are variables:
+
+":N" : Source text has length N (must be first op)
+">N" : Final text is N (positive) characters longer than source text (must be second op)
+"<N" : Final text is N (positive) characters shorter than source text (must be second op)
+">0" : Final text is same length as source text
+"+N" : Insert N characters from the bank, none of them newlines
+"-N" : Skip over (delete) N characters from the source text, none of them newlines
+"=N" : Keep N characters from the source text, none of them newlines
+"|L+N" : Insert N characters from the source text, containing L newlines. The last
+ character inserted MUST be a newline, but not the (new) document's final newline.
+"|L-N" : Delete N characters from the source text, containing L newlines. The last
+ character inserted MUST be a newline, but not the (old) document's final newline.
+"|L=N" : Keep N characters from the source text, containing L newlines. The last character
+ kept MUST be a newline, and the final newline of the document is allowed.
+"*I" : Apply attribute I from the pool to the following +, =, |+, or |= command.
+ In other words, any number of * ops can come before a +, =, or | but not
+ between a | and the corresponding + or =.
+ If +, text is inserted having this attribute. If =, text is kept but with
+ the attribute applied as an attribute addition or removal.
+ Consecutive attributes must be sorted lexically by (key,value) with key
+ and value taken as strings. It's illegal to have duplicate keys
+ for (key,value) pairs that apply to the same text. It's illegal to
+ have an empty value for a key in the case of an insertion (+), the
+ pair should just be omitted.
+
+Characters from the source text that aren't accounted for are assumed to be kept
+with the same attributes.
+
+Additional Constraints:
+
+- Consecutive +, -, and = ops of the same type that could be combined are not allowed.
+ Whether combination is possible depends on the attributes of the ops and whether
+ each is multiline or not. For example, two multiline deletions can never be
+ consecutive, nor can any insertion come after a non-multiline insertion with the
+ same attributes.
+- "No-op" ops are not allowed, such as deleting 0 characters. However, attribute
+ applications that don't have any effect are allowed.
+- Characters at the end of the source text cannot be explicitly kept with no changes;
+ if the change doesn't affect the last N characters, those "keep" ops must be left off.
+- In any consecutive sequence of insertions (+) and deletions (-) with no keeps (=),
+ the deletions must come before the insertions.
+- The document text before and after will always end with a newline. This policy avoids
+ a lot of special-casing of the end of the document. If a final newline is
+ always added when importing text and removed when exporting text, then the
+ changeset representation can be used to process text files that may or may not
+ have a final newline.
+
+Attribution string:
+
+An "attribution string" is a series of inserts with no deletions or keeps.
+For example, "*3+8|1+5" describes the attributes of a string of length 13,
+where the first 8 chars have attribute 3 and the next 5 chars have no
+attributes, with the last of these 5 chars being a newline. Constraints
+apply similar to those affecting changesets, but the restriction about
+the final newline of the new document being added doesn't apply.
+
+Attributes in an attribution string cannot be empty, like "(bold,)", they should
+instead be absent.
+
+
+
+
+
+-------
+Considerations:
+
+- composing changesets/attributions with different pools
+- generalizing "applyToAttribution" to make "mutateAttributionLines" and "compose"
diff --git a/infrastructure/ace/lib/rhino-js-1.7r1.jar b/infrastructure/ace/lib/rhino-js-1.7r1.jar
new file mode 120000
index 0000000..f41e23b
--- /dev/null
+++ b/infrastructure/ace/lib/rhino-js-1.7r1.jar
@@ -0,0 +1 @@
+../../lib/rhino-js-1.7r1.jar \ No newline at end of file
diff --git a/infrastructure/ace/lib/yuicompressor-2.4-appjet.jar b/infrastructure/ace/lib/yuicompressor-2.4-appjet.jar
new file mode 120000
index 0000000..3953af5
--- /dev/null
+++ b/infrastructure/ace/lib/yuicompressor-2.4-appjet.jar
@@ -0,0 +1 @@
+../../lib/yuicompressor-2.4-appjet.jar \ No newline at end of file
diff --git a/infrastructure/ace/notes.txt b/infrastructure/ace/notes.txt
new file mode 100644
index 0000000..d9e1fda
--- /dev/null
+++ b/infrastructure/ace/notes.txt
@@ -0,0 +1,195 @@
+XXX This is a scratch file I used for notes; information may be out of date or random -- dgreenspan
+
+- rename ace2.js to ace.js
+
+
+Editor goals:
+- Highlight JavaScript accurately (including regular expression, etc.)
+- On large documents (say 2000 lines), be responsive to new input and rehighlight the screen quickly
+- Highlight "as you type", not when you're done with the current line
+- Propagate multi-line comment highlighting efficiently
+- Look and feel as "clean" and "native" as possible to the user
+- Support unlimited "undo" with arbitrary undo model
+- Allow features such as auto-indentation and parenthesis-flashing to be added easily
+- Work in IE 6, FF 2, Safari 3, Camino
+- Support native copy and paste, within the buffer and with other programs
+- Not display any flickering, blurring, or any kind of artifact
+- Support incremental syntax-highlighting of other languages too
+- Be extensible -- multiple views of whole document, lines, tokens, characters
+- Support native selection behavior, international input, assistive devices (potentially)
+- Resizable text
+- Unlimited editors per page
+
+
+compatibility, speed, power, generality,
+
+
+
+
+- enhancement ideas
+ - show mismatched brackets
+ - undo history limit
+
+ace2 changelog for week of 5/9:
+- full "undo" support! control-Z (Windows) or command-Z (Mac)
+- flashing parentheses are back, and better than before!
+- appjet:css sections are syntax-highlighted
+- optimizations for slower machines
+- fixed various quirks
+- lines too long for browser are hard-wrapped on entry
+
+
+== path to calls that change rep
+- doLineSplice
+ - incorporateUserChanges
+ - idleWorkTimer
+ - handleKeyEvent
+ - performDocumentLineSplice
+ - setCodeText
+ - importCode
+ - setup
+ - handleReturnIndentation
+ - handleKeyEvent
+ - performDocumentReplaceRange
+ - handleKeyEvent
+ - performDocumentReplaceSelection
+ - handleKeyEvent
+- repSelectionChange
+ - incorporateUserChanges
+ - idleWorkTimer
+ - handleKeyEvent
+ - performSelectionChange
+ - setCodeText
+ - importCode
+ - setup
+ - handleReturnIndentation
+ - handleKeyEvent
+ - performDocumentReplaceRange
+ - doLineSplice
+
+
+make ace2_common local?
+
+
+next steps:
+- safari scroll jump
+- FF 1.6 support
+- weird "delete" bug
+- speed on slow machines
+- paren flashing
+- undo
+
+
+- investigate errors with special "delete" handling turned off
+- track down FF quirk (delete at begging of line starting with one space)
+- (done for now: look for IE memory leaks)
+
+
+Outstanding issues:
++ Bugs:
++ Quirks:
+ - FF: delete at beginning of line where line starts with 1 space (space briefly disappears)
+ - IE: clicking below document body clears selection (instead of moving caret)
+ - IE: horizontal scroll-bar sometimes unnecessary
++ Speed:
+ - skip-list is slow for insert/delete lines on highlighting
+ - return at bottom of 3000-line file takes too long to normalize in Firefox (probably worse in IE)
++ feature parity
+ - regular expression highlighting not smart in lexically ambiguous cases (should use previous token)
+ - paren flashing
++ additional features
+ - less zealous IDE document-dirty marking (e.g. arrow-key marks dirty)
+ - undo
++ fancy todo
+ - bring back rich shell editor
+ - use same highlighting for view-source, highlight on server
+ - highlight CSS and stuff
+
++ done
+ - multi-line strings
+ - does tab do the right thing?
+ - indent on return
+ - quirk: return key doesn't scroll caret into view
+ - line numbers
+ - highlight appjet directives
+ - IE Support
+ - slightly smarter indentation
+ - tab deletes until a stop
+ - interface: import/export
+ - interface: rich/plain
+ - bugfix: IE: return, delete, etc. doesn't mark document dirty!
+ - bugfix: IE: can't copy/paste within document
+ - caret not always in view after an edit
+
+====================
+
+Highlighting strategy:
+- allow incremental dirty-region highlighting, based on time and char to pass
+- first lex the viewport, based on information extending a little before it
+- then highlight the viewport
+- then highlight around the viewport?
+- lex the whole document from the top
+- highlight lines outside the viewport
+
+
+
+
+
+- deal with key events in relation to when they are responded to (doLater after all?)
+- use Pygment!
+
+- handle international characters (fragile DOM state)
+- normalize only when idle (make sure that works)
+- better detection, e.g. paste in Safari
+- selectionchange event?
+
+- can eventually allow discarding user changes!
+
+DONE:
+- editing when lines consist of spans
+- all browsers: scroll to full left on return, etc
+- why does IE let you type without firing events?
+- slow in IE?
+
+tests:
+- type some stuff, return, type more stuff, return
+- return repeatedly starting at end of line, delete repeatedly
+- return repeatedly starting at beginning of line, delete repeatedly
+- return repeatedly starting in middle of line, delete repeatedly
+- return/delete starting between blank lines
+- try to move past end of document, then try to type, then try to move
+- from collapsed selection, shift-left repeatedly, across lines, shift-right repeatedly
+- from collapsed selection, shift-right repeatedly, across lines, shift-left repeatedly
+- shift-up, shift-down; shift-down, shift-up
+- cut-and-paste span of characters into middle of line
+- cut-and-paste span of characters into blank line (FF)
+- cut-and-paste span of characters at end of line (FF)
+- cut-and-paste selection with blank lines in it, make sure lines still blank
+- cut-and-paste selection starting and ending with blank lines (IE, FF)
+- doc with blank lines, select-all, cut, paste
+- doc starting and ending in blank lines, select-all, cut, paste (IE, Firefox)
+ - IE currently loses one blank line at end if > 0
+ - Safari loses one blank line at end if > 1
+- non-empty doc, select-all, delete, select-all, delete (IE crash, Safari hidden cursor)
+- non-empty doc select-all, return, return, return (IE)
+- on last line of document: type stuff, return, type stuff. down arrow goes down = bad (IE)
+- on last line of document: type stuff, return, return. should be no extra lines (IE)
+- go to start of next-to-last line, shift-down, cut (IE)
+- cursor at start of line, shift-down, cut, paste (IE cursor jump)
+- cursor at start of one empty line, shift-down, cut, paste (IE)
+- cursor at start of two empty lines, shift-down, cut, paste (IE, FF)
+ - on IE, no new line is pasted; default behavior is worse, so I'll take it
+ - on FF, the equivalent of two returns; good enough
+- cursor at start of two empty lines, shift-down, cut, paste in middle of line (IE, FF)
+ - in IE, FF, Safari, the equivalent of two returns
+- type letter on blank line, delete it (IE)
+- type space on blank line, delete it (IE)
+- type space before non-blank line, delete it
+- delete blank line, then delete again quickly
+- delete blank line from caret at start of line starting with one space (FF)
+- type over selection from middle of one line to middle of next
+
+- in middle of a word (span), quickly delete, then type a character, then delete (IE)
+- paste text with blank lines from an external source
+- meta-delete
+- up arrow from beginning of line (WebKit)
diff --git a/infrastructure/ace/www/ace2_common.js b/infrastructure/ace/www/ace2_common.js
new file mode 100644
index 0000000..4a08de6
--- /dev/null
+++ b/infrastructure/ace/www/ace2_common.js
@@ -0,0 +1,115 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+function isNodeText(node) {
+ return (node.nodeType == 3);
+}
+
+function object(o) {
+ var f = function() {};
+ f.prototype = o;
+ return new f();
+}
+
+function extend(obj, props) {
+ for(var p in props) {
+ obj[p] = props[p];
+ }
+ return obj;
+}
+
+function forEach(array, func) {
+ for(var i=0;i<array.length;i++) {
+ var result = func(array[i], i);
+ if (result) break;
+ }
+}
+
+function map(array, func) {
+ var result = [];
+ // must remain compatible with "arguments" pseudo-array
+ for(var i=0;i<array.length;i++) {
+ if (func) result.push(func(array[i], i));
+ else result.push(array[i]);
+ }
+ return result;
+}
+
+function filter(array, func) {
+ var result = [];
+ // must remain compatible with "arguments" pseudo-array
+ for(var i=0;i<array.length;i++) {
+ if (func(array[i], i)) result.push(array[i]);
+ }
+ return result;
+}
+
+function isArray(testObject) {
+ return testObject && typeof testObject === 'object' &&
+ !(testObject.propertyIsEnumerable('length')) &&
+ typeof testObject.length === 'number';
+}
+
+// Figure out what browser is being used (stolen from jquery 1.2.1)
+var userAgent = navigator.userAgent.toLowerCase();
+var browser = {
+ version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(userAgent),
+ opera: /opera/.test(userAgent),
+ msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+ mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent),
+ windows: /windows/.test(userAgent) // dgreensp
+};
+
+function getAssoc(obj, name) {
+ return obj["_magicdom_"+name];
+}
+
+function setAssoc(obj, name, value) {
+ // note that in IE designMode, properties of a node can get
+ // copied to new nodes that are spawned during editing; also,
+ // properties representable in HTML text can survive copy-and-paste
+ obj["_magicdom_"+name] = value;
+}
+
+// "func" is a function over 0..(numItems-1) that is monotonically
+// "increasing" with index (false, then true). Finds the boundary
+// between false and true, a number between 0 and numItems inclusive.
+function binarySearch(numItems, func) {
+ if (numItems < 1) return 0;
+ if (func(0)) return 0;
+ if (! func(numItems-1)) return numItems;
+ var low = 0; // func(low) is always false
+ var high = numItems-1; // func(high) is always true
+ while ((high - low) > 1) {
+ var x = Math.floor((low+high)/2); // x != low, x != high
+ if (func(x)) high = x;
+ else low = x;
+ }
+ return high;
+}
+
+function binarySearchInfinite(expectedLength, func) {
+ var i = 0;
+ while (!func(i)) i += expectedLength;
+ return binarySearch(i, func);
+}
+
+function htmlPrettyEscape(str) {
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
+ .replace(/\r?\n/g, '\\n');
+}
diff --git a/infrastructure/ace/www/ace2_common_dev.js b/infrastructure/ace/www/ace2_common_dev.js
new file mode 100644
index 0000000..8fb88b0
--- /dev/null
+++ b/infrastructure/ace/www/ace2_common_dev.js
@@ -0,0 +1,296 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Remove non-cross-browser stuff I'm tempted to use */
+if (Array.prototype.filter) delete Array.prototype.filter;
+if (Array.prototype.forEach) delete Array.prototype.forEach;
+if (Array.prototype.map) delete Array.prototype.map;
+/* */
+
+function busyWait(ms) {
+ var start = (new Date()).getTime();
+ while ((new Date()).getTime() < start+ms) {}
+}
+
+/*
+ based on: http://www.JSON.org/json2.js
+ 2008-07-15
+*/
+toSource = function () {
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ Date.prototype.toJSON = function (key) {
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+ // If the string contains no control characters, no quote characters, and no
+ // backslash characters, then we can safely slap some quotes around it.
+ // Otherwise we must also replace the offending characters with safe escape
+ // sequences.
+
+ escapeable.lastIndex = 0;
+ return escapeable.test(string) ?
+ '"' + string.replace(escapeable, function (a) {
+ var c = meta[a];
+ if (typeof c === 'string') {
+ return c;
+ }
+ return '\\u' + ('0000' +
+ (+(a.charCodeAt(0))).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+ // Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ // If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ // If we were called with a replacer function, then call the replacer to
+ // obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ // What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+ // JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+ // If the value is a boolean or null, convert it to a string. Note:
+ // typeof null does not produce 'null'. The case is included here in
+ // the remote chance that this gets fixed someday.
+
+ return String(value);
+
+ // If the type is 'object', we might be dealing with an object or an array or
+ // null.
+
+ case 'object':
+
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
+ // so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+ // Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+ // If the object has a dontEnum length property, we'll treat it as an array.
+
+ if (typeof value.length === 'number' &&
+ !(value.propertyIsEnumerable('length'))) {
+
+ // The object is an array. Stringify every element. Use null as a placeholder
+ // for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ // Join all of the elements together, separated with commas, and wrap them in
+ // brackets.
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+ // If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+ // Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ // Join all of the member texts together, separated with commas,
+ // and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ return function (value, replacer, space) {
+
+ // The stringify method takes a value and an optional replacer, and an optional
+ // space parameter, and returns a JSON text. The replacer can be a function
+ // that can replace values, or an array of strings that will select the keys.
+ // A default replacer method can be provided. Use of the space parameter can
+ // produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+ // If the space parameter is a number, make an indent string containing that
+ // many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+ // If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+ // If there is a replacer, it must be a function or an array.
+ // Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+ // Make a fake root object containing our value under the key of ''.
+ // Return the result of stringifying the value.
+
+ return str('', {'': value});
+ }
+}();
+
+function debugFrame(optName, func) {
+ var name = "something";
+ if ((typeof optName) == "string") {
+ name = optName;
+ }
+ else func = optName;
+
+ return function() {
+ try {
+ return func.apply(this, arguments);
+ }
+ catch (e) {
+ console.warn(name+" didn't complete");
+ throw e;
+ }
+ }
+}
+
+function makeRecentSet(size) {
+ var ringBuffer = {};
+ var nextIndex = 0;
+ return {
+ contains: function (elem) {
+ for(var i=0;i<size;i++) {
+ if (ringBuffer[i] === elem) return true;
+ }
+ return false;
+ },
+ addNew: function (elem) {
+ // precond: not already in set
+ ringBuffer[nextIndex] = elem;
+ nextIndex = ((nextIndex+1) % size);
+ }
+ };
+}
diff --git a/infrastructure/ace/www/ace2_inner.js b/infrastructure/ace/www/ace2_inner.js
new file mode 100644
index 0000000..afd1e35
--- /dev/null
+++ b/infrastructure/ace/www/ace2_inner.js
@@ -0,0 +1,4778 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function OUTER(gscope) {
+
+ var DEBUG=true;//$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
+
+ var isSetUp = false;
+
+ var THE_TAB = ' ';//4
+ var MAX_LIST_LEVEL = 8;
+
+ var LINE_NUMBER_PADDING_RIGHT = 4;
+ var LINE_NUMBER_PADDING_LEFT = 4;
+ var MIN_LINEDIV_WIDTH = 20;
+ var EDIT_BODY_PADDING_TOP = 8;
+ var EDIT_BODY_PADDING_LEFT = 8;
+
+ var caughtErrors = [];
+
+ var thisAuthor = '';
+
+ var disposed = false;
+
+ var editorInfo = parent.editorInfo;
+
+ var iframe = window.frameElement;
+ var outerWin = iframe.ace_outerWin;
+ iframe.ace_outerWin = null; // prevent IE 6 memory leak
+ var sideDiv = iframe.nextSibling;
+ var lineMetricsDiv = sideDiv.nextSibling;
+ var overlaysdiv = lineMetricsDiv.nextSibling;
+ initLineNumbers();
+
+ var outsideKeyDown = function(evt) {};
+ var outsideKeyPress = function(evt) { return true; };
+ var outsideNotifyDirty = function() {};
+
+ // selFocusAtStart -- determines whether the selection extends "backwards", so that the focus
+ // point (controlled with the arrow keys) is at the beginning; not supported in IE, though
+ // native IE selections have that behavior (which we try not to interfere with).
+ // Must be false if selection is collapsed!
+ var rep = { lines: newSkipList(), selStart: null, selEnd: null, selFocusAtStart: false,
+ alltext: "", alines: [],
+ apool: new AttribPool() };
+ // lines, alltext, alines, and DOM are set up in setup()
+ if (undoModule.enabled) {
+ undoModule.apool = rep.apool;
+ }
+
+ var root, doc; // set in setup()
+
+ var isEditable = true;
+ var doesWrap = true;
+ var hasLineNumbers = true;
+ var isStyled = true;
+
+ // space around the innermost iframe element
+ var iframePadLeft = MIN_LINEDIV_WIDTH + LINE_NUMBER_PADDING_RIGHT + EDIT_BODY_PADDING_LEFT;
+ var iframePadTop = EDIT_BODY_PADDING_TOP;
+ var iframePadBottom = 0, iframePadRight = 0;
+
+ var console = (DEBUG && top.console);
+ if (! console) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+ console = {};
+ for (var i = 0; i < names.length; ++i)
+ console[names[i]] = function() {};
+ //console.error = function(str) { alert(str); };
+ }
+ var PROFILER = window.PROFILER;
+ if (!PROFILER) {
+ PROFILER = function() { return {start:noop, mark:noop, literal:noop, end:noop, cancel:noop}; };
+ }
+ function noop() {}
+ function identity(x) { return x; }
+
+ // "dmesg" is for displaying messages in the in-page output pane
+ // visible when "?djs=1" is appended to the pad URL. It generally
+ // remains a no-op unless djs is enabled, but we make a habit of
+ // only calling it in error cases or while debugging.
+ var dmesg = noop;
+ window.dmesg = noop;
+
+ var scheduler = parent;
+
+ var textFace = 'monospace';
+ var textSize = 12;
+ function textLineHeight() { return Math.round(textSize * 4/3); }
+
+ var dynamicCSS = null;
+ function initDynamicCSS() {
+ dynamicCSS = makeCSSManager("dynamicsyntax");
+ }
+
+ var changesetTracker = makeChangesetTracker(scheduler, rep.apool, {
+ withCallbacks: function(operationName, f) {
+ inCallStackIfNecessary(operationName, function() {
+ fastIncorp(1);
+ f({
+ setDocumentAttributedText: function(atext) {
+ setDocAText(atext);
+ },
+ applyChangesetToDocument: function(changeset, preferInsertionAfterCaret) {
+ var oldEventType = currentCallStack.editEvent.eventType;
+ currentCallStack.startNewEvent("nonundoable");
+
+ performDocumentApplyChangeset(changeset, preferInsertionAfterCaret);
+
+ currentCallStack.startNewEvent(oldEventType);
+ }
+ });
+ });
+ }
+ });
+
+ var authorInfos = {}; // presence of key determines if author is present in doc
+
+ function setAuthorInfo(author, info) {
+ if ((typeof author) != "string") {
+ throw new Error("setAuthorInfo: author ("+author+") is not a string");
+ }
+ if (! info) {
+ delete authorInfos[author];
+ if (dynamicCSS) {
+ dynamicCSS.removeSelectorStyle(getAuthorColorClassSelector(getAuthorClassName(author)));
+ }
+ }
+ else {
+ authorInfos[author] = info;
+ if (info.bgcolor) {
+ if (dynamicCSS) {
+ var bgcolor = info.bgcolor;
+ if ((typeof info.fade) == "number") {
+ bgcolor = fadeColor(bgcolor, info.fade);
+ }
+
+ dynamicCSS.selectorStyle(getAuthorColorClassSelector(
+ getAuthorClassName(author))).backgroundColor = bgcolor;
+ }
+ }
+ }
+ }
+
+ function getAuthorClassName(author) {
+ return "author-"+author.replace(/[^a-y0-9]/g, function(c) {
+ if (c == ".") return "-";
+ return 'z'+c.charCodeAt(0)+'z';
+ });
+ }
+ function className2Author(className) {
+ if (className.substring(0,7) == "author-") {
+ return className.substring(7).replace(/[a-y0-9]+|-|z.+?z/g, function(cc) {
+ if (cc == '-') return '.';
+ else if (cc.charAt(0) == 'z') {
+ return String.fromCharCode(Number(cc.slice(1,-1)));
+ }
+ else {
+ return cc;
+ }
+ });
+ }
+ return null;
+ }
+ function getAuthorColorClassSelector(oneClassName) {
+ return ".authorColors ."+oneClassName;
+ }
+ function setUpTrackingCSS() {
+ if (dynamicCSS) {
+ var backgroundHeight = lineMetricsDiv.offsetHeight;
+ var lineHeight = textLineHeight();
+ var extraBodding = 0;
+ var extraTodding = 0;
+ if (backgroundHeight < lineHeight) {
+ extraBodding = Math.ceil((lineHeight - backgroundHeight)/2);
+ extraTodding = lineHeight - backgroundHeight - extraBodding;
+ }
+ var spanStyle = dynamicCSS.selectorStyle("#innerdocbody span");
+ spanStyle.paddingTop = extraTodding+"px";
+ spanStyle.paddingBottom = extraBodding+"px";
+ }
+ }
+ function boldColorFromColor(lightColorCSS) {
+ var color = colorutils.css2triple(lightColorCSS);
+
+ // amp up the saturation to full
+ color = colorutils.saturate(color);
+
+ // normalize brightness based on luminosity
+ color = colorutils.scaleColor(color, 0, 0.5 / colorutils.luminosity(color));
+
+ return colorutils.triple2css(color);
+ }
+ function fadeColor(colorCSS, fadeFrac) {
+ var color = colorutils.css2triple(colorCSS);
+ color = colorutils.blend(color, [1,1,1], fadeFrac);
+ return colorutils.triple2css(color);
+ }
+
+ function doAlert(str) {
+ scheduler.setTimeout(function() { alert(str); }, 0);
+ }
+
+ var currentCallStack = null;
+ function inCallStack(type, action) {
+ if (disposed) return;
+
+ if (currentCallStack) {
+ console.error("Can't enter callstack "+type+", already in "+
+ currentCallStack.type);
+ }
+
+ var profiling = false;
+ function profileRest() {
+ profiling = true;
+ console.profile();
+ }
+
+ function newEditEvent(eventType) {
+ return {eventType:eventType, backset: null};
+ }
+
+ function submitOldEvent(evt) {
+ if (rep.selStart && rep.selEnd) {
+ var selStartChar =
+ rep.lines.offsetOfIndex(rep.selStart[0]) + rep.selStart[1];
+ var selEndChar =
+ rep.lines.offsetOfIndex(rep.selEnd[0]) + rep.selEnd[1];
+ evt.selStart = selStartChar;
+ evt.selEnd = selEndChar;
+ evt.selFocusAtStart = rep.selFocusAtStart;
+ }
+ if (undoModule.enabled) {
+ var undoWorked = false;
+ try {
+ if (evt.eventType == "setup" || evt.eventType == "importText" ||
+ evt.eventType == "setBaseText") {
+ undoModule.clearHistory();
+ }
+ else if (evt.eventType == "nonundoable") {
+ if (evt.changeset) {
+ undoModule.reportExternalChange(evt.changeset);
+ }
+ }
+ else {
+ undoModule.reportEvent(evt);
+ }
+ undoWorked = true;
+ }
+ finally {
+ if (! undoWorked) {
+ undoModule.enabled = false; // for safety
+ }
+ }
+ }
+ }
+
+ function startNewEvent(eventType, dontSubmitOld) {
+ var oldEvent = currentCallStack.editEvent;
+ if (! dontSubmitOld) {
+ submitOldEvent(oldEvent);
+ }
+ currentCallStack.editEvent = newEditEvent(eventType);
+ return oldEvent;
+ }
+
+ currentCallStack = {type: type, docTextChanged: false, selectionAffected: false,
+ userChangedSelection: false,
+ domClean: false, profileRest:profileRest,
+ isUserChange: false, // is this a "user change" type of call-stack
+ repChanged: false, editEvent: newEditEvent(type),
+ startNewEvent:startNewEvent};
+ var cleanExit = false;
+ var result;
+ try {
+ result = action();
+ //console.log("Just did action for: "+type);
+ cleanExit = true;
+ }
+ catch (e) {
+ caughtErrors.push({error: e, time: +new Date()});
+ dmesg(e.toString());
+ throw e;
+ }
+ finally {
+ var cs = currentCallStack;
+ //console.log("Finished action for: "+type);
+ if (cleanExit) {
+ submitOldEvent(cs.editEvent);
+ if (cs.domClean && cs.type != "setup") {
+ if (cs.isUserChange) {
+ if (cs.repChanged) parenModule.notifyChange();
+ else parenModule.notifyTick();
+ }
+ recolorModule.recolorLines();
+ if (cs.selectionAffected) {
+ updateBrowserSelectionFromRep();
+ }
+ if ((cs.docTextChanged || cs.userChangedSelection) && cs.type != "applyChangesToBase") {
+ scrollSelectionIntoView();
+ }
+ if (cs.docTextChanged && cs.type.indexOf("importText") < 0) {
+ outsideNotifyDirty();
+ }
+ }
+ }
+ else {
+ // non-clean exit
+ if (currentCallStack.type == "idleWorkTimer") {
+ idleWorkTimer.atLeast(1000);
+ }
+ }
+ currentCallStack = null;
+ if (profiling) console.profileEnd();
+ }
+ return result;
+ }
+
+ function inCallStackIfNecessary(type, action) {
+ if (! currentCallStack) {
+ inCallStack(type, action);
+ }
+ else {
+ action();
+ }
+ }
+
+ function recolorLineByKey(key) {
+ if (rep.lines.containsKey(key)) {
+ var offset = rep.lines.offsetOfKey(key);
+ var width = rep.lines.atKey(key).width;
+ recolorLinesInRange(offset, offset + width);
+ }
+ }
+
+ function getLineKeyForOffset(charOffset) {
+ return rep.lines.atOffset(charOffset).key;
+ }
+
+ var recolorModule = (function() {
+ var dirtyLineKeys = {};
+
+ var module = {};
+ module.setCharNeedsRecoloring = function(offset) {
+ if (offset >= rep.alltext.length) {
+ offset = rep.alltext.length-1;
+ }
+ dirtyLineKeys[getLineKeyForOffset(offset)] = true;
+ }
+
+ module.setCharRangeNeedsRecoloring = function(offset1, offset2) {
+ if (offset1 >= rep.alltext.length) {
+ offset1 = rep.alltext.length-1;
+ }
+ if (offset2 >= rep.alltext.length) {
+ offset2 = rep.alltext.length-1;
+ }
+ var firstEntry = rep.lines.atOffset(offset1);
+ var lastKey = rep.lines.atOffset(offset2).key;
+ dirtyLineKeys[lastKey] = true;
+ var entry = firstEntry;
+ while (entry && entry.key != lastKey) {
+ dirtyLineKeys[entry.key] = true;
+ entry = rep.lines.next(entry);
+ }
+ }
+
+ module.recolorLines = function() {
+ for(var k in dirtyLineKeys) {
+ recolorLineByKey(k);
+ }
+ dirtyLineKeys = {};
+ }
+
+ return module;
+ })();
+
+ var parenModule = (function() {
+ var module = {};
+ module.notifyTick = function() { handleFlashing(false); };
+ module.notifyChange = function() { handleFlashing(true); };
+ module.shouldNormalizeOnChar = function (c) {
+ if (parenFlashRep.active) {
+ // avoid highlight style from carrying on to typed text
+ return true;
+ }
+ c = String.fromCharCode(c);
+ return !! (bracketMap[c]);
+ }
+
+ var parenFlashRep = { active: false, whichChars: null, whichLineKeys: null, expireTime: null };
+ var bracketMap = {'(': 1, ')':-1, '[':2, ']':-2, '{':3, '}':-3};
+ var bracketRegex = /[{}\[\]()]/g;
+ function handleFlashing(docChanged) {
+ function getSearchRange(aroundLoc) {
+ var rng = getVisibleCharRange();
+ var d = 100; // minimum radius
+ var e = 3000; // maximum radius;
+ if (rng[0] > aroundLoc-d) rng[0] = aroundLoc-d;
+ if (rng[0] < aroundLoc-e) rng[0] = aroundLoc-e;
+ if (rng[0] < 0) rng[0] = 0;
+ if (rng[1] < aroundLoc+d) rng[1] = aroundLoc+d;
+ if (rng[1] > aroundLoc+e) rng[1] = aroundLoc+e;
+ if (rng[1] > rep.lines.totalWidth()) rng[1] = rep.lines.totalWidth();
+ return rng;
+ }
+ function findMatchingVisibleBracket(startLoc, forwards) {
+ var rng = getSearchRange(startLoc);
+ var str = rep.alltext.substring(rng[0], rng[1]);
+ var bstr = str.replace(bracketRegex, '('); // handy for searching
+ var loc = startLoc - rng[0];
+ var bracketState = [];
+ var foundParen = false;
+ var goodParen = false;
+ function nextLoc() {
+ if (loc < 0) return;
+ if (forwards) loc++; else loc--;
+ if (loc < 0 || loc >= str.length) loc = -1;
+ if (loc >= 0) {
+ if (forwards) loc = bstr.indexOf('(', loc);
+ else loc = bstr.lastIndexOf('(', loc);
+ }
+ }
+ while ((! foundParen) && (loc >= 0)) {
+ if (getCharType(loc + rng[0]) == "p") {
+ var b = bracketMap[str.charAt(loc)]; // -1, 1, -2, 2, -3, 3
+ var into = forwards;
+ var typ = b;
+ if (typ < 0) { into = ! into; typ = -typ; }
+ if (into) bracketState.push(typ);
+ else {
+ var recent = bracketState.pop();
+ if (recent != typ) {
+ foundParen = true; goodParen = false;
+ }
+ else if (bracketState.length == 0) {
+ foundParen = true; goodParen = true;
+ }
+ }
+ }
+ //console.log(bracketState.toSource());
+ if ((! foundParen) && (loc >= 0)) nextLoc();
+ }
+ if (! foundParen) return null;
+ return {chr: (loc + rng[0]), good: goodParen};
+ }
+
+ var r = parenFlashRep;
+ var charsToHighlight = null;
+ var linesToUnhighlight = null;
+ if (r.active && (docChanged || (now() > r.expireTime))) {
+ linesToUnhighlight = r.whichLineKeys;
+ r.active = false;
+ }
+ if ((! r.active) && docChanged && isCaret() && caretColumn() > 0) {
+ var caret = caretDocChar();
+ if (caret > 0 && getCharType(caret-1) == "p") {
+ var charBefore = rep.alltext.charAt(caret-1);
+ if (bracketMap[charBefore]) {
+ var lookForwards = (bracketMap[charBefore] > 0);
+ var findResult = findMatchingVisibleBracket(caret-1, lookForwards);
+ if (findResult) {
+ var mateLoc = findResult.chr;
+ var mateGood = findResult.good;
+ r.active = true;
+ charsToHighlight = {};
+ charsToHighlight[caret-1] = 'flash';
+ charsToHighlight[mateLoc] = (mateGood ? 'flash' : 'flashbad');
+ r.whichLineKeys = [];
+ r.whichLineKeys.push(getLineKeyForOffset(caret-1));
+ r.whichLineKeys.push(getLineKeyForOffset(mateLoc));
+ r.expireTime = now() + 4000;
+ newlyActive = true;
+ }
+ }
+ }
+
+ }
+ if (linesToUnhighlight) {
+ recolorLineByKey(linesToUnhighlight[0]);
+ recolorLineByKey(linesToUnhighlight[1]);
+ }
+ if (r.active && charsToHighlight) {
+ function f(txt, cls, next, ofst) {
+ var flashClass = charsToHighlight[ofst];
+ if (cls) {
+ next(txt, cls+" "+flashClass);
+ }
+ else next(txt, cls);
+ }
+ for(var c in charsToHighlight) {
+ recolorLinesInRange((+c), (+c)+1, null, f);
+ }
+ }
+ }
+
+ return module;
+ })();
+
+ function dispose() {
+ disposed = true;
+ if (idleWorkTimer) idleWorkTimer.never();
+ teardown();
+ }
+
+ function checkALines() {
+ return; // disable for speed
+ function error() { throw new Error("checkALines"); }
+ if (rep.alines.length != rep.lines.length()) {
+ error();
+ }
+ for(var i=0;i<rep.alines.length;i++) {
+ var aline = rep.alines[i];
+ var lineText = rep.lines.atIndex(i).text+"\n";
+ var lineTextLength = lineText.length;
+ var opIter = Changeset.opIterator(aline);
+ var alineLength = 0;
+ while (opIter.hasNext()) {
+ var o = opIter.next();
+ alineLength += o.chars;
+ if (opIter.hasNext()) {
+ if (o.lines != 0) error();
+ }
+ else {
+ if (o.lines != 1) error();
+ }
+ }
+ if (alineLength != lineTextLength) {
+ error();
+ }
+ }
+ }
+
+ function setWraps(newVal) {
+ doesWrap = newVal;
+ var dwClass = "doesWrap";
+ setClassPresence(root, "doesWrap", doesWrap);
+ scheduler.setTimeout(function() {
+ inCallStackIfNecessary("setWraps", function() {
+ fastIncorp(7);
+ recreateDOM();
+ fixView();
+ });
+ }, 0);
+ }
+
+ function setStyled(newVal) {
+ var oldVal = isStyled;
+ isStyled = !!newVal;
+
+ if (newVal != oldVal) {
+ if (! newVal) {
+ // clear styles
+ inCallStackIfNecessary("setStyled", function() {
+ fastIncorp(12);
+ var clearStyles = [];
+ for(var k in STYLE_ATTRIBS) {
+ clearStyles.push([k,'']);
+ }
+ performDocumentApplyAttributesToCharRange(0, rep.alltext.length, clearStyles);
+ });
+ }
+ }
+ }
+
+ function setTextFace(face) {
+ textFace = face;
+ root.style.fontFamily = textFace;
+ lineMetricsDiv.style.fontFamily = textFace;
+ scheduler.setTimeout(function() {
+ setUpTrackingCSS();
+ }, 0);
+ }
+
+ function setTextSize(size) {
+ textSize = size;
+ root.style.fontSize = textSize+"px";
+ root.style.lineHeight = textLineHeight()+"px";
+ sideDiv.style.lineHeight = textLineHeight()+"px";
+ lineMetricsDiv.style.fontSize = textSize+"px";
+ scheduler.setTimeout(function() {
+ setUpTrackingCSS();
+ }, 0);
+ }
+
+ function recreateDOM() {
+ // precond: normalized
+ recolorLinesInRange(0, rep.alltext.length);
+ }
+
+ function setEditable(newVal) {
+ isEditable = newVal;
+
+ // the following may fail, e.g. if iframe is hidden
+ if (! isEditable) {
+ setDesignMode(false);
+ }
+ else {
+ setDesignMode(true);
+ }
+ setClassPresence(root, "static", ! isEditable);
+ }
+
+ function enforceEditability() {
+ setEditable(isEditable);
+ }
+
+ function importText(text, undoable, dontProcess) {
+ var lines;
+ if (dontProcess) {
+ if (text.charAt(text.length-1) != "\n") {
+ throw new Error("new raw text must end with newline");
+ }
+ if (/[\r\t\xa0]/.exec(text)) {
+ throw new Error("new raw text must not contain CR, tab, or nbsp");
+ }
+ lines = text.substring(0, text.length-1).split('\n');
+ }
+ else {
+ lines = map(text.split('\n'), textify);
+ }
+ var newText = "\n";
+ if (lines.length > 0) {
+ newText = lines.join('\n')+'\n';
+ }
+
+ inCallStackIfNecessary("importText"+(undoable?"Undoable":""), function() {
+ setDocText(newText);
+ });
+
+ if (dontProcess && rep.alltext != text) {
+ throw new Error("mismatch error setting raw text in importText");
+ }
+ }
+
+ function importAText(atext, apoolJsonObj, undoable) {
+ atext = Changeset.cloneAText(atext);
+ if (apoolJsonObj) {
+ var wireApool = (new AttribPool()).fromJsonable(apoolJsonObj);
+ atext.attribs = Changeset.moveOpsToNewPool(atext.attribs, wireApool, rep.apool);
+ }
+ inCallStackIfNecessary("importText"+(undoable?"Undoable":""), function() {
+ setDocAText(atext);
+ });
+ }
+
+ function setDocAText(atext) {
+ fastIncorp(8);
+
+ var oldLen = rep.lines.totalWidth();
+ var numLines = rep.lines.length();
+ var upToLastLine = rep.lines.offsetOfIndex(numLines-1);
+ var lastLineLength = rep.lines.atIndex(numLines-1).text.length;
+ var assem = Changeset.smartOpAssembler();
+ var o = Changeset.newOp('-');
+ o.chars = upToLastLine;
+ o.lines = numLines-1;
+ assem.append(o);
+ o.chars = lastLineLength;
+ o.lines = 0;
+ assem.append(o);
+ Changeset.appendATextToAssembler(atext, assem);
+ var newLen = oldLen + assem.getLengthChange();
+ var changeset = Changeset.checkRep(
+ Changeset.pack(oldLen, newLen, assem.toString(),
+ atext.text.slice(0, -1)));
+ performDocumentApplyChangeset(changeset);
+
+ performSelectionChange([0,rep.lines.atIndex(0).lineMarker],
+ [0,rep.lines.atIndex(0).lineMarker]);
+
+ idleWorkTimer.atMost(100);
+
+ if (rep.alltext != atext.text) {
+ dmesg(htmlPrettyEscape(rep.alltext));
+ dmesg(htmlPrettyEscape(atext.text));
+ throw new Error("mismatch error setting raw text in setDocAText");
+ }
+ }
+
+ function setDocText(text) {
+ setDocAText(Changeset.makeAText(text));
+ }
+
+ function getDocText() {
+ var alltext = rep.alltext;
+ var len = alltext.length;
+ if (len > 0) len--; // final extra newline
+ return alltext.substring(0, len);
+ }
+
+ function exportText() {
+ if (currentCallStack && ! currentCallStack.domClean) {
+ inCallStackIfNecessary("exportText", function() { fastIncorp(2); });
+ }
+ return getDocText();
+ }
+
+ function editorChangedSize() {
+ fixView();
+ }
+
+ function setOnKeyPress(handler) {
+ outsideKeyPress = handler;
+ }
+
+ function setOnKeyDown(handler) {
+ outsideKeyDown = handler;
+ }
+
+ function setNotifyDirty(handler) {
+ outsideNotifyDirty = handler;
+ }
+
+ function getFormattedCode() {
+ if (currentCallStack && ! currentCallStack.domClean) {
+ inCallStackIfNecessary("getFormattedCode", incorporateUserChanges);
+ }
+ var buf = [];
+ if (rep.lines.length() > 0) {
+ // should be the case, even for empty file
+ var entry = rep.lines.atIndex(0);
+ while (entry) {
+ var domInfo = entry.domInfo;
+ buf.push((domInfo && domInfo.getInnerHTML()) ||
+ domline.processSpaces(domline.escapeHTML(entry.text),
+ doesWrap) ||
+ '&nbsp;' /*empty line*/);
+ entry = rep.lines.next(entry);
+ }
+ }
+ return '<div class="syntax"><div>'+buf.join('</div>\n<div>')+
+ '</div></div>';
+ }
+
+ var CMDS = {
+ bold: function() { toggleAttributeOnSelection('bold'); },
+ italic: function() { toggleAttributeOnSelection('italic'); },
+ underline: function() { toggleAttributeOnSelection('underline'); },
+ strikethrough: function() { toggleAttributeOnSelection('strikethrough'); },
+ undo: function() { doUndoRedo('undo'); },
+ redo: function() { doUndoRedo('redo'); },
+ clearauthorship: function(prompt) {
+ if ((!(rep.selStart && rep.selEnd)) || isCaret()) {
+ if (prompt) {
+ prompt();
+ }
+ else {
+ performDocumentApplyAttributesToCharRange(0, rep.alltext.length,
+ [['author', '']]);
+ }
+ }
+ else {
+ setAttributeOnSelection('author', '');
+ }
+ },
+ insertunorderedlist: doInsertUnorderedList,
+ indent: function() {
+ if (! doIndentOutdent(false)) {
+ doInsertUnorderedList();
+ }
+ },
+ outdent: function() { doIndentOutdent(true); }
+ };
+
+ function execCommand(cmd) {
+ cmd = cmd.toLowerCase();
+ var cmdArgs = Array.prototype.slice.call(arguments, 1);
+ if (CMDS[cmd]) {
+ inCallStack(cmd, function() {
+ fastIncorp(9);
+ CMDS[cmd].apply(CMDS, cmdArgs);
+ });
+ }
+ }
+
+ editorInfo.ace_focus = focus;
+ editorInfo.ace_importText = importText;
+ editorInfo.ace_importAText = importAText;
+ editorInfo.ace_exportText = exportText;
+ editorInfo.ace_editorChangedSize = editorChangedSize;
+ editorInfo.ace_setOnKeyPress = setOnKeyPress;
+ editorInfo.ace_setOnKeyDown = setOnKeyDown;
+ editorInfo.ace_setNotifyDirty = setNotifyDirty;
+ editorInfo.ace_dispose = dispose;
+ editorInfo.ace_getFormattedCode = getFormattedCode;
+ editorInfo.ace_setEditable = setEditable;
+ editorInfo.ace_execCommand = execCommand;
+
+ editorInfo.ace_setProperty = function(key, value) {
+ var k = key.toLowerCase();
+ if (k == "wraps") {
+ setWraps(value);
+ }
+ else if (k == "showsauthorcolors") {
+ setClassPresence(root, "authorColors", !!value);
+ }
+ else if (k == "showsuserselections") {
+ setClassPresence(root, "userSelections", !!value);
+ }
+ else if (k == "showslinenumbers") {
+ hasLineNumbers = !!value;
+ setClassPresence(sideDiv, "sidedivhidden", ! hasLineNumbers);
+ fixView();
+ }
+ else if (k == "grayedout") {
+ setClassPresence(outerWin.document.body, "grayedout", !!value);
+ }
+ else if (k == "dmesg") {
+ dmesg = value;
+ window.dmesg = value;
+ }
+ else if (k == 'userauthor') {
+ thisAuthor = String(value);
+ }
+ else if (k == 'styled') {
+ setStyled(value);
+ }
+ else if (k == 'textface') {
+ setTextFace(value);
+ }
+ else if (k == 'textsize') {
+ setTextSize(value);
+ }
+ }
+
+ editorInfo.ace_setBaseText = function(txt) {
+ changesetTracker.setBaseText(txt);
+ };
+ editorInfo.ace_setBaseAttributedText = function(atxt, apoolJsonObj) {
+ setUpTrackingCSS();
+ changesetTracker.setBaseAttributedText(atxt, apoolJsonObj);
+ };
+ editorInfo.ace_applyChangesToBase = function(c, optAuthor, apoolJsonObj) {
+ changesetTracker.applyChangesToBase(c, optAuthor, apoolJsonObj);
+ };
+ editorInfo.ace_prepareUserChangeset = function() {
+ return changesetTracker.prepareUserChangeset();
+ };
+ editorInfo.ace_applyPreparedChangesetToBase = function() {
+ changesetTracker.applyPreparedChangesetToBase();
+ };
+ editorInfo.ace_setUserChangeNotificationCallback = function(f) {
+ changesetTracker.setUserChangeNotificationCallback(f);
+ };
+ editorInfo.ace_setAuthorInfo = function(author, info) {
+ setAuthorInfo(author, info);
+ };
+ editorInfo.ace_setAuthorSelectionRange = function(author, start, end) {
+ changesetTracker.setAuthorSelectionRange(author, start, end);
+ };
+
+ editorInfo.ace_getUnhandledErrors = function() {
+ return caughtErrors.slice();
+ };
+
+ editorInfo.ace_getDebugProperty = function(prop) {
+ if (prop == "debugger") {
+ // obfuscate "eval" so as not to scare yuicompressor
+ window['ev'+'al']("debugger");
+ }
+ else if (prop == "rep") {
+ return rep;
+ }
+ else if (prop == "window") {
+ return window;
+ }
+ else if (prop == "document") {
+ return document;
+ }
+ return undefined;
+ };
+
+ function now() { return (new Date()).getTime(); }
+
+ function newTimeLimit(ms) {
+ //console.debug("new time limit");
+ var startTime = now();
+ var lastElapsed = 0;
+ var exceededAlready = false;
+ var printedTrace = false;
+ var isTimeUp = function () {
+ if (exceededAlready) {
+ if ((! printedTrace)) {// && now() - startTime - ms > 300) {
+ //console.trace();
+ printedTrace = true;
+ }
+ return true;
+ }
+ var elapsed = now() - startTime;
+ if (elapsed > ms) {
+ exceededAlready = true;
+ //console.debug("time limit hit, before was %d/%d", lastElapsed, ms);
+ //console.trace();
+ return true;
+ }
+ else {
+ lastElapsed = elapsed;
+ return false;
+ }
+ }
+ isTimeUp.elapsed = function() { return now() - startTime; }
+ return isTimeUp;
+ }
+
+
+ function makeIdleAction(func) {
+ var scheduledTimeout = null;
+ var scheduledTime = 0;
+ function unschedule() {
+ if (scheduledTimeout) {
+ scheduler.clearTimeout(scheduledTimeout);
+ scheduledTimeout = null;
+ }
+ }
+ function reschedule(time) {
+ unschedule();
+ scheduledTime = time;
+ var delay = time - now();
+ if (delay < 0) delay = 0;
+ scheduledTimeout = scheduler.setTimeout(callback, delay);
+ }
+ function callback() {
+ scheduledTimeout = null;
+ // func may reschedule the action
+ func();
+ }
+ return {
+ atMost: function (ms) {
+ var latestTime = now() + ms;
+ if ((! scheduledTimeout) || scheduledTime > latestTime) {
+ reschedule(latestTime);
+ }
+ },
+ // atLeast(ms) will schedule the action if not scheduled yet.
+ // In other words, "infinity" is replaced by ms, even though
+ // it is technically larger.
+ atLeast: function (ms) {
+ var earliestTime = now()+ms;
+ if ((! scheduledTimeout) || scheduledTime < earliestTime) {
+ reschedule(earliestTime);
+ }
+ },
+ never: function() {
+ unschedule();
+ }
+ }
+ }
+
+ function fastIncorp(n) {
+ // normalize but don't do any lexing or anything
+ incorporateUserChanges(newTimeLimit(0));
+ }
+
+ function incorpIfQuick() {
+ var me = incorpIfQuick;
+ var failures = (me.failures || 0);
+ if (failures < 5) {
+ var isTimeUp = newTimeLimit(40);
+ var madeChanges = incorporateUserChanges(isTimeUp);
+ if (isTimeUp()) {
+ me.failures = failures+1;
+ }
+ return true;
+ }
+ else {
+ var skipCount = (me.skipCount || 0);
+ skipCount++;
+ if (skipCount == 20) {
+ skipCount = 0;
+ me.failures = 0;
+ }
+ me.skipCount = skipCount;
+ }
+ return false;
+ }
+
+ var idleWorkTimer = makeIdleAction(function() {
+
+ //if (! top.BEFORE) top.BEFORE = [];
+ //top.BEFORE.push(magicdom.root.dom.innerHTML);
+
+ if (! isEditable) return; // and don't reschedule
+
+ if (inInternationalComposition) {
+ // don't do idle input incorporation during international input composition
+ idleWorkTimer.atLeast(500);
+ return;
+ }
+
+ inCallStack("idleWorkTimer", function() {
+
+ var isTimeUp = newTimeLimit(250);
+
+ //console.time("idlework");
+
+ var finishedImportantWork = false;
+ var finishedWork = false;
+
+ try {
+
+ // isTimeUp() is a soft constraint for incorporateUserChanges,
+ // which always renormalizes the DOM, no matter how long it takes,
+ // but doesn't necessarily lex and highlight it
+ incorporateUserChanges(isTimeUp);
+
+ if (isTimeUp()) return;
+
+ updateLineNumbers(); // update line numbers if any time left
+
+ if (isTimeUp()) return;
+
+ var visibleRange = getVisibleCharRange();
+ var docRange = [0, rep.lines.totalWidth()];
+ //console.log("%o %o", docRange, visibleRange);
+
+ finishedImportantWork = true;
+ finishedWork = true;
+ }
+ finally {
+ //console.timeEnd("idlework");
+ if (finishedWork) {
+ idleWorkTimer.atMost(1000);
+ }
+ else if (finishedImportantWork) {
+ // if we've finished highlighting the view area,
+ // more highlighting could be counter-productive,
+ // e.g. if the user just opened a triple-quote and will soon close it.
+ idleWorkTimer.atMost(500);
+ }
+ else {
+ var timeToWait = Math.round(isTimeUp.elapsed() / 2);
+ if (timeToWait < 100) timeToWait = 100;
+ idleWorkTimer.atMost(timeToWait);
+ }
+ }
+ });
+
+ //if (! top.AFTER) top.AFTER = [];
+ //top.AFTER.push(magicdom.root.dom.innerHTML);
+
+ });
+
+ var _nextId = 1;
+ function uniqueId(n) {
+ // not actually guaranteed to be unique, e.g. if user copy-pastes
+ // nodes with ids
+ var nid = n.id;
+ if (nid) return nid;
+ return (n.id = "magicdomid"+(_nextId++));
+ }
+
+
+ function recolorLinesInRange(startChar, endChar, isTimeUp, optModFunc) {
+ if (endChar <= startChar) return;
+ if (startChar < 0 || startChar >= rep.lines.totalWidth()) return;
+ var lineEntry = rep.lines.atOffset(startChar); // rounds down to line boundary
+ var lineStart = rep.lines.offsetOfEntry(lineEntry);
+ var lineIndex = rep.lines.indexOfEntry(lineEntry);
+ var selectionNeedsResetting = false;
+ var firstLine = null;
+ var lastLine = null;
+ isTimeUp = (isTimeUp || noop);
+
+ // tokenFunc function; accesses current value of lineEntry and curDocChar,
+ // also mutates curDocChar
+ var curDocChar;
+ var tokenFunc = function(tokenText, tokenClass) {
+ lineEntry.domInfo.appendSpan(tokenText, tokenClass);
+ };
+ if (optModFunc) {
+ var f = tokenFunc;
+ tokenFunc = function(tokenText, tokenClass) {
+ optModFunc(tokenText, tokenClass, f, curDocChar);
+ curDocChar += tokenText.length;
+ };
+ }
+
+ while (lineEntry && lineStart < endChar && ! isTimeUp()) {
+ //var timer = newTimeLimit(200);
+ var lineEnd = lineStart + lineEntry.width;
+
+ curDocChar = lineStart;
+ lineEntry.domInfo.clearSpans();
+ getSpansForLine(lineEntry, tokenFunc, lineStart);
+ lineEntry.domInfo.finishUpdate();
+
+ markNodeClean(lineEntry.lineNode);
+
+ if (rep.selStart && rep.selStart[0] == lineIndex ||
+ rep.selEnd && rep.selEnd[0] == lineIndex) {
+ selectionNeedsResetting = true;
+ }
+
+ //if (timer()) console.dirxml(lineEntry.lineNode.dom);
+
+ if (firstLine === null) firstLine = lineIndex;
+ lastLine = lineIndex;
+ lineStart = lineEnd;
+ lineEntry = rep.lines.next(lineEntry);
+ lineIndex++;
+ }
+ if (selectionNeedsResetting) {
+ currentCallStack.selectionAffected = true;
+ }
+ //console.debug("Recolored line range %d-%d", firstLine, lastLine);
+ }
+
+ // like getSpansForRange, but for a line, and the func takes (text,class)
+ // instead of (width,class); excludes the trailing '\n' from
+ // consideration by func
+ function getSpansForLine(lineEntry, textAndClassFunc, lineEntryOffsetHint) {
+ var lineEntryOffset = lineEntryOffsetHint;
+ if ((typeof lineEntryOffset) != "number") {
+ lineEntryOffset = rep.lines.offsetOfEntry(lineEntry);
+ }
+ var text = lineEntry.text;
+ var width = lineEntry.width; // text.length+1
+
+ if (text.length == 0) {
+ // allow getLineStyleFilter to set line-div styles
+ var func = linestylefilter.getLineStyleFilter(
+ 0, '', textAndClassFunc, rep.apool);
+ func('', '');
+ }
+ else {
+ var offsetIntoLine = 0;
+ var filteredFunc = textAndClassFunc;
+ filteredFunc = linestylefilter.getURLFilter(text, filteredFunc);
+ if (browser.msie) {
+ // IE7+ will take an e-mail address like <foo@bar.com> and linkify it to foo@bar.com.
+ // We then normalize it back to text with no angle brackets. It's weird. So always
+ // break spans at an "at" sign.
+ filteredFunc = linestylefilter.getAtSignSplitterFilter(
+ text, filteredFunc);
+ }
+ var lineNum = rep.lines.indexOfEntry(lineEntry);
+ var aline = rep.alines[lineNum];
+ filteredFunc = linestylefilter.getLineStyleFilter(
+ text.length, aline, filteredFunc, rep.apool);
+ filteredFunc(text, '');
+ }
+ }
+
+
+ function getCharType(charIndex) {
+ return '';
+ }
+
+ var observedChanges;
+ function clearObservedChanges() {
+ observedChanges = { cleanNodesNearChanges: {} };
+ }
+ clearObservedChanges();
+
+ function getCleanNodeByKey(key) {
+ var p = PROFILER("getCleanNodeByKey", false);
+ p.extra = 0;
+ var n = doc.getElementById(key);
+ // copying and pasting can lead to duplicate ids
+ while (n && isNodeDirty(n)) {
+ p.extra++;
+ n.id = "";
+ n = doc.getElementById(key);
+ }
+ p.literal(p.extra, "extra");
+ p.end();
+ return n;
+ }
+
+ function observeChangesAroundNode(node) {
+ // Around this top-level DOM node, look for changes to the document
+ // (from how it looks in our representation) and record them in a way
+ // that can be used to "normalize" the document (apply the changes to our
+ // representation, and put the DOM in a canonical form).
+
+ //top.console.log("observeChangesAroundNode(%o)", node);
+
+ var cleanNode;
+ var hasAdjacentDirtyness;
+ if (! isNodeDirty(node)) {
+ cleanNode = node;
+ var prevSib = cleanNode.previousSibling;
+ var nextSib = cleanNode.nextSibling;
+ hasAdjacentDirtyness = ((prevSib && isNodeDirty(prevSib))
+ || (nextSib && isNodeDirty(nextSib)));
+ }
+ else {
+ // node is dirty, look for clean node above
+ var upNode = node.previousSibling;
+ while (upNode && isNodeDirty(upNode)) {
+ upNode = upNode.previousSibling;
+ }
+ if (upNode) {
+ cleanNode = upNode;
+ }
+ else {
+ var downNode = node.nextSibling;
+ while (downNode && isNodeDirty(downNode)) {
+ downNode = downNode.nextSibling;
+ }
+ if (downNode) {
+ cleanNode = downNode;
+ }
+ }
+ if (! cleanNode) {
+ // Couldn't find any adjacent clean nodes!
+ // Since top and bottom of doc is dirty, the dirty area will be detected.
+ return;
+ }
+ hasAdjacentDirtyness = true;
+ }
+
+ if (hasAdjacentDirtyness) {
+ // previous or next line is dirty
+ observedChanges.cleanNodesNearChanges['$'+uniqueId(cleanNode)] = true;
+ }
+ else {
+ // next and prev lines are clean (if they exist)
+ var lineKey = uniqueId(cleanNode);
+ var prevSib = cleanNode.previousSibling;
+ var nextSib = cleanNode.nextSibling;
+ var actualPrevKey = ((prevSib && uniqueId(prevSib)) || null);
+ var actualNextKey = ((nextSib && uniqueId(nextSib)) || null);
+ var repPrevEntry = rep.lines.prev(rep.lines.atKey(lineKey));
+ var repNextEntry = rep.lines.next(rep.lines.atKey(lineKey));
+ var repPrevKey = ((repPrevEntry && repPrevEntry.key) || null);
+ var repNextKey = ((repNextEntry && repNextEntry.key) || null);
+ if (actualPrevKey != repPrevKey || actualNextKey != repNextKey) {
+ observedChanges.cleanNodesNearChanges['$'+uniqueId(cleanNode)] = true;
+ }
+ }
+ }
+
+ function observeChangesAroundSelection() {
+ if (currentCallStack.observedSelection) return;
+ currentCallStack.observedSelection = true;
+
+ var p = PROFILER("getSelection", false);
+ var selection = getSelection();
+ p.end();
+ if (selection) {
+ function topLevel(n) {
+ if ((!n) || n == root) return null;
+ while (n.parentNode != root) {
+ n = n.parentNode;
+ }
+ return n;
+ }
+ var node1 = topLevel(selection.startPoint.node);
+ var node2 = topLevel(selection.endPoint.node);
+ if (node1) observeChangesAroundNode(node1);
+ if (node2 && node1 != node2) {
+ observeChangesAroundNode(node2);
+ }
+ }
+ }
+
+ function observeSuspiciousNodes() {
+ // inspired by Firefox bug #473255, where pasting formatted text
+ // causes the cursor to jump away, making the new HTML never found.
+ if (root.getElementsByTagName) {
+ var nds = root.getElementsByTagName("style");
+ for(var i=0;i<nds.length;i++) {
+ var n = nds[i];
+ while (n.parentNode && n.parentNode != root) {
+ n = n.parentNode;
+ }
+ if (n.parentNode == root) {
+ observeChangesAroundNode(n);
+ }
+ }
+ }
+ }
+
+ function incorporateUserChanges(isTimeUp) {
+
+ if (currentCallStack.domClean) return false;
+
+ inInternationalComposition = false; // if we need the document normalized, so be it
+
+ currentCallStack.isUserChange = true;
+
+ isTimeUp = (isTimeUp || function() { return false; });
+
+ if (DEBUG && top.DONT_INCORP || window.DEBUG_DONT_INCORP) return false;
+
+ var p = PROFILER("incorp", false);
+
+ //if (doc.body.innerHTML.indexOf("AppJet") >= 0)
+ //dmesg(htmlPrettyEscape(doc.body.innerHTML));
+ //if (top.RECORD) top.RECORD.push(doc.body.innerHTML);
+
+ // returns true if dom changes were made
+
+ if (! root.firstChild) {
+ root.innerHTML = "<div><!-- --></div>";
+ }
+
+ p.mark("obs");
+ observeChangesAroundSelection();
+ observeSuspiciousNodes();
+ p.mark("dirty");
+ var dirtyRanges = getDirtyRanges();
+ //console.log("dirtyRanges: "+toSource(dirtyRanges));
+
+ var dirtyRangesCheckOut = true;
+ var j = 0;
+ var a,b;
+ while (j < dirtyRanges.length) {
+ a = dirtyRanges[j][0];
+ b = dirtyRanges[j][1];
+ if (! ((a == 0 || getCleanNodeByKey(rep.lines.atIndex(a-1).key)) &&
+ (b == rep.lines.length() || getCleanNodeByKey(rep.lines.atIndex(b).key)))) {
+ dirtyRangesCheckOut = false;
+ break;
+ }
+ j++;
+ }
+ if (! dirtyRangesCheckOut) {
+ var numBodyNodes = root.childNodes.length;
+ for(var k=0;k<numBodyNodes;k++) {
+ var bodyNode = root.childNodes.item(k);
+ if ((bodyNode.tagName) && ((! bodyNode.id) || (! rep.lines.containsKey(bodyNode.id)))) {
+ observeChangesAroundNode(bodyNode);
+ }
+ }
+ dirtyRanges = getDirtyRanges();
+ }
+
+ clearObservedChanges();
+
+ p.mark("getsel");
+ var selection = getSelection();
+
+ //console.log(magicdom.root.dom.innerHTML);
+ //console.log("got selection: %o", selection);
+ var selStart, selEnd; // each one, if truthy, has [line,char] needed to set selection
+
+ var i = 0;
+ var splicesToDo = [];
+ var netNumLinesChangeSoFar = 0;
+ var toDeleteAtEnd = [];
+ p.mark("ranges");
+ p.literal(dirtyRanges.length, "numdirt");
+ var domInsertsNeeded = []; // each entry is [nodeToInsertAfter, [info1, info2, ...]]
+ while (i < dirtyRanges.length) {
+ var range = dirtyRanges[i];
+ a = range[0];
+ b = range[1];
+ var firstDirtyNode = (((a == 0) && root.firstChild) ||
+ getCleanNodeByKey(rep.lines.atIndex(a-1).key).nextSibling);
+ firstDirtyNode = (firstDirtyNode && isNodeDirty(firstDirtyNode) && firstDirtyNode);
+ var lastDirtyNode = (((b == rep.lines.length()) && root.lastChild) ||
+ getCleanNodeByKey(rep.lines.atIndex(b).key).previousSibling);
+ lastDirtyNode = (lastDirtyNode && isNodeDirty(lastDirtyNode) && lastDirtyNode);
+ if (firstDirtyNode && lastDirtyNode) {
+ var cc = makeContentCollector(isStyled, browser, rep.apool, null,
+ className2Author);
+ cc.notifySelection(selection);
+ var dirtyNodes = [];
+ for(var n = firstDirtyNode; n && ! (n.previousSibling &&
+ n.previousSibling == lastDirtyNode);
+ n = n.nextSibling) {
+ if (browser.msie) {
+ // try to undo IE's pesky and overzealous linkification
+ try { n.createTextRange().execCommand("unlink", false, null); }
+ catch (e) {}
+ }
+ cc.collectContent(n);
+ dirtyNodes.push(n);
+ }
+ cc.notifyNextNode(lastDirtyNode.nextSibling);
+ var lines = cc.getLines();
+ if ((lines.length <= 1 || lines[lines.length-1] !== "")
+ && lastDirtyNode.nextSibling) {
+ // dirty region doesn't currently end a line, even taking the following node
+ // (or lack of node) into account, so include the following clean node.
+ // It could be SPAN or a DIV; basically this is any case where the contentCollector
+ // decides it isn't done.
+ // Note that this clean node might need to be there for the next dirty range.
+ //console.log("inclusive of "+lastDirtyNode.next().dom.tagName);
+ b++;
+ var cleanLine = lastDirtyNode.nextSibling;
+ cc.collectContent(cleanLine);
+ toDeleteAtEnd.push(cleanLine);
+ cc.notifyNextNode(cleanLine.nextSibling);
+ }
+
+ var ccData = cc.finish();
+ var ss = ccData.selStart;
+ var se = ccData.selEnd;
+ lines = ccData.lines;
+ var lineAttribs = ccData.lineAttribs;
+ var linesWrapped = ccData.linesWrapped;
+
+ if (linesWrapped > 0) {
+ doAlert("Editor warning: "+linesWrapped+" long line"+
+ (linesWrapped == 1 ? " was" : "s were")+" hard-wrapped into "+
+ ccData.numLinesAfter
+ +" lines.");
+ }
+
+ if (ss[0] >= 0) selStart = [ss[0]+a+netNumLinesChangeSoFar, ss[1]];
+ if (se[0] >= 0) selEnd = [se[0]+a+netNumLinesChangeSoFar, se[1]];
+
+ /*var oldLines = rep.alltext.substring(rep.lines.offsetOfIndex(a),
+ rep.lines.offsetOfIndex(b));
+ var newLines = lines.join('\n')+'\n';
+ dmesg("OLD: "+htmlPrettyEscape(oldLines));
+ dmesg("NEW: "+htmlPrettyEscape(newLines));*/
+
+ var entries = [];
+ var nodeToAddAfter = lastDirtyNode;
+ var lineNodeInfos = new Array(lines.length);
+ for(var k=0;k<lines.length;k++) {
+ var lineString = lines[k];
+ var newEntry = createDomLineEntry(lineString);
+ entries.push(newEntry);
+ lineNodeInfos[k] = newEntry.domInfo;
+ }
+ //var fragment = magicdom.wrapDom(document.createDocumentFragment());
+ domInsertsNeeded.push([nodeToAddAfter, lineNodeInfos]);
+ forEach(dirtyNodes, function (n) { toDeleteAtEnd.push(n); });
+ var spliceHints = {};
+ if (selStart) spliceHints.selStart = selStart;
+ if (selEnd) spliceHints.selEnd = selEnd;
+ splicesToDo.push([a+netNumLinesChangeSoFar, b-a, entries, lineAttribs, spliceHints]);
+ netNumLinesChangeSoFar += (lines.length - (b-a));
+ }
+ else if (b > a) {
+ splicesToDo.push([a+netNumLinesChangeSoFar, b-a, [], []]);
+ }
+ i++;
+ }
+
+ var domChanges = (splicesToDo.length > 0);
+
+ // update the representation
+ p.mark("splice");
+ forEach(splicesToDo, function (splice) {
+ doIncorpLineSplice(splice[0], splice[1], splice[2], splice[3], splice[4]);
+ });
+
+ //p.mark("relex");
+ //rep.lexer.lexCharRange(getVisibleCharRange(), function() { return false; });
+ //var isTimeUp = newTimeLimit(100);
+
+ // do DOM inserts
+ p.mark("insert");
+ forEach(domInsertsNeeded, function (ins) {
+ insertDomLines(ins[0], ins[1], isTimeUp);
+ });
+
+ p.mark("del");
+ // delete old dom nodes
+ forEach(toDeleteAtEnd, function (n) {
+ //var id = n.uniqueId();
+
+ // parent of n may not be "root" in IE due to non-tree-shaped DOM (wtf)
+ n.parentNode.removeChild(n);
+
+ //dmesg(htmlPrettyEscape(htmlForRemovedChild(n)));
+ //console.log("removed: "+id);
+ });
+
+ p.mark("findsel");
+ // if the nodes that define the selection weren't encountered during
+ // content collection, figure out where those nodes are now.
+ if (selection && !selStart) {
+ //if (domChanges) dmesg("selection not collected");
+ selStart = getLineAndCharForPoint(selection.startPoint);
+ }
+ if (selection && !selEnd) {
+ selEnd = getLineAndCharForPoint(selection.endPoint);
+ }
+
+ // selection from content collection can, in various ways, extend past final
+ // BR in firefox DOM, so cap the line
+ var numLines = rep.lines.length();
+ if (selStart && selStart[0] >= numLines) {
+ selStart[0] = numLines-1;
+ selStart[1] = rep.lines.atIndex(selStart[0]).text.length;
+ }
+ if (selEnd && selEnd[0] >= numLines) {
+ selEnd[0] = numLines-1;
+ selEnd[1] = rep.lines.atIndex(selEnd[0]).text.length;
+ }
+
+ p.mark("repsel");
+ // update rep
+ repSelectionChange(selStart, selEnd, selection && selection.focusAtStart);
+ // update browser selection
+ p.mark("browsel");
+ if (selection && (domChanges || isCaret())) {
+ // if no DOM changes (not this case), want to treat range selection delicately,
+ // e.g. in IE not lose which end of the selection is the focus/anchor;
+ // on the other hand, we may have just noticed a press of PageUp/PageDown
+ currentCallStack.selectionAffected = true;
+ }
+
+ currentCallStack.domClean = true;
+
+ p.mark("fixview");
+
+ fixView();
+
+ p.end("END");
+
+ return domChanges;
+ }
+
+ function htmlForRemovedChild(n) {
+ var div = doc.createElement("DIV");
+ div.appendChild(n);
+ return div.innerHTML;
+ }
+
+ var STYLE_ATTRIBS = {bold: true, italic: true, underline: true,
+ strikethrough: true, list: true};
+ var OTHER_INCORPED_ATTRIBS = {insertorder: true, author: true};
+
+ function isStyleAttribute(aname) {
+ return !! STYLE_ATTRIBS[aname];
+ }
+ function isIncorpedAttribute(aname) {
+ return (!! STYLE_ATTRIBS[aname]) || (!! OTHER_INCORPED_ATTRIBS[aname]);
+ }
+
+ function insertDomLines(nodeToAddAfter, infoStructs, isTimeUp) {
+ isTimeUp = (isTimeUp || function() { return false; });
+
+ var lastEntry;
+ var lineStartOffset;
+ if (infoStructs.length < 1) return;
+ var startEntry = rep.lines.atKey(uniqueId(infoStructs[0].node));
+ var endEntry = rep.lines.atKey(uniqueId(infoStructs[infoStructs.length-1].node));
+ var charStart = rep.lines.offsetOfEntry(startEntry);
+ var charEnd = rep.lines.offsetOfEntry(endEntry) + endEntry.width;
+
+ //rep.lexer.lexCharRange([charStart, charEnd], isTimeUp);
+
+ forEach(infoStructs, function (info) {
+ var p2 = PROFILER("insertLine", false);
+ var node = info.node;
+ var key = uniqueId(node);
+ var entry;
+ p2.mark("findEntry");
+ if (lastEntry) {
+ // optimization to avoid recalculation
+ var next = rep.lines.next(lastEntry);
+ if (next && next.key == key) {
+ entry = next;
+ lineStartOffset += lastEntry.width;
+ }
+ }
+ if (! entry) {
+ p2.literal(1, "nonopt");
+ entry = rep.lines.atKey(key);
+ lineStartOffset = rep.lines.offsetOfKey(key);
+ }
+ else p2.literal(0, "nonopt");
+ lastEntry = entry;
+ p2.mark("spans");
+ getSpansForLine(entry, function (tokenText, tokenClass) {
+ info.appendSpan(tokenText, tokenClass);
+ }, lineStartOffset, isTimeUp());
+ //else if (entry.text.length > 0) {
+ //info.appendSpan(entry.text, 'dirty');
+ //}
+ p2.mark("addLine");
+ info.prepareForAdd();
+ entry.lineMarker = info.lineMarker;
+ if (! nodeToAddAfter) {
+ root.insertBefore(node, root.firstChild);
+ }
+ else {
+ root.insertBefore(node, nodeToAddAfter.nextSibling);
+ }
+ nodeToAddAfter = node;
+ info.notifyAdded();
+ p2.mark("markClean");
+ markNodeClean(node);
+ p2.end();
+ });
+ }
+
+ function isCaret() {
+ return (rep.selStart && rep.selEnd && rep.selStart[0] == rep.selEnd[0] &&
+ rep.selStart[1] == rep.selEnd[1]);
+ }
+
+ // prereq: isCaret()
+ function caretLine() { return rep.selStart[0]; }
+ function caretColumn() { return rep.selStart[1]; }
+ function caretDocChar() {
+ return rep.lines.offsetOfIndex(caretLine()) + caretColumn();
+ }
+
+ function handleReturnIndentation() {
+ // on return, indent to level of previous line
+ if (isCaret() && caretColumn() == 0 && caretLine() > 0) {
+ var lineNum = caretLine();
+ var thisLine = rep.lines.atIndex(lineNum);
+ var prevLine = rep.lines.prev(thisLine);
+ var prevLineText = prevLine.text;
+ var theIndent = /^ *(?:)/.exec(prevLineText)[0];
+ if (/[\[\(\{]\s*$/.exec(prevLineText)) theIndent += THE_TAB;
+ var cs = Changeset.builder(rep.lines.totalWidth()).keep(
+ rep.lines.offsetOfIndex(lineNum), lineNum).insert(
+ theIndent, [['author',thisAuthor]], rep.apool).toString();
+ performDocumentApplyChangeset(cs);
+ performSelectionChange([lineNum, theIndent.length], [lineNum, theIndent.length]);
+ }
+ }
+
+
+ function setupMozillaCaretHack(lineNum) {
+ // This is really ugly, but by god, it works!
+ // Fixes annoying Firefox caret artifact (observed in 2.0.0.12
+ // and unfixed in Firefox 2 as of now) where mutating the DOM
+ // and then moving the caret to the beginning of a line causes
+ // an image of the caret to be XORed at the top of the iframe.
+ // The previous solution involved remembering to set the selection
+ // later, in response to the next event in the queue, which was hugely
+ // annoying.
+ // This solution: add a space character (0x20) to the beginning of the line.
+ // After setting the selection, remove the space.
+ var lineNode = rep.lines.atIndex(lineNum).lineNode;
+
+ var fc = lineNode.firstChild;
+ while (isBlockElement(fc) && fc.firstChild) {
+ fc = fc.firstChild;
+ }
+ var textNode;
+ if (isNodeText(fc)) {
+ fc.nodeValue = " "+fc.nodeValue;
+ textNode = fc;
+ }
+ else {
+ textNode = doc.createTextNode(" ");
+ fc.parentNode.insertBefore(textNode, fc);
+ }
+ markNodeClean(lineNode);
+ return { unhack: function() {
+ if (textNode.nodeValue == " ") {
+ textNode.parentNode.removeChild(textNode);
+ }
+ else {
+ textNode.nodeValue = textNode.nodeValue.substring(1);
+ }
+ markNodeClean(lineNode);
+ } };
+ }
+
+
+ function getPointForLineAndChar(lineAndChar) {
+ var line = lineAndChar[0];
+ var charsLeft = lineAndChar[1];
+ //console.log("line: %d, key: %s, node: %o", line, rep.lines.atIndex(line).key,
+ //getCleanNodeByKey(rep.lines.atIndex(line).key));
+ var lineEntry = rep.lines.atIndex(line);
+ charsLeft -= lineEntry.lineMarker;
+ if (charsLeft < 0) {
+ charsLeft = 0;
+ }
+ var lineNode = lineEntry.lineNode;
+ var n = lineNode;
+ var after = false;
+ if (charsLeft == 0) {
+ var index = 0;
+ if (browser.msie && line == (rep.lines.length()-1) && lineNode.childNodes.length == 0) {
+ // best to stay at end of last empty div in IE
+ index = 1;
+ }
+ return {node: lineNode, index:index, maxIndex:1};
+ }
+ while (!(n == lineNode && after)) {
+ if (after) {
+ if (n.nextSibling) {
+ n = n.nextSibling;
+ after = false;
+ }
+ else n = n.parentNode;
+ }
+ else {
+ if (isNodeText(n)) {
+ var len = n.nodeValue.length;
+ if (charsLeft <= len) {
+ return {node: n, index:charsLeft, maxIndex:len};
+ }
+ charsLeft -= len;
+ after = true;
+ }
+ else {
+ if (n.firstChild) n = n.firstChild;
+ else after = true;
+ }
+ }
+ }
+ return {node: lineNode, index:1, maxIndex:1};
+ }
+
+ function nodeText(n) {
+ return n.innerText || n.textContent || n.nodeValue || '';
+ }
+
+ function getLineAndCharForPoint(point) {
+ // Turn DOM node selection into [line,char] selection.
+ // This method has to work when the DOM is not pristine,
+ // assuming the point is not in a dirty node.
+ if (point.node == root) {
+ if (point.index == 0) {
+ return [0, 0];
+ }
+ else {
+ var N = rep.lines.length();
+ var ln = rep.lines.atIndex(N-1);
+ return [N-1, ln.text.length];
+ }
+ }
+ else {
+ var n = point.node;
+ var col = 0;
+ // if this part fails, it probably means the selection node
+ // was dirty, and we didn't see it when collecting dirty nodes.
+ if (isNodeText(n)) {
+ col = point.index;
+ }
+ else if (point.index > 0) {
+ col = nodeText(n).length;
+ }
+ var parNode, prevSib;
+ while ((parNode = n.parentNode) != root) {
+ if ((prevSib = n.previousSibling)) {
+ n = prevSib;
+ col += nodeText(n).length;
+ }
+ else {
+ n = parNode;
+ }
+ }
+ if (n.id == "") console.debug("BAD");
+ if (n.firstChild && isBlockElement(n.firstChild)) {
+ col += 1; // lineMarker
+ }
+ var lineEntry = rep.lines.atKey(n.id);
+ var lineNum = rep.lines.indexOfEntry(lineEntry);
+ return [lineNum, col];
+ }
+ }
+
+ function createDomLineEntry(lineString) {
+ var info = doCreateDomLine(lineString.length > 0);
+ var newNode = info.node;
+ return {key: uniqueId(newNode), text: lineString, lineNode: newNode,
+ domInfo: info, lineMarker: 0};
+ }
+
+ function canApplyChangesetToDocument(changes) {
+ return Changeset.oldLen(changes) == rep.alltext.length;
+ }
+
+ function performDocumentApplyChangeset(changes, insertsAfterSelection) {
+ doRepApplyChangeset(changes, insertsAfterSelection);
+
+ var requiredSelectionSetting = null;
+ if (rep.selStart && rep.selEnd) {
+ var selStartChar = rep.lines.offsetOfIndex(rep.selStart[0]) + rep.selStart[1];
+ var selEndChar = rep.lines.offsetOfIndex(rep.selEnd[0]) + rep.selEnd[1];
+ var result = Changeset.characterRangeFollow(changes, selStartChar, selEndChar,
+ insertsAfterSelection);
+ requiredSelectionSetting = [result[0], result[1], rep.selFocusAtStart];
+ }
+
+ var linesMutatee = {
+ splice: function(start, numRemoved, newLinesVA) {
+ domAndRepSplice(start, numRemoved,
+ map(Array.prototype.slice.call(arguments, 2),
+ function(s) { return s.slice(0,-1); }),
+ null);
+ },
+ get: function(i) { return rep.lines.atIndex(i).text+'\n'; },
+ length: function() { return rep.lines.length(); },
+ slice_notused: function(start, end) {
+ return map(rep.lines.slice(start, end), function(e) { return e.text+'\n'; });
+ }
+ };
+
+ Changeset.mutateTextLines(changes, linesMutatee);
+
+ checkALines();
+
+ if (requiredSelectionSetting) {
+ performSelectionChange(lineAndColumnFromChar(requiredSelectionSetting[0]),
+ lineAndColumnFromChar(requiredSelectionSetting[1]),
+ requiredSelectionSetting[2]);
+ }
+
+ function domAndRepSplice(startLine, deleteCount, newLineStrings, isTimeUp) {
+ // dgreensp 3/2009: the spliced lines may be in the middle of a dirty region,
+ // so if no explicit time limit, don't spend a lot of time highlighting
+ isTimeUp = (isTimeUp || newTimeLimit(50));
+
+ var keysToDelete = [];
+ if (deleteCount > 0) {
+ var entryToDelete = rep.lines.atIndex(startLine);
+ for(var i=0;i<deleteCount;i++) {
+ keysToDelete.push(entryToDelete.key);
+ entryToDelete = rep.lines.next(entryToDelete);
+ }
+ }
+
+ var lineEntries = map(newLineStrings, createDomLineEntry);
+
+ doRepLineSplice(startLine, deleteCount, lineEntries);
+
+ var nodeToAddAfter;
+ if (startLine > 0) {
+ nodeToAddAfter = getCleanNodeByKey(rep.lines.atIndex(startLine-1).key);
+ }
+ else nodeToAddAfter = null;
+
+ insertDomLines(nodeToAddAfter, map(lineEntries, function (entry) { return entry.domInfo; }),
+ isTimeUp);
+
+ forEach(keysToDelete, function (k) {
+ var n = doc.getElementById(k);
+ n.parentNode.removeChild(n);
+ });
+
+ if ((rep.selStart && rep.selStart[0] >= startLine && rep.selStart[0] <= startLine+deleteCount) ||
+ (rep.selEnd && rep.selEnd[0] >= startLine && rep.selEnd[0] <= startLine+deleteCount)) {
+ currentCallStack.selectionAffected = true;
+ }
+ }
+ }
+
+ function checkChangesetLineInformationAgainstRep(changes) {
+ return true; // disable for speed
+ var opIter = Changeset.opIterator(Changeset.unpack(changes).ops);
+ var curOffset = 0;
+ var curLine = 0;
+ var curCol = 0;
+ while (opIter.hasNext()) {
+ var o = opIter.next();
+ if (o.opcode == '-' || o.opcode == '=') {
+ curOffset += o.chars;
+ if (o.lines) {
+ curLine += o.lines;
+ curCol = 0;
+ }
+ else {
+ curCol += o.chars;
+ }
+ }
+ var calcLine = rep.lines.indexOfOffset(curOffset);
+ var calcLineStart = rep.lines.offsetOfIndex(calcLine);
+ var calcCol = curOffset - calcLineStart;
+ if (calcCol != curCol || calcLine != curLine) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function doRepApplyChangeset(changes, insertsAfterSelection) {
+ Changeset.checkRep(changes);
+
+ if (Changeset.oldLen(changes) != rep.alltext.length)
+ throw new Error("doRepApplyChangeset length mismatch: "+
+ Changeset.oldLen(changes)+"/"+rep.alltext.length);
+
+ if (! checkChangesetLineInformationAgainstRep(changes)) {
+ throw new Error("doRepApplyChangeset line break mismatch");
+ }
+
+ (function doRecordUndoInformation(changes) {
+ var editEvent = currentCallStack.editEvent;
+ if (editEvent.eventType == "nonundoable") {
+ if (! editEvent.changeset) {
+ editEvent.changeset = changes;
+ }
+ else {
+ editEvent.changeset = Changeset.compose(editEvent.changeset, changes,
+ rep.apool);
+ }
+ }
+ else {
+ var inverseChangeset = Changeset.inverse(changes, {get: function(i) {
+ return rep.lines.atIndex(i).text+'\n';
+ }, length: function() { return rep.lines.length(); }},
+ rep.alines, rep.apool);
+
+ if (! editEvent.backset) {
+ editEvent.backset = inverseChangeset;
+ }
+ else {
+ editEvent.backset = Changeset.compose(inverseChangeset,
+ editEvent.backset, rep.apool);
+ }
+ }
+ })(changes);
+
+ //rep.alltext = Changeset.applyToText(changes, rep.alltext);
+ Changeset.mutateAttributionLines(changes, rep.alines, rep.apool);
+
+ if (changesetTracker.isTracking()) {
+ changesetTracker.composeUserChangeset(changes);
+ }
+
+ }
+
+ function lineAndColumnFromChar(x) {
+ var lineEntry = rep.lines.atOffset(x);
+ var lineStart = rep.lines.offsetOfEntry(lineEntry);
+ var lineNum = rep.lines.indexOfEntry(lineEntry);
+ return [lineNum, x - lineStart];
+ }
+
+ function performDocumentReplaceCharRange(startChar, endChar, newText) {
+ if (startChar == endChar && newText.length == 0) {
+ return;
+ }
+ // Requires that the replacement preserve the property that the
+ // internal document text ends in a newline. Given this, we
+ // rewrite the splice so that it doesn't touch the very last
+ // char of the document.
+ if (endChar == rep.alltext.length) {
+ if (startChar == endChar) {
+ // an insert at end
+ startChar--;
+ endChar--;
+ newText = '\n'+newText.substring(0, newText.length-1);
+ }
+ else if (newText.length == 0) {
+ // a delete at end
+ startChar--;
+ endChar--;
+ }
+ else {
+ // a replace at end
+ endChar--;
+ newText = newText.substring(0, newText.length-1);
+ }
+ }
+ performDocumentReplaceRange(lineAndColumnFromChar(startChar),
+ lineAndColumnFromChar(endChar),
+ newText);
+ }
+
+ function performDocumentReplaceRange(start, end, newText) {
+ //dmesg(String([start.toSource(),end.toSource(),newText.toSource()]));
+
+ // start[0]: <--- start[1] --->CCCCCCCCCCC\n
+ // CCCCCCCCCCCCCCCCCCCC\n
+ // CCCC\n
+ // end[0]: <CCC end[1] CCC>-------\n
+
+ var builder = Changeset.builder(rep.lines.totalWidth());
+ buildKeepToStartOfRange(builder, start);
+ buildRemoveRange(builder, start, end);
+ builder.insert(newText, [['author',thisAuthor]], rep.apool);
+ var cs = builder.toString();
+
+ performDocumentApplyChangeset(cs);
+ }
+
+ function performDocumentApplyAttributesToCharRange(start, end, attribs) {
+ if (end >= rep.alltext.length) {
+ end = rep.alltext.length-1;
+ }
+ performDocumentApplyAttributesToRange(lineAndColumnFromChar(start),
+ lineAndColumnFromChar(end), attribs);
+ }
+
+ function performDocumentApplyAttributesToRange(start, end, attribs) {
+ var builder = Changeset.builder(rep.lines.totalWidth());
+ buildKeepToStartOfRange(builder, start);
+ buildKeepRange(builder, start, end, attribs, rep.apool);
+ var cs = builder.toString();
+ performDocumentApplyChangeset(cs);
+ }
+
+ function buildKeepToStartOfRange(builder, start) {
+ var startLineOffset = rep.lines.offsetOfIndex(start[0]);
+
+ builder.keep(startLineOffset, start[0]);
+ builder.keep(start[1]);
+ }
+ function buildRemoveRange(builder, start, end) {
+ var startLineOffset = rep.lines.offsetOfIndex(start[0]);
+ var endLineOffset = rep.lines.offsetOfIndex(end[0]);
+
+ if (end[0] > start[0]) {
+ builder.remove(endLineOffset - startLineOffset - start[1], end[0] - start[0]);
+ builder.remove(end[1]);
+ }
+ else {
+ builder.remove(end[1] - start[1]);
+ }
+ }
+ function buildKeepRange(builder, start, end, attribs, pool) {
+ var startLineOffset = rep.lines.offsetOfIndex(start[0]);
+ var endLineOffset = rep.lines.offsetOfIndex(end[0]);
+
+ if (end[0] > start[0]) {
+ builder.keep(endLineOffset - startLineOffset - start[1], end[0] - start[0], attribs, pool);
+ builder.keep(end[1], 0, attribs, pool);
+ }
+ else {
+ builder.keep(end[1] - start[1], 0, attribs, pool);
+ }
+ }
+
+ function setAttributeOnSelection(attributeName, attributeValue) {
+ if (!(rep.selStart && rep.selEnd)) return;
+
+ performDocumentApplyAttributesToRange(rep.selStart, rep.selEnd,
+ [[attributeName, attributeValue]]);
+ }
+
+ function toggleAttributeOnSelection(attributeName) {
+ if (!(rep.selStart && rep.selEnd)) return;
+
+ var selectionAllHasIt = true;
+ var withIt = Changeset.makeAttribsString('+', [[attributeName, 'true']], rep.apool);
+ var withItRegex = new RegExp(withIt.replace(/\*/g,'\\*')+"(\\*|$)");
+ function hasIt(attribs) { return withItRegex.test(attribs); }
+
+ var selStartLine = rep.selStart[0];
+ var selEndLine = rep.selEnd[0];
+ for(var n=selStartLine; n<=selEndLine; n++) {
+ var opIter = Changeset.opIterator(rep.alines[n]);
+ var indexIntoLine = 0;
+ var selectionStartInLine = 0;
+ var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline
+ if (n == selStartLine) {
+ selectionStartInLine = rep.selStart[1];
+ }
+ if (n == selEndLine) {
+ selectionEndInLine = rep.selEnd[1];
+ }
+ while (opIter.hasNext()) {
+ var op = opIter.next();
+ var opStartInLine = indexIntoLine;
+ var opEndInLine = opStartInLine + op.chars;
+ if (! hasIt(op.attribs)) {
+ // does op overlap selection?
+ if (! (opEndInLine <= selectionStartInLine || opStartInLine >= selectionEndInLine)) {
+ selectionAllHasIt = false;
+ break;
+ }
+ }
+ indexIntoLine = opEndInLine;
+ }
+ if (! selectionAllHasIt) {
+ break;
+ }
+ }
+
+ if (selectionAllHasIt) {
+ performDocumentApplyAttributesToRange(rep.selStart, rep.selEnd,
+ [[attributeName,'']]);
+ }
+ else {
+ performDocumentApplyAttributesToRange(rep.selStart, rep.selEnd,
+ [[attributeName,'true']]);
+ }
+ }
+
+ function performDocumentReplaceSelection(newText) {
+ if (!(rep.selStart && rep.selEnd)) return;
+ performDocumentReplaceRange(rep.selStart, rep.selEnd, newText);
+ }
+
+ // Change the abstract representation of the document to have a different set of lines.
+ // Must be called after rep.alltext is set.
+ function doRepLineSplice(startLine, deleteCount, newLineEntries) {
+
+ forEach(newLineEntries, function (entry) { entry.width = entry.text.length+1; });
+
+ var startOldChar = rep.lines.offsetOfIndex(startLine);
+ var endOldChar = rep.lines.offsetOfIndex(startLine+deleteCount);
+
+ var oldRegionStart = rep.lines.offsetOfIndex(startLine);
+ var oldRegionEnd = rep.lines.offsetOfIndex(startLine+deleteCount);
+ rep.lines.splice(startLine, deleteCount, newLineEntries);
+ currentCallStack.docTextChanged = true;
+ currentCallStack.repChanged = true;
+ var newRegionEnd = rep.lines.offsetOfIndex(startLine + newLineEntries.length);
+
+ var newText = map(newLineEntries, function (e) { return e.text+'\n'; }).join('');
+
+ rep.alltext = rep.alltext.substring(0, startOldChar) + newText +
+ rep.alltext.substring(endOldChar, rep.alltext.length);
+
+ //var newTotalLength = rep.alltext.length;
+
+ //rep.lexer.updateBuffer(rep.alltext, oldRegionStart, oldRegionEnd - oldRegionStart,
+ //newRegionEnd - oldRegionStart);
+ }
+
+ function doIncorpLineSplice(startLine, deleteCount, newLineEntries, lineAttribs, hints) {
+
+ var startOldChar = rep.lines.offsetOfIndex(startLine);
+ var endOldChar = rep.lines.offsetOfIndex(startLine+deleteCount);
+
+ var oldRegionStart = rep.lines.offsetOfIndex(startLine);
+
+ var selStartHintChar, selEndHintChar;
+ if (hints && hints.selStart) {
+ selStartHintChar = rep.lines.offsetOfIndex(hints.selStart[0]) + hints.selStart[1] -
+ oldRegionStart;
+ }
+ if (hints && hints.selEnd) {
+ selEndHintChar = rep.lines.offsetOfIndex(hints.selEnd[0]) + hints.selEnd[1] -
+ oldRegionStart;
+ }
+
+ var newText = map(newLineEntries, function (e) { return e.text+'\n'; }).join('');
+ var oldText = rep.alltext.substring(startOldChar, endOldChar);
+ var oldAttribs = rep.alines.slice(startLine, startLine+deleteCount).join('');
+ var newAttribs = lineAttribs.join('|1+1')+'|1+1'; // not valid in a changeset
+ var analysis = analyzeChange(oldText, newText, oldAttribs, newAttribs,
+ selStartHintChar, selEndHintChar);
+ var commonStart = analysis[0];
+ var commonEnd = analysis[1];
+ var shortOldText = oldText.substring(commonStart, oldText.length - commonEnd);
+ var shortNewText = newText.substring(commonStart, newText.length - commonEnd);
+ var spliceStart = startOldChar+commonStart;
+ var spliceEnd = endOldChar-commonEnd;
+ var shiftFinalNewlineToBeforeNewText = false;
+
+ // adjust the splice to not involve the final newline of the document;
+ // be very defensive
+ if (shortOldText.charAt(shortOldText.length-1) == '\n' &&
+ shortNewText.charAt(shortNewText.length-1) == '\n') {
+ // replacing text that ends in newline with text that also ends in newline
+ // (still, after analysis, somehow)
+ shortOldText = shortOldText.slice(0,-1);
+ shortNewText = shortNewText.slice(0,-1);
+ spliceEnd--;
+ commonEnd++;
+ }
+ if (shortOldText.length == 0 && spliceStart == rep.alltext.length
+ && shortNewText.length > 0) {
+ // inserting after final newline, bad
+ spliceStart--;
+ spliceEnd--;
+ shortNewText = '\n'+shortNewText.slice(0,-1);
+ shiftFinalNewlineToBeforeNewText = true;
+ }
+ if (spliceEnd == rep.alltext.length && shortOldText.length > 0 &&
+ shortNewText.length == 0) {
+ // deletion at end of rep.alltext
+ if (rep.alltext.charAt(spliceStart-1) == '\n') {
+ // (if not then what the heck? it will definitely lead
+ // to a rep.alltext without a final newline)
+ spliceStart--;
+ spliceEnd--;
+ }
+ }
+
+ if (! (shortOldText.length == 0 && shortNewText.length == 0)) {
+ var oldDocText = rep.alltext;
+ var oldLen = oldDocText.length;
+
+ var spliceStartLine = rep.lines.indexOfOffset(spliceStart);
+ var spliceStartLineStart = rep.lines.offsetOfIndex(spliceStartLine);
+ function startBuilder() {
+ var builder = Changeset.builder(oldLen);
+ builder.keep(spliceStartLineStart, spliceStartLine);
+ builder.keep(spliceStart - spliceStartLineStart);
+ return builder;
+ }
+
+ function eachAttribRun(attribs, func/*(startInNewText, endInNewText, attribs)*/) {
+ var attribsIter = Changeset.opIterator(attribs);
+ var textIndex = 0;
+ var newTextStart = commonStart;
+ var newTextEnd = newText.length - commonEnd - (shiftFinalNewlineToBeforeNewText ? 1 : 0);
+ while (attribsIter.hasNext()) {
+ var op = attribsIter.next();
+ var nextIndex = textIndex + op.chars;
+ if (!(nextIndex <= newTextStart || textIndex >= newTextEnd)) {
+ func(Math.max(newTextStart, textIndex), Math.min(newTextEnd, nextIndex), op.attribs);
+ }
+ textIndex = nextIndex;
+ }
+ }
+
+ var justApplyStyles = (shortNewText == shortOldText);
+ var theChangeset;
+
+ if (justApplyStyles) {
+ // create changeset that clears the incorporated styles on
+ // the existing text. we compose this with the
+ // changeset the applies the styles found in the DOM.
+ // This allows us to incorporate, e.g., Safari's native "unbold".
+
+ var incorpedAttribClearer = cachedStrFunc(function (oldAtts) {
+ return Changeset.mapAttribNumbers(oldAtts, function(n) {
+ var k = rep.apool.getAttribKey(n);
+ if (isStyleAttribute(k)) {
+ return rep.apool.putAttrib([k,'']);
+ }
+ return false;
+ });
+ });
+
+ var builder1 = startBuilder();
+ if (shiftFinalNewlineToBeforeNewText) {
+ builder1.keep(1, 1);
+ }
+ eachAttribRun(oldAttribs, function(start, end, attribs) {
+ builder1.keepText(newText.substring(start, end), incorpedAttribClearer(attribs));
+ });
+ var clearer = builder1.toString();
+
+ var builder2 = startBuilder();
+ if (shiftFinalNewlineToBeforeNewText) {
+ builder2.keep(1, 1);
+ }
+ eachAttribRun(newAttribs, function(start, end, attribs) {
+ builder2.keepText(newText.substring(start, end), attribs);
+ });
+ var styler = builder2.toString();
+
+ theChangeset = Changeset.compose(clearer, styler, rep.apool);
+ }
+ else {
+ var builder = startBuilder();
+
+ var spliceEndLine = rep.lines.indexOfOffset(spliceEnd);
+ var spliceEndLineStart = rep.lines.offsetOfIndex(spliceEndLine);
+ if (spliceEndLineStart > spliceStart) {
+ builder.remove(spliceEndLineStart - spliceStart, spliceEndLine - spliceStartLine);
+ builder.remove(spliceEnd - spliceEndLineStart);
+ }
+ else {
+ builder.remove(spliceEnd - spliceStart);
+ }
+
+ var isNewTextMultiauthor = false;
+ var authorAtt = Changeset.makeAttribsString(
+ '+', (thisAuthor ? [['author', thisAuthor]] : []), rep.apool);
+ var authorizer = cachedStrFunc(function(oldAtts) {
+ if (isNewTextMultiauthor) {
+ // prefer colors from DOM
+ return Changeset.composeAttributes(authorAtt, oldAtts, true, rep.apool);
+ }
+ else {
+ // use this author's color
+ return Changeset.composeAttributes(oldAtts, authorAtt, true, rep.apool);
+ }
+ });
+
+ var foundDomAuthor = '';
+ eachAttribRun(newAttribs, function(start, end, attribs) {
+ var a = Changeset.attribsAttributeValue(attribs, 'author', rep.apool);
+ if (a && a != foundDomAuthor) {
+ if (! foundDomAuthor) {
+ foundDomAuthor = a;
+ }
+ else {
+ isNewTextMultiauthor = true; // multiple authors in DOM!
+ }
+ }
+ });
+
+ if (shiftFinalNewlineToBeforeNewText) {
+ builder.insert('\n', authorizer(''));
+ }
+
+ eachAttribRun(newAttribs, function(start, end, attribs) {
+ builder.insert(newText.substring(start, end), authorizer(attribs));
+ });
+ theChangeset = builder.toString();
+ }
+
+ //dmesg(htmlPrettyEscape(theChangeset));
+
+ doRepApplyChangeset(theChangeset);
+ }
+
+ // do this no matter what, because we need to get the right
+ // line keys into the rep.
+ doRepLineSplice(startLine, deleteCount, newLineEntries);
+
+ checkALines();
+ }
+
+ function cachedStrFunc(func) {
+ var cache = {};
+ return function(s) {
+ if (! cache[s]) {
+ cache[s] = func(s);
+ }
+ return cache[s];
+ };
+ }
+
+ function analyzeChange(oldText, newText, oldAttribs, newAttribs, optSelStartHint, optSelEndHint) {
+ function incorpedAttribFilter(anum) {
+ return isStyleAttribute(rep.apool.getAttribKey(anum));
+ }
+ function attribRuns(attribs) {
+ var lengs = [];
+ var atts = [];
+ var iter = Changeset.opIterator(attribs);
+ while (iter.hasNext()) {
+ var op = iter.next();
+ lengs.push(op.chars);
+ atts.push(op.attribs);
+ }
+ return [lengs,atts];
+ }
+ function attribIterator(runs, backward) {
+ var lengs = runs[0];
+ var atts = runs[1];
+ var i = (backward ? lengs.length-1 : 0);
+ var j = 0;
+ return function next() {
+ while (j >= lengs[i]) {
+ if (backward) i--; else i++;
+ j = 0;
+ }
+ var a = atts[i];
+ j++;
+ return a;
+ };
+ }
+
+ var oldLen = oldText.length;
+ var newLen = newText.length;
+ var minLen = Math.min(oldLen, newLen);
+
+ var oldARuns = attribRuns(Changeset.filterAttribNumbers(oldAttribs, incorpedAttribFilter));
+ var newARuns = attribRuns(Changeset.filterAttribNumbers(newAttribs, incorpedAttribFilter));
+
+ var commonStart = 0;
+ var oldStartIter = attribIterator(oldARuns, false);
+ var newStartIter = attribIterator(newARuns, false);
+ while (commonStart < minLen) {
+ if (oldText.charAt(commonStart) == newText.charAt(commonStart) &&
+ oldStartIter() == newStartIter()) {
+ commonStart++;
+ }
+ else break;
+ }
+
+ var commonEnd = 0;
+ var oldEndIter = attribIterator(oldARuns, true);
+ var newEndIter = attribIterator(newARuns, true);
+ while (commonEnd < minLen) {
+ if (commonEnd == 0) {
+ // assume newline in common
+ oldEndIter(); newEndIter();
+ commonEnd++;
+ }
+ else if (oldText.charAt(oldLen-1-commonEnd) == newText.charAt(newLen-1-commonEnd) &&
+ oldEndIter() == newEndIter()) {
+ commonEnd++;
+ }
+ else break;
+ }
+
+ var hintedCommonEnd = -1;
+ if ((typeof optSelEndHint) == "number") {
+ hintedCommonEnd = newLen - optSelEndHint;
+ }
+
+
+ if (commonStart + commonEnd > oldLen) {
+ // ambiguous insertion
+ var minCommonEnd = oldLen - commonStart;
+ var maxCommonEnd = commonEnd;
+ if (hintedCommonEnd >= minCommonEnd && hintedCommonEnd <= maxCommonEnd) {
+ commonEnd = hintedCommonEnd;
+ }
+ else {
+ commonEnd = minCommonEnd;
+ }
+ commonStart = oldLen - commonEnd;
+ }
+ if (commonStart + commonEnd > newLen) {
+ // ambiguous deletion
+ var minCommonEnd = newLen - commonStart;
+ var maxCommonEnd = commonEnd;
+ if (hintedCommonEnd >= minCommonEnd && hintedCommonEnd <= maxCommonEnd) {
+ commonEnd = hintedCommonEnd;
+ }
+ else {
+ commonEnd = minCommonEnd;
+ }
+ commonStart = newLen - commonEnd;
+ }
+
+ return [commonStart, commonEnd];
+ }
+
+ function equalLineAndChars(a, b) {
+ if (!a) return !b;
+ if (!b) return !a;
+ return (a[0] == b[0] && a[1] == b[1]);
+ }
+
+ function performSelectionChange(selectStart, selectEnd, focusAtStart) {
+ if (repSelectionChange(selectStart, selectEnd, focusAtStart)) {
+ currentCallStack.selectionAffected = true;
+ }
+ }
+
+ // Change the abstract representation of the document to have a different selection.
+ // Should not rely on the line representation. Should not affect the DOM.
+ function repSelectionChange(selectStart, selectEnd, focusAtStart) {
+ focusAtStart = !! focusAtStart;
+
+ var newSelFocusAtStart = (focusAtStart &&
+ ((! selectStart) || (! selectEnd) ||
+ (selectStart[0] != selectEnd[0]) ||
+ (selectStart[1] != selectEnd[1])));
+
+ if ((! equalLineAndChars(rep.selStart, selectStart)) ||
+ (! equalLineAndChars(rep.selEnd, selectEnd)) ||
+ (rep.selFocusAtStart != newSelFocusAtStart)) {
+ rep.selStart = selectStart;
+ rep.selEnd = selectEnd;
+ rep.selFocusAtStart = newSelFocusAtStart;
+ if (mozillaFakeArrows) mozillaFakeArrows.notifySelectionChanged();
+ currentCallStack.repChanged = true;
+
+ return true;
+ //console.log("selStart: %o, selEnd: %o, focusAtStart: %s", rep.selStart, rep.selEnd,
+ //String(!!rep.selFocusAtStart));
+ }
+ return false;
+ //console.log("%o %o %s", rep.selStart, rep.selEnd, rep.selFocusAtStart);
+ }
+
+ /*function escapeHTML(s) {
+ var re = /[&<>'"]/g; /']/; // stupid indentation thing
+ if (! re.MAP) {
+ // persisted across function calls!
+ re.MAP = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;'
+ };
+ }
+ return s.replace(re, function(c) { return re.MAP[c]; });
+ }*/
+
+ function doCreateDomLine(nonEmpty) {
+ if (browser.msie && (! nonEmpty)) {
+ var result = { node: null,
+ appendSpan: noop,
+ prepareForAdd: noop,
+ notifyAdded: noop,
+ clearSpans: noop,
+ finishUpdate: noop,
+ lineMarker: 0 };
+
+ var lineElem = doc.createElement("div");
+ result.node = lineElem;
+
+ result.notifyAdded = function() {
+ // magic -- settng an empty div's innerHTML to the empty string
+ // keeps it from collapsing. Apparently innerHTML must be set *after*
+ // adding the node to the DOM.
+ // Such a div is what IE 6 creates naturally when you make a blank line
+ // in a document of divs. However, when copy-and-pasted the div will
+ // contain a space, so we note its emptiness with a property.
+ lineElem.innerHTML = "";
+ // a primitive-valued property survives copy-and-paste
+ setAssoc(lineElem, "shouldBeEmpty", true);
+ // an object property doesn't
+ setAssoc(lineElem, "unpasted", {});
+ };
+ var lineClass = 'ace-line';
+ result.appendSpan = function(txt, cls) {
+ if ((! txt) && cls) {
+ // gain a whole-line style (currently to show insertion point in CSS)
+ lineClass = domline.addToLineClass(lineClass, cls);
+ }
+ // otherwise, ignore appendSpan, this is an empty line
+ };
+ result.clearSpans = function() {
+ lineClass = ''; // non-null to cause update
+ };
+ function writeClass() {
+ if (lineClass !== null) lineElem.className = lineClass;
+ }
+ result.prepareForAdd = writeClass;
+ result.finishUpdate = writeClass;
+ result.getInnerHTML = function() { return ""; };
+
+ return result;
+ }
+ else {
+ return domline.createDomLine(nonEmpty, doesWrap, browser, doc);
+ }
+ }
+
+ function textify(str) {
+ return str.replace(/[\n\r ]/g, ' ').replace(/\xa0/g, ' ').replace(/\t/g, ' ');
+ }
+
+ var _blockElems = { "div":1, "p":1, "pre":1, "li":1, "ol":1, "ul":1 };
+ function isBlockElement(n) {
+ return !!_blockElems[(n.tagName || "").toLowerCase()];
+ }
+
+ function getDirtyRanges() {
+ // based on observedChanges, return a list of ranges of original lines
+ // that need to be removed or replaced with new user content to incorporate
+ // the user's changes into the line representation. ranges may be zero-length,
+ // indicating inserted content. for example, [0,0] means content was inserted
+ // at the top of the document, while [3,4] means line 3 was deleted, modified,
+ // or replaced with one or more new lines of content. ranges do not touch.
+
+ var p = PROFILER("getDirtyRanges", false);
+ p.forIndices = 0;
+ p.consecutives = 0;
+ p.corrections = 0;
+
+ var cleanNodeForIndexCache = {};
+ var N = rep.lines.length(); // old number of lines
+ function cleanNodeForIndex(i) {
+ // if line (i) in the un-updated line representation maps to a clean node
+ // in the document, return that node.
+ // if (i) is out of bounds, return true. else return false.
+ if (cleanNodeForIndexCache[i] === undefined) {
+ p.forIndices++;
+ var result;
+ if (i < 0 || i >= N) {
+ result = true; // truthy, but no actual node
+ }
+ else {
+ var key = rep.lines.atIndex(i).key;
+ result = (getCleanNodeByKey(key) || false);
+ }
+ cleanNodeForIndexCache[i] = result;
+ }
+ return cleanNodeForIndexCache[i];
+ }
+ var isConsecutiveCache = {};
+ function isConsecutive(i) {
+ if (isConsecutiveCache[i] === undefined) {
+ p.consecutives++;
+ isConsecutiveCache[i] = (function() {
+ // returns whether line (i) and line (i-1), assumed to be map to clean DOM nodes,
+ // or document boundaries, are consecutive in the changed DOM
+ var a = cleanNodeForIndex(i-1);
+ var b = cleanNodeForIndex(i);
+ if ((!a) || (!b)) return false; // violates precondition
+ if ((a === true) && (b === true)) return ! root.firstChild;
+ if ((a === true) && b.previousSibling) return false;
+ if ((b === true) && a.nextSibling) return false;
+ if ((a === true) || (b === true)) return true;
+ return a.nextSibling == b;
+ })();
+ }
+ return isConsecutiveCache[i];
+ }
+ function isClean(i) {
+ // returns whether line (i) in the un-updated representation maps to a clean node,
+ // or is outside the bounds of the document
+ return !! cleanNodeForIndex(i);
+ }
+ // list of pairs, each representing a range of lines that is clean and consecutive
+ // in the changed DOM. lines (-1) and (N) are always clean, but may or may not
+ // be consecutive with lines in the document. pairs are in sorted order.
+ var cleanRanges = [[-1,N+1]];
+ function rangeForLine(i) {
+ // returns index of cleanRange containing i, or -1 if none
+ var answer = -1;
+ forEach(cleanRanges, function (r, idx) {
+ if (i >= r[1]) return false; // keep looking
+ if (i < r[0]) return true; // not found, stop looking
+ answer = idx;
+ return true; // found, stop looking
+ });
+ return answer;
+ }
+ function removeLineFromRange(rng, line) {
+ // rng is index into cleanRanges, line is line number
+ // precond: line is in rng
+ var a = cleanRanges[rng][0];
+ var b = cleanRanges[rng][1];
+ if ((a+1) == b) cleanRanges.splice(rng, 1);
+ else if (line == a) cleanRanges[rng][0]++;
+ else if (line == (b-1)) cleanRanges[rng][1]--;
+ else cleanRanges.splice(rng, 1, [a,line], [line+1,b]);
+ }
+ function splitRange(rng, pt) {
+ // precond: pt splits cleanRanges[rng] into two non-empty ranges
+ var a = cleanRanges[rng][0];
+ var b = cleanRanges[rng][1];
+ cleanRanges.splice(rng, 1, [a,pt], [pt,b]);
+ }
+ var correctedLines = {};
+ function correctlyAssignLine(line) {
+ if (correctedLines[line]) return true;
+ p.corrections++;
+ correctedLines[line] = true;
+ // "line" is an index of a line in the un-updated rep.
+ // returns whether line was already correctly assigned (i.e. correctly
+ // clean or dirty, according to cleanRanges, and if clean, correctly
+ // attached or not attached (i.e. in the same range as) the prev and next lines).
+ //console.log("correctly assigning: %d", line);
+ var rng = rangeForLine(line);
+ var lineClean = isClean(line);
+ if (rng < 0) {
+ if (lineClean) {
+ console.debug("somehow lost clean line");
+ }
+ return true;
+ }
+ if (! lineClean) {
+ // a clean-range includes this dirty line, fix it
+ removeLineFromRange(rng, line);
+ return false;
+ }
+ else {
+ // line is clean, but could be wrongly connected to a clean line
+ // above or below
+ var a = cleanRanges[rng][0];
+ var b = cleanRanges[rng][1];
+ var didSomething = false;
+ // we'll leave non-clean adjacent nodes in the clean range for the caller to
+ // detect and deal with. we deal with whether the range should be split
+ // just above or just below this line.
+ if (a < line && isClean(line-1) && ! isConsecutive(line)) {
+ splitRange(rng, line);
+ didSomething = true;
+ }
+ if (b > (line+1) && isClean(line+1) && ! isConsecutive(line+1)) {
+ splitRange(rng, line+1);
+ didSomething = true;
+ }
+ return ! didSomething;
+ }
+ }
+ function detectChangesAroundLine(line, reqInARow) {
+ // make sure cleanRanges is correct about line number "line" and the surrounding
+ // lines; only stops checking at end of document or after no changes need
+ // making for several consecutive lines. note that iteration is over old lines,
+ // so this operation takes time proportional to the number of old lines
+ // that are changed or missing, not the number of new lines inserted.
+ var correctInARow = 0;
+ var currentIndex = line;
+ while (correctInARow < reqInARow && currentIndex >= 0) {
+ if (correctlyAssignLine(currentIndex)) {
+ correctInARow++;
+ }
+ else correctInARow = 0;
+ currentIndex--;
+ }
+ correctInARow = 0;
+ currentIndex = line;
+ while (correctInARow < reqInARow && currentIndex < N) {
+ if (correctlyAssignLine(currentIndex)) {
+ correctInARow++;
+ }
+ else correctInARow = 0;
+ currentIndex++;
+ }
+ }
+
+ if (N == 0) {
+ p.cancel();
+ if (! isConsecutive(0)) {
+ splitRange(0, 0);
+ }
+ }
+ else {
+ p.mark("topbot");
+ detectChangesAroundLine(0,1);
+ detectChangesAroundLine(N-1,1);
+
+ p.mark("obs");
+ //console.log("observedChanges: "+toSource(observedChanges));
+ for (var k in observedChanges.cleanNodesNearChanges) {
+ var key = k.substring(1);
+ if (rep.lines.containsKey(key)) {
+ var line = rep.lines.indexOfKey(key);
+ detectChangesAroundLine(line,2);
+ }
+ }
+ p.mark("stats&calc");
+ p.literal(p.forIndices, "byidx");
+ p.literal(p.consecutives, "cons");
+ p.literal(p.corrections, "corr");
+ }
+
+ var dirtyRanges = [];
+ for(var r=0;r<cleanRanges.length-1;r++) {
+ dirtyRanges.push([cleanRanges[r][1], cleanRanges[r+1][0]]);
+ }
+
+ p.end();
+
+ return dirtyRanges;
+ }
+
+ function markNodeClean(n) {
+ // clean nodes have knownHTML that matches their innerHTML
+ var dirtiness = {};
+ dirtiness.nodeId = uniqueId(n);
+ dirtiness.knownHTML = n.innerHTML;
+ if (browser.msie) {
+ // adding a space to an "empty" div in IE designMode doesn't
+ // change the innerHTML of the div's parent; also, other
+ // browsers don't support innerText
+ dirtiness.knownText = n.innerText;
+ }
+ setAssoc(n, "dirtiness", dirtiness);
+ }
+
+ function isNodeDirty(n) {
+ var p = PROFILER("cleanCheck", false);
+ if (n.parentNode != root) return true;
+ var data = getAssoc(n, "dirtiness");
+ if (!data) return true;
+ if (n.id !== data.nodeId) return true;
+ if (browser.msie) {
+ if (n.innerText !== data.knownText) return true;
+ }
+ if (n.innerHTML !== data.knownHTML) return true;
+ p.end();
+ return false;
+ }
+
+ function getLineEntryTopBottom(entry, destObj) {
+ var dom = entry.lineNode;
+ var top = dom.offsetTop;
+ var height = dom.offsetHeight;
+ var obj = (destObj || {});
+ obj.top = top;
+ obj.bottom = (top+height);
+ return obj;
+ }
+
+ function getViewPortTopBottom() {
+ var theTop = getScrollY();
+ var doc = outerWin.document;
+ var height = doc.documentElement.clientHeight;
+ return {top:theTop, bottom:(theTop+height)};
+ }
+
+ function getVisibleLineRange() {
+ var viewport = getViewPortTopBottom();
+ //console.log("viewport top/bottom: %o", viewport);
+ var obj = {};
+ var start = rep.lines.search(function (e) {
+ return getLineEntryTopBottom(e, obj).bottom > viewport.top;
+ });
+ var end = rep.lines.search(function(e) {
+ return getLineEntryTopBottom(e, obj).top >= viewport.bottom;
+ });
+ if (end < start) end = start; // unlikely
+ //console.log(start+","+end);
+ return [start,end];
+ }
+
+ function getVisibleCharRange() {
+ var lineRange = getVisibleLineRange();
+ return [rep.lines.offsetOfIndex(lineRange[0]),
+ rep.lines.offsetOfIndex(lineRange[1])];
+ }
+
+ function handleClick(evt) {
+ inCallStack("handleClick", function() {
+ idleWorkTimer.atMost(200);
+ });
+
+ // only want to catch left-click
+ if ((! evt.ctrlKey) && (evt.button != 2) && (evt.button != 3)) {
+ // find A tag with HREF
+ function isLink(n) { return (n.tagName||'').toLowerCase() == "a" && n.href; }
+ var n = evt.target;
+ while (n && n.parentNode && ! isLink(n)) { n = n.parentNode; }
+ if (n && isLink(n)) {
+ try {
+ var newWindow = window.open(n.href, '_blank');
+ newWindow.focus();
+ }
+ catch (e) {
+ // absorb "user canceled" error in IE for certain prompts
+ }
+ evt.preventDefault();
+ }
+ }
+ }
+
+ function doReturnKey() {
+ if (! (rep.selStart && rep.selEnd)) {
+ return;
+ }
+ var lineNum = rep.selStart[0];
+ var listType = getLineListType(lineNum);
+
+ performDocumentReplaceSelection('\n');
+ if (listType) {
+ if (lineNum+1 < rep.lines.length()) {
+ setLineListType(lineNum+1, listType);
+ }
+ }
+ else {
+ handleReturnIndentation();
+ }
+ }
+
+ function doIndentOutdent(isOut) {
+ if (! (rep.selStart && rep.selEnd)) {
+ return false;
+ }
+
+ var firstLine, lastLine;
+ firstLine = rep.selStart[0];
+ lastLine = Math.max(firstLine,
+ rep.selEnd[0] - ((rep.selEnd[1] == 0) ? 1 : 0));
+
+ var mods = [];
+ var foundLists = false;
+ for(var n=firstLine;n<=lastLine;n++) {
+ var listType = getLineListType(n);
+ if (listType) {
+ listType = /([a-z]+)([12345678])/.exec(listType);
+ if (listType) {
+ foundLists = true;
+ var t = listType[1];
+ var level = Number(listType[2]);
+ var newLevel =
+ Math.max(1, Math.min(MAX_LIST_LEVEL,
+ level + (isOut ? -1 : 1)));
+ if (level != newLevel) {
+ mods.push([n, t+newLevel]);
+ }
+ }
+ }
+ }
+
+ if (mods.length > 0) {
+ setLineListTypes(mods);
+ }
+
+ return foundLists;
+ }
+
+ function doTabKey(shiftDown) {
+ if (! doIndentOutdent(shiftDown)) {
+ performDocumentReplaceSelection(THE_TAB);
+ }
+ }
+
+ function doDeleteKey(optEvt) {
+ var evt = optEvt || {};
+ var handled = false;
+ if (rep.selStart) {
+ if (isCaret()) {
+ var lineNum = caretLine();
+ var col = caretColumn();
+ var lineEntry = rep.lines.atIndex(lineNum);
+ var lineText = lineEntry.text;
+ var lineMarker = lineEntry.lineMarker;
+ if (/^ +$/.exec(lineText.substring(lineMarker, col))) {
+ var col2 = col - lineMarker;
+ var tabSize = THE_TAB.length;
+ var toDelete = ((col2 - 1) % tabSize)+1;
+ performDocumentReplaceRange([lineNum,col-toDelete],
+ [lineNum,col], '');
+ //scrollSelectionIntoView();
+ handled = true;
+ }
+ }
+ if (! handled) {
+ if (isCaret()) {
+ var theLine = caretLine();
+ var lineEntry = rep.lines.atIndex(theLine);
+ if (caretColumn() <= lineEntry.lineMarker) {
+ // delete at beginning of line
+ var action = 'delete_newline';
+ var prevLineListType =
+ (theLine > 0 ? getLineListType(theLine-1) : '');
+ var thisLineListType = getLineListType(theLine);
+ var prevLineEntry = (theLine > 0 &&
+ rep.lines.atIndex(theLine-1));
+ var prevLineBlank = (prevLineEntry &&
+ prevLineEntry.text.length ==
+ prevLineEntry.lineMarker);
+ if (thisLineListType) {
+ // this line is a list
+ /*if (prevLineListType) {
+ // prev line is a list too, remove this bullet
+ performDocumentReplaceRange([theLine-1, prevLineEntry.text.length],
+ [theLine, lineEntry.lineMarker], '');
+ }
+ else*/ if (prevLineBlank && ! prevLineListType) {
+ // previous line is blank, remove it
+ performDocumentReplaceRange([theLine-1, prevLineEntry.text.length],
+ [theLine, 0], '');
+ }
+ else {
+ // delistify
+ performDocumentReplaceRange([theLine, 0],
+ [theLine, lineEntry.lineMarker], '');
+ }
+ }
+ else if (theLine > 0) {
+ // remove newline
+ performDocumentReplaceRange([theLine-1, prevLineEntry.text.length],
+ [theLine, 0], '');
+ }
+ }
+ else {
+ var docChar = caretDocChar();
+ if (docChar > 0) {
+ if (evt.metaKey || evt.ctrlKey || evt.altKey) {
+ // delete as many unicode "letters or digits" in a row as possible;
+ // always delete one char, delete further even if that first char
+ // isn't actually a word char.
+ var deleteBackTo = docChar-1;
+ while (deleteBackTo > lineEntry.lineMarker &&
+ isWordChar(rep.alltext.charAt(deleteBackTo-1))) {
+ deleteBackTo--;
+ }
+ performDocumentReplaceCharRange(deleteBackTo, docChar, '');
+ }
+ else {
+ // normal delete
+ performDocumentReplaceCharRange(docChar-1, docChar, '');
+ }
+ }
+ }
+ }
+ else {
+ performDocumentReplaceSelection('');
+ }
+ }
+ }
+ }
+
+ // set of "letter or digit" chars is based on section 20.5.16 of the original Java Language Spec
+ var REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
+ var REGEX_SPACE = /\s/;
+
+ function isWordChar(c) {
+ return !! REGEX_WORDCHAR.exec(c);
+ }
+ function isSpaceChar(c) {
+ return !! REGEX_SPACE.exec(c);
+ }
+
+ function moveByWordInLine(lineText, initialIndex, forwardNotBack) {
+ var i = initialIndex;
+ function nextChar() {
+ if (forwardNotBack) return lineText.charAt(i);
+ else return lineText.charAt(i-1);
+ }
+ function advance() { if (forwardNotBack) i++; else i--; }
+ function isDone() {
+ if (forwardNotBack) return i >= lineText.length;
+ else return i <= 0;
+ }
+
+ // On Mac and Linux, move right moves to end of word and move left moves to start;
+ // on Windows, always move to start of word.
+ // On Windows, Firefox and IE disagree on whether to stop for punctuation (FF says no).
+ if (browser.windows && forwardNotBack) {
+ while ((! isDone()) && isWordChar(nextChar())) { advance(); }
+ while ((! isDone()) && ! isWordChar(nextChar())) { advance(); }
+ }
+ else {
+ while ((! isDone()) && ! isWordChar(nextChar())) { advance(); }
+ while ((! isDone()) && isWordChar(nextChar())) { advance(); }
+ }
+
+ return i;
+ }
+
+ function handleKeyEvent(evt) {
+ if (DEBUG && top.DONT_INCORP) return;
+
+ /*if (evt.which == 48) {
+ //setEditable(! isEditable);
+ //doAlert(getInnerWidth());
+ //doAlert(doc.documentElement.innerWidth)
+ alert(eval(prompt()));
+ evt.preventDefault();
+ return;
+ }*/
+ /*if (evt.which == 48) {
+ alert(doc.body.innerHTML);
+ }*/
+ /*if (evt.which == 48 && evt.type == "keydown") {
+ var lineHeights = [];
+ function eachChild(node, func) {
+ if (node.firstChild) {
+ var n = node.firstChild;
+ while (n) {
+ func(n);
+ n = n.nextSibling;
+ }
+ }
+ }
+ eachChild(doc.body, function (n) {
+ if (n.clientHeight) {
+ lineHeights.push(n.clientHeight);
+ }
+ });
+ alert(lineHeights.join(','));
+ }*/
+ /*if (evt.which == 48) {
+ top.DONT_INCORP = true;
+ var cmdTarget = doc;
+ if (browser.msie) {
+ if (doc.selection) {
+ cmdTarget = doc.selection.createRange();
+ }
+ else cmdTarget = null;
+ }
+ if (cmdTarget) {
+ cmdTarget.execCommand("Bold", false, null);
+ }
+ alert(doc.body.innerHTML);
+ evt.preventDefault();
+ return;
+ }*/
+ /*if (evt.which == 48) {
+ if (evt.type == "keypress") {
+ top.console.log(window.getSelection().getRangeAt(0));
+ evt.preventDefault();
+ }
+ return;
+ }*/
+ /*if (evt.which == 48) {
+ if (evt.type == "keypress") {
+ inCallStack("bold", function() {
+ fastIncorp(9);
+ toggleAttributeOnSelection('bold');
+ });
+ evt.preventDefault();
+ }
+ return;
+ }*/
+ /*if (evt.which == 48) {
+ if (evt.type == "keypress") {
+ inCallStack("insertunorderedlist", function() {
+ fastIncorp(9);
+ doInsertUnorderedList();
+ });
+ evt.preventDefault();
+ }
+ return;
+ }*/
+
+ if (! isEditable) return;
+
+ var type = evt.type;
+ var charCode = evt.charCode;
+ var keyCode = evt.keyCode;
+ var mods = "";
+ if (evt.altKey) mods = mods+"A";
+ if (evt.ctrlKey) mods = mods+"C";
+ if (evt.shiftKey) mods = mods+"S";
+ if (evt.metaKey) mods = mods+"M";
+ var modsPrfx = "";
+ if (mods) modsPrfx = mods+"-";
+ var which = evt.which;
+
+ //dmesg("keyevent type: "+type+", which: "+which);
+
+ // Don't take action based on modifier keys going up and down.
+ // Modifier keys do not generate "keypress" events.
+ // 224 is the command-key under Mac Firefox.
+ // 91 is the Windows key in IE; it is ASCII for open-bracket but isn't the keycode for that key
+ // 20 is capslock in IE.
+ var isModKey = ((!charCode) &&
+ ((type == "keyup") || (type == "keydown")) &&
+ (keyCode == 16 || keyCode == 17 || keyCode == 18 || keyCode == 20 || keyCode == 224
+ || keyCode == 91));
+ if (isModKey) return;
+
+ var specialHandled = false;
+ var isTypeForSpecialKey = ((browser.msie || browser.safari) ?
+ (type == "keydown") : (type == "keypress"));
+ var isTypeForCmdKey = ((browser.msie || browser.safari) ? (type == "keydown") : (type == "keypress"));
+
+ var stopped = false;
+
+ inCallStack("handleKeyEvent", function() {
+
+ if (type == "keypress" ||
+ (isTypeForSpecialKey && keyCode == 13/*return*/)) {
+ // in IE, special keys don't send keypress, the keydown does the action
+ if (! outsideKeyPress(evt)) {
+ evt.preventDefault();
+ stopped = true;
+ }
+ }
+ else if (type == "keydown") {
+ outsideKeyDown(evt);
+ }
+
+ if (! stopped) {
+ if (isTypeForSpecialKey && keyCode == 8) {
+ // "delete" key; in mozilla, if we're at the beginning of a line, normalize now,
+ // or else deleting a blank line can take two delete presses.
+ // --
+ // we do deletes completely customly now:
+ // - allows consistent (and better) meta-delete behavior
+ // - normalizing and then allowing default behavior confused IE
+ // - probably eliminates a few minor quirks
+ fastIncorp(3);
+ evt.preventDefault();
+ doDeleteKey(evt);
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForSpecialKey && keyCode == 13) {
+ // return key, handle specially;
+ // note that in mozilla we need to do an incorporation for proper return behavior anyway.
+ fastIncorp(4);
+ evt.preventDefault();
+ doReturnKey();
+ //scrollSelectionIntoView();
+ scheduler.setTimeout(function() {outerWin.scrollBy(-100,0);}, 0);
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForSpecialKey && keyCode == 9 &&
+ ! (evt.metaKey || evt.ctrlKey)) {
+ // tab
+ fastIncorp(5);
+ evt.preventDefault();
+ doTabKey(evt.shiftKey);
+ //scrollSelectionIntoView();
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "z" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-Z (undo)
+ fastIncorp(6);
+ evt.preventDefault();
+ if (evt.shiftKey) {
+ doUndoRedo("redo");
+ }
+ else {
+ doUndoRedo("undo");
+ }
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "y" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-Y (redo)
+ fastIncorp(10);
+ evt.preventDefault();
+ doUndoRedo("redo");
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "b" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-B (bold)
+ fastIncorp(13);
+ evt.preventDefault();
+ toggleAttributeOnSelection('bold');
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "i" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-I (italic)
+ fastIncorp(14);
+ evt.preventDefault();
+ toggleAttributeOnSelection('italic');
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "u" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-U (underline)
+ fastIncorp(15);
+ evt.preventDefault();
+ toggleAttributeOnSelection('underline');
+ specialHandled = true;
+ }
+ if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "h" &&
+ (evt.ctrlKey)) {
+ // cmd-H (backspace)
+ fastIncorp(20);
+ evt.preventDefault();
+ doDeleteKey();
+ specialHandled = true;
+ }
+ /*if ((!specialHandled) && isTypeForCmdKey &&
+ String.fromCharCode(which).toLowerCase() == "u" &&
+ (evt.metaKey || evt.ctrlKey)) {
+ // cmd-U
+ doc.body.innerHTML = '';
+ evt.preventDefault();
+ specialHandled = true;
+ }*/
+
+ if (mozillaFakeArrows && mozillaFakeArrows.handleKeyEvent(evt)) {
+ evt.preventDefault();
+ specialHandled = true;
+ }
+ }
+
+ if (type == "keydown") {
+ idleWorkTimer.atLeast(500);
+ }
+ else if (type == "keypress") {
+ if ((! specialHandled) && parenModule.shouldNormalizeOnChar(charCode)) {
+ idleWorkTimer.atMost(0);
+ }
+ else {
+ idleWorkTimer.atLeast(500);
+ }
+ }
+ else if (type == "keyup") {
+ var wait = 200;
+ idleWorkTimer.atLeast(wait);
+ idleWorkTimer.atMost(wait);
+ }
+
+ // Is part of multi-keystroke international character on Firefox Mac
+ var isFirefoxHalfCharacter =
+ (browser.mozilla && evt.altKey && charCode == 0 && keyCode == 0);
+
+ // Is part of multi-keystroke international character on Safari Mac
+ var isSafariHalfCharacter =
+ (browser.safari && evt.altKey && keyCode == 229);
+
+ if (thisKeyDoesntTriggerNormalize || isFirefoxHalfCharacter || isSafariHalfCharacter) {
+ idleWorkTimer.atLeast(3000); // give user time to type
+ // if this is a keydown, e.g., the keyup shouldn't trigger a normalize
+ thisKeyDoesntTriggerNormalize = true;
+ }
+
+ if ((! specialHandled) && (! thisKeyDoesntTriggerNormalize) &&
+ (! inInternationalComposition)) {
+ if (type != "keyup" || ! incorpIfQuick()) {
+ observeChangesAroundSelection();
+ }
+ }
+
+ if (type == "keyup") {
+ thisKeyDoesntTriggerNormalize = false;
+ }
+ });
+ }
+
+ var thisKeyDoesntTriggerNormalize = false;
+
+ function doUndoRedo(which) {
+ // precond: normalized DOM
+ if (undoModule.enabled) {
+ var whichMethod;
+ if (which == "undo") whichMethod = 'performUndo';
+ if (which == "redo") whichMethod = 'performRedo';
+ if (whichMethod) {
+ var oldEventType = currentCallStack.editEvent.eventType;
+ currentCallStack.startNewEvent(which);
+ undoModule[whichMethod](function(backset, selectionInfo) {
+ if (backset) {
+ performDocumentApplyChangeset(backset);
+ }
+ if (selectionInfo) {
+ performSelectionChange(lineAndColumnFromChar(selectionInfo.selStart),
+ lineAndColumnFromChar(selectionInfo.selEnd),
+ selectionInfo.selFocusAtStart);
+ }
+ var oldEvent = currentCallStack.startNewEvent(oldEventType, true);
+ return oldEvent;
+ });
+ }
+ }
+ }
+
+ /*function enforceNewTextTypedStyle() {
+ var sel = getSelection();
+ var n = (sel && sel.startPoint && sel.startPoint.node);
+ if (!n) return;
+ var isInOurNode = false;
+ while (n) {
+ if (n.tagName) {
+ var tag = n.tagName.toLowerCase();
+ if (tag == "b" || tag == "strong") {
+ isInOurNode = true;
+ break;
+ }
+ if (((typeof n.className) == "string") &&
+ n.className.toLowerCase().indexOf("Apple-style-span") >= 0) {
+ isInOurNode = true;
+ break;
+ }
+ }
+ n = n.parentNode;
+ }
+
+ if (! isInOurNode) {
+ doc.execCommand("Bold", false, null);
+ }
+
+ if (! browser.msie) {
+ var browserSelection = window.getSelection();
+ if (browserSelection && browserSelection.type != "None" &&
+ browserSelection.rangeCount !== 0) {
+ var range = browserSelection.getRangeAt(0);
+ var surrounder = doc.createElement("B");
+ range.surroundContents(surrounder);
+ range.selectNodeContents(surrounder);
+ browserSelection.removeAllRanges();
+ browserSelection.addRange(range);
+ }
+ }
+ }*/
+
+ function updateBrowserSelectionFromRep() {
+ // requires normalized DOM!
+ var selStart = rep.selStart, selEnd = rep.selEnd;
+
+ if (!(selStart && selEnd)) {
+ setSelection(null);
+ return;
+ }
+
+ var mozillaCaretHack = (false && browser.mozilla && selStart && selEnd &&
+ selStart[0] == selEnd[0]
+ && selStart[1] == rep.lines.atIndex(selStart[0]).lineMarker
+ && selEnd[1] == rep.lines.atIndex(selEnd[0]).lineMarker &&
+ setupMozillaCaretHack(selStart[0]));
+
+ var selection = {};
+
+ var ss = [selStart[0], selStart[1]];
+ if (mozillaCaretHack) ss[1] += 1;
+ selection.startPoint = getPointForLineAndChar(ss);
+
+ var se = [selEnd[0], selEnd[1]];
+ if (mozillaCaretHack) se[1] += 1;
+ selection.endPoint = getPointForLineAndChar(se);
+
+ selection.focusAtStart = !!rep.selFocusAtStart;
+
+ setSelection(selection);
+
+ if (mozillaCaretHack) {
+ mozillaCaretHack.unhack();
+ }
+ }
+
+ function getRepHTML() {
+ /*function lineWithSelection(text, lineNum) {
+ var haveSelStart = (rep.selStart && rep.selStart[0] == lineNum);
+ var haveSelEnd = (rep.selEnd && rep.selEnd[0] == lineNum);
+ var startCol = (haveSelStart && rep.selStart[1]);
+ var endCol = (haveSelEnd && rep.selEnd[1]);
+ var len = text.length;
+ if (haveSelStart && haveSelEnd && startCol == endCol) {
+ var color = "#000";
+ if (endCol == len) {
+ return '<span style="border-right: 1px solid '+color+'">'+
+ htmlEscape(text)+'</span>';
+ }
+ else {
+ return htmlEscape
+ }
+ }
+ }*/
+
+ return map(rep.lines.slice(), function (entry) {
+ var text = entry.text;
+ var content;
+ if (text.length == 0) {
+ content = '<span style="color: #aaa">--</span>';
+ }
+ else {
+ content = htmlPrettyEscape(text);
+ }
+ return '<div><code>'+content+'</div></code>';
+ }).join('');
+ }
+
+ function nodeMaxIndex(nd) {
+ if (isNodeText(nd)) return nd.nodeValue.length;
+ else return 1;
+ }
+
+ function hasIESelection() {
+ var browserSelection;
+ try { browserSelection = doc.selection; } catch (e) {}
+ if (! browserSelection) return false;
+ var origSelectionRange;
+ try { origSelectionRange = browserSelection.createRange(); } catch (e) {}
+ if (! origSelectionRange) return false;
+ var selectionParent = origSelectionRange.parentElement();
+ if (selectionParent.ownerDocument != doc) return false;
+ return true;
+ }
+
+ function getSelection() {
+ // returns null, or a structure containing startPoint and endPoint,
+ // each of which has node (a magicdom node), index, and maxIndex. If the node
+ // is a text node, maxIndex is the length of the text; else maxIndex is 1.
+ // index is between 0 and maxIndex, inclusive.
+ if (browser.msie) {
+ var browserSelection;
+ try { browserSelection = doc.selection; } catch (e) {}
+ if (! browserSelection) return null;
+ var origSelectionRange;
+ try { origSelectionRange = browserSelection.createRange(); } catch (e) {}
+ if (! origSelectionRange) return null;
+ var selectionParent = origSelectionRange.parentElement();
+ if (selectionParent.ownerDocument != doc) return null;
+ function newRange() {
+ return doc.body.createTextRange();
+ }
+ function rangeForElementNode(nd) {
+ var rng = newRange();
+ // doesn't work on text nodes
+ rng.moveToElementText(nd);
+ return rng;
+ }
+ function pointFromCollapsedRange(rng) {
+ var parNode = rng.parentElement();
+ var elemBelow = -1;
+ var elemAbove = parNode.childNodes.length;
+ var rangeWithin = rangeForElementNode(parNode);
+
+ if (rng.compareEndPoints("StartToStart", rangeWithin) == 0) {
+ return {node:parNode, index:0, maxIndex:1};
+ }
+ else if (rng.compareEndPoints("EndToEnd", rangeWithin) == 0) {
+ if (isBlockElement(parNode) && parNode.nextSibling) {
+ // caret after block is not consistent across browsers
+ // (same line vs next) so put caret before next node
+ return {node:parNode.nextSibling, index:0, maxIndex:1};
+ }
+ return {node:parNode, index:1, maxIndex:1};
+ }
+ else if (parNode.childNodes.length == 0) {
+ return {node:parNode, index:0, maxIndex:1};
+ }
+
+ for(var i=0;i<parNode.childNodes.length;i++) {
+ var n = parNode.childNodes.item(i);
+ if (! isNodeText(n)) {
+ var nodeRange = rangeForElementNode(n);
+ var startComp = rng.compareEndPoints("StartToStart", nodeRange);
+ var endComp = rng.compareEndPoints("EndToEnd", nodeRange);
+ if (startComp >= 0 && endComp <= 0) {
+ var index = 0;
+ if (startComp > 0) {
+ index = 1;
+ }
+ return {node:n, index:index, maxIndex:1};
+ }
+ else if (endComp > 0) {
+ if (i > elemBelow) {
+ elemBelow = i;
+ rangeWithin.setEndPoint("StartToEnd", nodeRange);
+ }
+ }
+ else if (startComp < 0) {
+ if (i < elemAbove) {
+ elemAbove = i;
+ rangeWithin.setEndPoint("EndToStart", nodeRange);
+ }
+ }
+ }
+ }
+ if ((elemAbove - elemBelow) == 1) {
+ if (elemBelow >= 0) {
+ return {node:parNode.childNodes.item(elemBelow), index:1, maxIndex:1};
+ }
+ else {
+ return {node:parNode.childNodes.item(elemAbove), index:0, maxIndex:1};
+ }
+ }
+ var idx = 0;
+ var r = rng.duplicate();
+ // infinite stateful binary search! call function for values 0 to inf,
+ // expecting the answer to be about 40. return index of smallest
+ // true value.
+ var indexIntoRange = binarySearchInfinite(40, function (i) {
+ // the search algorithm whips the caret back and forth,
+ // though it has to be moved relatively and may hit
+ // the end of the buffer
+ var delta = i-idx;
+ var moved = Math.abs(r.move("character", -delta));
+ // next line is work-around for fact that when moving left, the beginning
+ // of a text node is considered to be after the start of the parent element:
+ if (r.move("character", -1)) r.move("character", 1);
+ if (delta < 0) idx -= moved;
+ else idx += moved;
+ return (r.compareEndPoints("StartToStart", rangeWithin) <= 0);
+ });
+ // iterate over consecutive text nodes, point is in one of them
+ var textNode = elemBelow+1;
+ var indexLeft = indexIntoRange;
+ while (textNode < elemAbove) {
+ var tn = parNode.childNodes.item(textNode);
+ if (indexLeft <= tn.nodeValue.length) {
+ return {node:tn, index:indexLeft, maxIndex:tn.nodeValue.length};
+ }
+ indexLeft -= tn.nodeValue.length;
+ textNode++;
+ }
+ var tn = parNode.childNodes.item(textNode-1);
+ return {node:tn, index:tn.nodeValue.length, maxIndex:tn.nodeValue.length};
+ }
+ var selection = {};
+ if (origSelectionRange.compareEndPoints("StartToEnd", origSelectionRange) == 0) {
+ // collapsed
+ var pnt = pointFromCollapsedRange(origSelectionRange);
+ selection.startPoint = pnt;
+ selection.endPoint = {node:pnt.node, index:pnt.index, maxIndex:pnt.maxIndex};
+ }
+ else {
+ var start = origSelectionRange.duplicate();
+ start.collapse(true);
+ var end = origSelectionRange.duplicate();
+ end.collapse(false);
+ selection.startPoint = pointFromCollapsedRange(start);
+ selection.endPoint = pointFromCollapsedRange(end);
+ /*if ((!selection.startPoint.node.isText) && (!selection.endPoint.node.isText)) {
+ console.log(selection.startPoint.node.uniqueId()+","+
+ selection.startPoint.index+" / "+
+ selection.endPoint.node.uniqueId()+","+
+ selection.endPoint.index);
+ }*/
+ }
+ return selection;
+ }
+ else {
+ // non-IE browser
+ var browserSelection = window.getSelection();
+ if (browserSelection && browserSelection.type != "None" &&
+ browserSelection.rangeCount !== 0) {
+ var range = browserSelection.getRangeAt(0);
+ function isInBody(n) {
+ while (n && ! (n.tagName && n.tagName.toLowerCase() == "body")) {
+ n = n.parentNode;
+ }
+ return !!n;
+ }
+ function pointFromRangeBound(container, offset) {
+ if (! isInBody(container)) {
+ // command-click in Firefox selects whole document, HEAD and BODY!
+ return {node:root, index:0, maxIndex:1};
+ }
+ var n = container;
+ var childCount = n.childNodes.length;
+ if (isNodeText(n)) {
+ return {node:n, index:offset, maxIndex:n.nodeValue.length};
+ }
+ else if (childCount == 0) {
+ return {node:n, index:0, maxIndex:1};
+ }
+ // treat point between two nodes as BEFORE the second (rather than after the first)
+ // if possible; this way point at end of a line block-element is treated as
+ // at beginning of next line
+ else if (offset == childCount) {
+ var nd = n.childNodes.item(childCount-1);
+ var max = nodeMaxIndex(nd);
+ return {node:nd, index:max, maxIndex:max};
+ }
+ else {
+ var nd = n.childNodes.item(offset);
+ var max = nodeMaxIndex(nd);
+ return {node:nd, index:0, maxIndex:max};
+ }
+ }
+ var selection = {};
+ selection.startPoint = pointFromRangeBound(range.startContainer, range.startOffset);
+ selection.endPoint = pointFromRangeBound(range.endContainer, range.endOffset);
+ selection.focusAtStart = (((range.startContainer != range.endContainer) ||
+ (range.startOffset != range.endOffset)) &&
+ browserSelection.anchorNode &&
+ (browserSelection.anchorNode == range.endContainer) &&
+ (browserSelection.anchorOffset == range.endOffset));
+ return selection;
+ }
+ else return null;
+ }
+ }
+
+ function setSelection(selection) {
+ function copyPoint(pt) {
+ return {node:pt.node, index:pt.index, maxIndex:pt.maxIndex};
+ }
+ if (browser.msie) {
+ // Oddly enough, accessing scrollHeight fixes return key handling on IE 8,
+ // presumably by forcing some kind of internal DOM update.
+ doc.body.scrollHeight;
+
+ function moveToElementText(s, n) {
+ while (n.firstChild && ! isNodeText(n.firstChild)) {
+ n = n.firstChild;
+ }
+ s.moveToElementText(n);
+ }
+ function newRange() {
+ return doc.body.createTextRange();
+ }
+ function setCollapsedBefore(s, n) {
+ // s is an IE TextRange, n is a dom node
+ if (isNodeText(n)) {
+ // previous node should not also be text, but prevent inf recurs
+ if (n.previousSibling && ! isNodeText(n.previousSibling)) {
+ setCollapsedAfter(s, n.previousSibling);
+ }
+ else {
+ setCollapsedBefore(s, n.parentNode);
+ }
+ }
+ else {
+ moveToElementText(s, n);
+ // work around for issue that caret at beginning of line
+ // somehow ends up at end of previous line
+ if (s.move('character', 1)) {
+ s.move('character', -1);
+ }
+ s.collapse(true); // to start
+ }
+ }
+ function setCollapsedAfter(s, n) {
+ // s is an IE TextRange, n is a magicdom node
+ if (isNodeText(n)) {
+ // can't use end of container when no nextSibling (could be on next line),
+ // so use previousSibling or start of container and move forward.
+ setCollapsedBefore(s, n);
+ s.move("character", n.nodeValue.length);
+ }
+ else {
+ moveToElementText(s, n);
+ s.collapse(false); // to end
+ }
+ }
+ function getPointRange(point) {
+ var s = newRange();
+ var n = point.node;
+ if (isNodeText(n)) {
+ setCollapsedBefore(s, n);
+ s.move("character", point.index);
+ }
+ else if (point.index == 0) {
+ setCollapsedBefore(s, n);
+ }
+ else {
+ setCollapsedAfter(s, n);
+ }
+ return s;
+ }
+
+ if (selection) {
+ if (! hasIESelection()) {
+ return; // don't steal focus
+ }
+
+ var startPoint = copyPoint(selection.startPoint);
+ var endPoint = copyPoint(selection.endPoint);
+
+ // fix issue where selection can't be extended past end of line
+ // with shift-rightarrow or shift-downarrow
+ if (endPoint.index == endPoint.maxIndex && endPoint.node.nextSibling) {
+ endPoint.node = endPoint.node.nextSibling;
+ endPoint.index = 0;
+ endPoint.maxIndex = nodeMaxIndex(endPoint.node);
+ }
+ var range = getPointRange(startPoint);
+ range.setEndPoint("EndToEnd", getPointRange(endPoint));
+
+ // setting the selection in IE causes everything to scroll
+ // so that the selection is visible. if setting the selection
+ // definitely accomplishes nothing, don't do it.
+ function isEqualToDocumentSelection(rng) {
+ var browserSelection;
+ try { browserSelection = doc.selection; } catch (e) {}
+ if (! browserSelection) return false;
+ var rng2 = browserSelection.createRange();
+ if (rng2.parentElement().ownerDocument != doc) return false;
+ if (rng.compareEndPoints("StartToStart", rng2) !== 0) return false;
+ if (rng.compareEndPoints("EndToEnd", rng2) !== 0) return false;
+ return true;
+ }
+ if (! isEqualToDocumentSelection(range)) {
+ //dmesg(toSource(selection));
+ //dmesg(escapeHTML(doc.body.innerHTML));
+ range.select();
+ }
+ }
+ else {
+ try { doc.selection.empty(); } catch (e) {}
+ }
+ }
+ else {
+ // non-IE browser
+ var isCollapsed;
+ function pointToRangeBound(pt) {
+ var p = copyPoint(pt);
+ // Make sure Firefox cursor is deep enough; fixes cursor jumping when at top level,
+ // and also problem where cut/copy of a whole line selected with fake arrow-keys
+ // copies the next line too.
+ if (isCollapsed) {
+ function diveDeep() {
+ while (p.node.childNodes.length > 0) {
+ //&& (p.node == root || p.node.parentNode == root)) {
+ if (p.index == 0) {
+ p.node = p.node.firstChild;
+ p.maxIndex = nodeMaxIndex(p.node);
+ }
+ else if (p.index == p.maxIndex) {
+ p.node = p.node.lastChild;
+ p.maxIndex = nodeMaxIndex(p.node);
+ p.index = p.maxIndex;
+ }
+ else break;
+ }
+ }
+ // now fix problem where cursor at end of text node at end of span-like element
+ // with background doesn't seem to show up...
+ if (isNodeText(p.node) && p.index == p.maxIndex) {
+ var n = p.node;
+ while ((! n.nextSibling) && (n != root) && (n.parentNode != root)) {
+ n = n.parentNode;
+ }
+ if (n.nextSibling &&
+ (! ((typeof n.nextSibling.tagName) == "string" &&
+ n.nextSibling.tagName.toLowerCase() == "br")) &&
+ (n != p.node) && (n != root) && (n.parentNode != root)) {
+ // found a parent, go to next node and dive in
+ p.node = n.nextSibling;
+ p.maxIndex = nodeMaxIndex(p.node);
+ p.index = 0;
+ diveDeep();
+ }
+ }
+ // try to make sure insertion point is styled;
+ // also fixes other FF problems
+ if (! isNodeText(p.node)) {
+ diveDeep();
+ }
+ }
+ /*// make sure Firefox cursor is shallow enough;
+ // to fix problem where "return" between two spans doesn't move the caret to
+ // the next line
+ // (decided against)
+ while (!(p.node.isRoot || p.node.parent().isRoot || p.node.parent().parent().isRoot)) {
+ if (p.index == 0 && ! p.node.prev()) {
+ p.node = p.node.parent();
+ p.maxIndex = 1;
+ }
+ else if (p.index == p.maxIndex && ! p.node.next()) {
+ p.node = p.node.parent();
+ p.maxIndex = 1;
+ p.index = 1;
+ }
+ else break;
+ }
+ if ((! p.node.isRoot) && (!p.node.parent().isRoot) &&
+ (p.index == p.maxIndex) && p.node.next()) {
+ p.node = p.node.next();
+ p.maxIndex = nodeMaxIndex(p.node);
+ p.index = 0;
+ }*/
+ if (isNodeText(p.node)) {
+ return { container: p.node, offset: p.index };
+ }
+ else {
+ // p.index in {0,1}
+ return { container: p.node.parentNode, offset: childIndex(p.node) + p.index };
+ }
+ }
+ var browserSelection = window.getSelection();
+ if (browserSelection) {
+ browserSelection.removeAllRanges();
+ if (selection) {
+ isCollapsed = (selection.startPoint.node === selection.endPoint.node &&
+ selection.startPoint.index === selection.endPoint.index);
+ var start = pointToRangeBound(selection.startPoint);
+ var end = pointToRangeBound(selection.endPoint);
+
+ if ((!isCollapsed) && selection.focusAtStart && browserSelection.collapse && browserSelection.extend) {
+ // can handle "backwards"-oriented selection, shift-arrow-keys move start
+ // of selection
+ browserSelection.collapse(end.container, end.offset);
+ //console.trace();
+ //console.log(htmlPrettyEscape(rep.alltext));
+ //console.log("%o %o", rep.selStart, rep.selEnd);
+ //console.log("%o %d", start.container, start.offset);
+ browserSelection.extend(start.container, start.offset);
+ }
+ else {
+ var range = doc.createRange();
+ range.setStart(start.container, start.offset);
+ range.setEnd(end.container, end.offset);
+ browserSelection.removeAllRanges();
+ browserSelection.addRange(range);
+ }
+ }
+ }
+ }
+ }
+
+ function childIndex(n) {
+ var idx = 0;
+ while (n.previousSibling) {
+ idx++;
+ n = n.previousSibling;
+ }
+ return idx;
+ }
+
+ function fixView() {
+ // calling this method repeatedly should be fast
+
+ if (getInnerWidth() == 0 || getInnerHeight() == 0) {
+ return;
+ }
+
+ function setIfNecessary(obj, prop, value) {
+ if (obj[prop] != value) {
+ obj[prop] = value;
+ }
+ }
+
+ var lineNumberWidth = sideDiv.firstChild.offsetWidth;
+ var newSideDivWidth = lineNumberWidth + LINE_NUMBER_PADDING_LEFT;
+ if (newSideDivWidth < MIN_LINEDIV_WIDTH) newSideDivWidth = MIN_LINEDIV_WIDTH;
+ iframePadLeft = EDIT_BODY_PADDING_LEFT;
+ if (hasLineNumbers) iframePadLeft += newSideDivWidth + LINE_NUMBER_PADDING_RIGHT;
+ setIfNecessary(iframe.style, "left", iframePadLeft+"px");
+ setIfNecessary(sideDiv.style, "width", newSideDivWidth+"px");
+
+ for(var i=0;i<2;i++) {
+ var newHeight = root.clientHeight;
+ var newWidth = (browser.msie ? root.createTextRange().boundingWidth : root.clientWidth);
+ var viewHeight = getInnerHeight() - iframePadBottom - iframePadTop;
+ var viewWidth = getInnerWidth() - iframePadLeft - iframePadRight;
+ if (newHeight < viewHeight) {
+ newHeight = viewHeight;
+ if (browser.msie) setIfNecessary(outerWin.document.documentElement.style, 'overflowY', 'auto');
+ }
+ else {
+ if (browser.msie) setIfNecessary(outerWin.document.documentElement.style, 'overflowY', 'scroll');
+ }
+ if (doesWrap) {
+ newWidth = viewWidth;
+ }
+ else {
+ if (newWidth < viewWidth) newWidth = viewWidth;
+ }
+ if (newHeight > 32000) newHeight = 32000;
+ if (newWidth > 32000) newWidth = 32000;
+ setIfNecessary(iframe.style, "height", newHeight+"px");
+ setIfNecessary(iframe.style, "width", newWidth+"px");
+ setIfNecessary(sideDiv.style, "height", newHeight+"px");
+ }
+ if (browser.mozilla) {
+ if (! doesWrap) {
+ // the body:display:table-cell hack makes mozilla do scrolling
+ // correctly by shrinking the <body> to fit around its content,
+ // but mozilla won't act on clicks below the body. We keep the
+ // style.height property set to the viewport height (editor height
+ // not including scrollbar), so it will never shrink so that part of
+ // the editor isn't clickable.
+ var body = root;
+ var styleHeight = viewHeight+"px";
+ setIfNecessary(body.style, "height", styleHeight);
+ }
+ else {
+ setIfNecessary(root.style, "height", "");
+ }
+ }
+ // if near edge, scroll to edge
+ var scrollX = getScrollX();
+ var scrollY = getScrollY();
+ var win = outerWin;
+ var r = 20;
+ /*if (scrollX <= iframePadLeft+r) win.scrollBy(-iframePadLeft-r, 0);
+ else if (getPageWidth() - scrollX - getInnerWidth() <= iframePadRight+r)
+ scrollBy(iframePadRight+r, 0);*/
+ /*if (scrollY <= iframePadTop+r) win.scrollBy(0, -iframePadTop-r);
+ else if (getPageHeight() - scrollY - getInnerHeight() <= iframePadBottom+r)
+ scrollBy(0, iframePadBottom+r);*/
+
+ enforceEditability();
+
+ addClass(sideDiv, 'sidedivdelayed');
+ }
+
+ function getScrollXY() {
+ var win = outerWin;
+ var odoc = outerWin.document;
+ if (typeof(win.pageYOffset) == "number") {
+ return {x: win.pageXOffset, y: win.pageYOffset};
+ }
+ var docel = odoc.documentElement;
+ if (docel && typeof(docel.scrollTop) == "number") {
+ return {x:docel.scrollLeft, y:docel.scrollTop};
+ }
+ }
+
+ function getScrollX() {
+ return getScrollXY().x;
+ }
+
+ function getScrollY() {
+ return getScrollXY().y;
+ }
+
+ function setScrollX(x) {
+ outerWin.scrollTo(x, getScrollY());
+ }
+
+ function setScrollY(y) {
+ outerWin.scrollTo(getScrollX(), y);
+ }
+
+ function setScrollXY(x, y) {
+ outerWin.scrollTo(x, y);
+ }
+
+ var _teardownActions = [];
+ function teardown() {
+ forEach(_teardownActions, function (a) { a(); });
+ }
+
+ bindEventHandler(window, "load", setup);
+
+ function setDesignMode(newVal) {
+ try {
+ function setIfNecessary(target, prop, val) {
+ if (String(target[prop]).toLowerCase() != val) {
+ target[prop] = val;
+ return true;
+ }
+ return false;
+ }
+ if (browser.msie || browser.safari) {
+ setIfNecessary(root, 'contentEditable', (newVal ? 'true' : 'false'));
+ }
+ else {
+ var wasSet = setIfNecessary(doc, 'designMode', (newVal ? 'on' : 'off'));
+ if (wasSet && newVal && browser.opera) {
+ // turning on designMode clears event handlers
+ bindTheEventHandlers();
+ }
+ }
+ return true;
+ }
+ catch (e) {
+ return false;
+ }
+ }
+
+ var iePastedLines = null;
+ function handleIEPaste(evt) {
+ // Pasting in IE loses blank lines in a way that loses information;
+ // "one\n\ntwo\nthree" becomes "<p>one</p><p>two</p><p>three</p>",
+ // which becomes "one\ntwo\nthree". We can get the correct text
+ // from the clipboard directly, but we still have to let the paste
+ // happen to get the style information.
+
+ var clipText = window.clipboardData && window.clipboardData.getData("Text");
+ if (clipText && doc.selection) {
+ // this "paste" event seems to mess with the selection whether we try to
+ // stop it or not, so can't really do document-level manipulation now
+ // or in an idle call-stack. instead, use IE native manipulation
+ //function escapeLine(txt) {
+ //return processSpaces(escapeHTML(textify(txt)));
+ //}
+ //var newHTML = map(clipText.replace(/\r/g,'').split('\n'), escapeLine).join('<br>');
+ //doc.selection.createRange().pasteHTML(newHTML);
+ //evt.preventDefault();
+
+ //iePastedLines = map(clipText.replace(/\r/g,'').split('\n'), textify);
+ }
+ }
+
+ var inInternationalComposition = false;
+
+ function handleCompositionEvent(evt) {
+ // international input events, fired in FF3, at least; allow e.g. Japanese input
+ if (evt.type == "compositionstart") {
+ inInternationalComposition = true;
+ }
+ else if (evt.type == "compositionend") {
+ inInternationalComposition = false;
+ }
+ }
+
+ /*function handleTextEvent(evt) {
+ top.console.log("TEXT EVENT");
+ inCallStackIfNecessary("handleTextEvent", function() {
+ observeChangesAroundSelection();
+ });
+ }*/
+
+ function bindTheEventHandlers() {
+ bindEventHandler(window, "unload", teardown);
+ bindEventHandler(document, "keydown", handleKeyEvent);
+ bindEventHandler(document, "keypress", handleKeyEvent);
+ bindEventHandler(document, "keyup", handleKeyEvent);
+ bindEventHandler(document, "click", handleClick);
+ bindEventHandler(root, "blur", handleBlur);
+ if (browser.msie) {
+ bindEventHandler(document, "click", handleIEOuterClick);
+ }
+ if (browser.msie) bindEventHandler(root, "paste", handleIEPaste);
+ if ((! browser.msie) && document.documentElement) {
+ bindEventHandler(document.documentElement, "compositionstart", handleCompositionEvent);
+ bindEventHandler(document.documentElement, "compositionend", handleCompositionEvent);
+ }
+
+ /*bindEventHandler(window, "mousemove", function(e) {
+ if (e.pageX < 10) {
+ window.DEBUG_DONT_INCORP = (e.pageX < 2);
+ }
+ });*/
+ }
+
+ function handleIEOuterClick(evt) {
+ if ((evt.target.tagName||'').toLowerCase() != "html") {
+ return;
+ }
+ if (!(evt.pageY > root.clientHeight)) {
+ return;
+ }
+
+ // click below the body
+ inCallStack("handleOuterClick", function() {
+ // put caret at bottom of doc
+ fastIncorp(11);
+ if (isCaret()) { // don't interfere with drag
+ var lastLine = rep.lines.length()-1;
+ var lastCol = rep.lines.atIndex(lastLine).text.length;
+ performSelectionChange([lastLine,lastCol],[lastLine,lastCol]);
+ }
+ });
+ }
+
+ function getClassArray(elem, optFilter) {
+ var bodyClasses = [];
+ (elem.className || '').replace(/\S+/g, function (c) {
+ if ((! optFilter) || (optFilter(c))) {
+ bodyClasses.push(c);
+ }
+ });
+ return bodyClasses;
+ }
+ function setClassArray(elem, array) {
+ elem.className = array.join(' ');
+ }
+ function addClass(elem, className) {
+ var seen = false;
+ var cc = getClassArray(elem, function(c) { if (c == className) seen = true; return true; });
+ if (! seen) {
+ cc.push(className);
+ setClassArray(elem, cc);
+ }
+ }
+ function removeClass(elem, className) {
+ var seen = false;
+ var cc = getClassArray(elem, function(c) {
+ if (c == className) { seen = true; return false; } return true; });
+ if (seen) {
+ setClassArray(elem, cc);
+ }
+ }
+ function setClassPresence(elem, className, present) {
+ if (present) addClass(elem, className);
+ else removeClass(elem, className);
+ }
+
+ function setup() {
+ doc = document; // defined as a var in scope outside
+ inCallStack("setup", function() {
+ var body = doc.getElementById("innerdocbody");
+ root = body; // defined as a var in scope outside
+
+ if (browser.mozilla) addClass(root, "mozilla");
+ if (browser.safari) addClass(root, "safari");
+ if (browser.msie) addClass(root, "msie");
+ if (browser.msie) {
+ // cache CSS background images
+ try {
+ doc.execCommand("BackgroundImageCache", false, true);
+ }
+ catch (e) {
+ /* throws an error in some IE 6 but not others! */
+ }
+ }
+ setClassPresence(root, "authorColors", true);
+ setClassPresence(root, "doesWrap", doesWrap);
+
+ initDynamicCSS();
+
+ enforceEditability();
+
+ // set up dom and rep
+ while (root.firstChild) root.removeChild(root.firstChild);
+ var oneEntry = createDomLineEntry("");
+ doRepLineSplice(0, rep.lines.length(), [oneEntry]);
+ insertDomLines(null, [oneEntry.domInfo], null);
+ rep.alines = Changeset.splitAttributionLines(
+ Changeset.makeAttribution("\n"), "\n");
+
+ bindTheEventHandlers();
+
+ });
+
+ scheduler.setTimeout(function() {
+ parent.readyFunc(); // defined in code that sets up the inner iframe
+ }, 0);
+
+ isSetUp = true;
+ }
+
+ function focus() {
+ window.focus();
+ }
+
+ function handleBlur(evt) {
+ if (browser.msie) {
+ // a fix: in IE, clicking on a control like a button outside the
+ // iframe can "blur" the editor, causing it to stop getting
+ // events, though typing still affects it(!).
+ setSelection(null);
+ }
+ }
+
+ function bindEventHandler(target, type, func) {
+ var handler;
+ if ((typeof func._wrapper) != "function") {
+ func._wrapper = function(event) {
+ func(fixEvent(event || window.event || {}));
+ }
+ }
+ var handler = func._wrapper;
+ if (target.addEventListener)
+ target.addEventListener(type, handler, false);
+ else
+ target.attachEvent("on" + type, handler);
+ _teardownActions.push(function() {
+ unbindEventHandler(target, type, func);
+ });
+ }
+
+ function unbindEventHandler(target, type, func) {
+ var handler = func._wrapper;
+ if (target.removeEventListener)
+ target.removeEventListener(type, handler, false);
+ else
+ target.detachEvent("on" + type, handler);
+ }
+
+ /*forEach(['rep', 'getCleanNodeByKey', 'getDirtyRanges', 'isNodeDirty',
+ 'getSelection', 'setSelection', 'updateBrowserSelectionFromRep',
+ 'makeRecentSet', 'resetProfiler', 'getScrollXY', 'makeIdleAction'], function (k) {
+ top['_'+k] = eval(k);
+ });*/
+
+ function getSelectionPointX(point) {
+ // doesn't work in wrap-mode
+ var node = point.node;
+ var index = point.index;
+ function leftOf(n) { return n.offsetLeft; }
+ function rightOf(n) { return n.offsetLeft + n.offsetWidth; }
+ if (! isNodeText(node)) {
+ if (index == 0) return leftOf(node);
+ else return rightOf(node);
+ }
+ else {
+ // we can get bounds of element nodes, so look for those.
+ // allow consecutive text nodes for robustness.
+ var charsToLeft = index;
+ var charsToRight = node.nodeValue.length - index;
+ var n;
+ for(n = node.previousSibling; n && isNodeText(n); n = n.previousSibling)
+ charsToLeft += n.nodeValue;
+ var leftEdge = (n ? rightOf(n) : leftOf(node.parentNode));
+ for(n = node.nextSibling; n && isNodeText(n); n = n.nextSibling)
+ charsToRight += n.nodeValue;
+ var rightEdge = (n ? leftOf(n) : rightOf(node.parentNode));
+ var frac = (charsToLeft / (charsToLeft + charsToRight));
+ var pixLoc = leftEdge + frac*(rightEdge - leftEdge);
+ return Math.round(pixLoc);
+ }
+ }
+
+ function getPageHeight() {
+ var win = outerWin;
+ var odoc = win.document;
+ if (win.innerHeight && win.scrollMaxY) return win.innerHeight + win.scrollMaxY;
+ else if (odoc.body.scrollHeight > odoc.body.offsetHeight) return odoc.body.scrollHeight;
+ else return odoc.body.offsetHeight;
+ }
+
+ function getPageWidth() {
+ var win = outerWin;
+ var odoc = win.document;
+ if (win.innerWidth && win.scrollMaxX) return win.innerWidth + win.scrollMaxX;
+ else if (odoc.body.scrollWidth > odoc.body.offsetWidth) return odoc.body.scrollWidth;
+ else return odoc.body.offsetWidth;
+ }
+
+ function getInnerHeight() {
+ var win = outerWin;
+ var odoc = win.document;
+ var h;
+ if (browser.opera) h = win.innerHeight;
+ else h = odoc.documentElement.clientHeight;
+ if (h) return h;
+
+ // deal with case where iframe is hidden, hope that
+ // style.height of iframe container is set in px
+ return Number(editorInfo.frame.parentNode.style.height.replace(/[^0-9]/g,'')
+ || 0);
+ }
+
+ function getInnerWidth() {
+ var win = outerWin;
+ var odoc = win.document;
+ return odoc.documentElement.clientWidth;
+ }
+
+ function scrollNodeVerticallyIntoView(node) {
+ // requires element (non-text) node;
+ // if node extends above top of viewport or below bottom of viewport (or top of scrollbar),
+ // scroll it the minimum distance needed to be completely in view.
+ var win = outerWin;
+ var odoc = outerWin.document;
+ var distBelowTop = node.offsetTop + iframePadTop - win.scrollY;
+ var distAboveBottom = win.scrollY + getInnerHeight() -
+ (node.offsetTop +iframePadTop + node.offsetHeight);
+
+ if (distBelowTop < 0) {
+ win.scrollBy(0, distBelowTop);
+ }
+ else if (distAboveBottom < 0) {
+ win.scrollBy(0, -distAboveBottom);
+ }
+ }
+
+ function scrollXHorizontallyIntoView(pixelX) {
+ var win = outerWin;
+ var odoc = outerWin.document;
+ pixelX += iframePadLeft;
+ var distInsideLeft = pixelX - win.scrollX;
+ var distInsideRight = win.scrollX + getInnerWidth() - pixelX;
+ if (distInsideLeft < 0) {
+ win.scrollBy(distInsideLeft, 0);
+ }
+ else if (distInsideRight < 0) {
+ win.scrollBy(-distInsideRight+1, 0);
+ }
+ }
+
+ function scrollSelectionIntoView() {
+ if (! rep.selStart) return;
+ fixView();
+ var focusLine = (rep.selFocusAtStart ? rep.selStart[0] : rep.selEnd[0]);
+ scrollNodeVerticallyIntoView(rep.lines.atIndex(focusLine).lineNode);
+ if (! doesWrap) {
+ var browserSelection = getSelection();
+ if (browserSelection) {
+ var focusPoint = (browserSelection.focusAtStart ? browserSelection.startPoint :
+ browserSelection.endPoint);
+ var selectionPointX = getSelectionPointX(focusPoint);
+ scrollXHorizontallyIntoView(selectionPointX);
+ fixView();
+ }
+ }
+ }
+
+ function getLineListType(lineNum) {
+ // get "list" attribute of first char of line
+ var aline = rep.alines[lineNum];
+ if (aline) {
+ var opIter = Changeset.opIterator(aline);
+ if (opIter.hasNext()) {
+ return Changeset.opAttributeValue(opIter.next(), 'list', rep.apool) || '';
+ }
+ }
+ return '';
+ }
+
+ function setLineListType(lineNum, listType) {
+ setLineListTypes([[lineNum, listType]]);
+ }
+
+ function setLineListTypes(lineNumTypePairsInOrder) {
+ var loc = [0,0];
+ var builder = Changeset.builder(rep.lines.totalWidth());
+ for(var i=0;i<lineNumTypePairsInOrder.length;i++) {
+ var pair = lineNumTypePairsInOrder[i];
+ var lineNum = pair[0];
+ var listType = pair[1];
+ buildKeepRange(builder, loc, (loc = [lineNum,0]));
+ if (getLineListType(lineNum)) {
+ // already a line marker
+ if (listType) {
+ // make different list type
+ buildKeepRange(builder, loc, (loc = [lineNum,1]),
+ [['list',listType]], rep.apool);
+ }
+ else {
+ // remove list marker
+ buildRemoveRange(builder, loc, (loc = [lineNum,1]));
+ }
+ }
+ else {
+ // currently no line marker
+ if (listType) {
+ // add a line marker
+ builder.insert('*', [['author', thisAuthor],
+ ['insertorder', 'first'],
+ ['list', listType]], rep.apool);
+ }
+ }
+ }
+
+ var cs = builder.toString();
+ if (! Changeset.isIdentity(cs)) {
+ performDocumentApplyChangeset(cs);
+ }
+ }
+
+ function doInsertUnorderedList() {
+ if (! (rep.selStart && rep.selEnd)) {
+ return;
+ }
+
+ var firstLine, lastLine;
+ firstLine = rep.selStart[0];
+ lastLine = Math.max(firstLine,
+ rep.selEnd[0] - ((rep.selEnd[1] == 0) ? 1 : 0));
+
+ var allLinesAreList = true;
+ for(var n=firstLine;n<=lastLine;n++) {
+ if (! getLineListType(n)) {
+ allLinesAreList = false;
+ break;
+ }
+ }
+
+ var mods = [];
+ for(var n=firstLine;n<=lastLine;n++) {
+ var t = getLineListType(n);
+ mods.push([n, allLinesAreList ? '' : (t ? t : 'bullet1')]);
+ }
+ setLineListTypes(mods);
+ }
+
+ var mozillaFakeArrows = (browser.mozilla && (function() {
+ // In Firefox 2, arrow keys are unstable while DOM-manipulating
+ // operations are going on. Specifically, if an operation
+ // (computation that ties up the event queue) is going on (in the
+ // call-stack of some event, like a timeout) that at some point
+ // mutates nodes involved in the selection, then the arrow
+ // keypress may (randomly) move the caret to the beginning or end
+ // of the document. If the operation also mutates the selection
+ // range, the old selection or the new selection may be used, or
+ // neither.
+
+ // As long as the arrow is pressed during the busy operation, it
+ // doesn't seem to matter that the keydown and keypress events
+ // aren't generated until afterwards, or that the arrow movement
+ // can still be stopped (meaning it hasn't been performed yet);
+ // Firefox must be preserving some old information about the
+ // selection or the DOM from when the key was initially pressed.
+ // However, it also doesn't seem to matter when the key was
+ // actually pressed relative to the time of the mutation within
+ // the prolonged operation. Also, even in very controlled tests
+ // (like a mutation followed by a long period of busyWaiting), the
+ // problem shows up often but not every time, with no discernable
+ // pattern. Who knows, it could have something to do with the
+ // caret-blinking timer, or DOM changes not being applied
+ // immediately.
+
+ // This problem, mercifully, does not show up at all in IE or
+ // Safari. My solution is to have my own, full-featured arrow-key
+ // implementation for Firefox.
+
+ // Note that the problem addressed here is potentially very subtle,
+ // especially if the operation is quick and is timed to usually happen
+ // when the user is idle.
+
+ // features:
+ // - 'up' and 'down' arrows preserve column when passing through shorter lines
+ // - shift-arrows extend the "focus" point, which may be start or end of range
+ // - the focus point is kept horizontally and vertically scrolled into view
+ // - arrows without shift cause caret to move to beginning or end of selection (left,right)
+ // or move focus point up or down a line (up,down)
+ // - command-(left,right,up,down) on Mac acts like (line-start, line-end, doc-start, doc-end)
+ // - takes wrapping into account when doesWrap is true, i.e. up-arrow and down-arrow move
+ // between the virtual lines within a wrapped line; this was difficult, and unfortunately
+ // requires mutating the DOM to get the necessary information
+
+ var savedFocusColumn = 0; // a value of 0 has no effect
+ var updatingSelectionNow = false;
+
+ function getVirtualLineView(lineNum) {
+ var lineNode = rep.lines.atIndex(lineNum).lineNode;
+ while (lineNode.firstChild && isBlockElement(lineNode.firstChild)) {
+ lineNode = lineNode.firstChild;
+ }
+ return makeVirtualLineView(lineNode);
+ }
+
+ function markerlessLineAndChar(line, chr) {
+ return [line, chr - rep.lines.atIndex(line).lineMarker];
+ }
+ function markerfulLineAndChar(line, chr) {
+ return [line, chr + rep.lines.atIndex(line).lineMarker];
+ }
+
+ return {
+ notifySelectionChanged: function() {
+ if (! updatingSelectionNow) {
+ savedFocusColumn = 0;
+ }
+ },
+ handleKeyEvent: function(evt) {
+ // returns "true" if handled
+ if (evt.type != "keypress") return false;
+ var keyCode = evt.keyCode;
+ if (keyCode < 37 || keyCode > 40) return false;
+ incorporateUserChanges();
+
+ if (!(rep.selStart && rep.selEnd)) return true;
+
+ // {byWord,toEnd,normal}
+ var moveMode = (evt.altKey ? "byWord" :
+ (evt.ctrlKey ? "byWord" :
+ (evt.metaKey ? "toEnd" :
+ "normal")));
+
+ var anchorCaret =
+ markerlessLineAndChar(rep.selStart[0], rep.selStart[1]);
+ var focusCaret =
+ markerlessLineAndChar(rep.selEnd[0], rep.selEnd[1]);
+ var wasCaret = isCaret();
+ if (rep.selFocusAtStart) {
+ var tmp = anchorCaret; anchorCaret = focusCaret; focusCaret = tmp;
+ }
+ var K_UP = 38, K_DOWN = 40, K_LEFT = 37, K_RIGHT = 39;
+ var dontMove = false;
+ if (wasCaret && ! evt.shiftKey) {
+ // collapse, will mutate both together
+ anchorCaret = focusCaret;
+ }
+ else if ((! wasCaret) && (! evt.shiftKey)) {
+ if (keyCode == K_LEFT) {
+ // place caret at beginning
+ if (rep.selFocusAtStart) anchorCaret = focusCaret;
+ else focusCaret = anchorCaret;
+ if (moveMode == "normal") dontMove = true;
+ }
+ else if (keyCode == K_RIGHT) {
+ // place caret at end
+ if (rep.selFocusAtStart) focusCaret = anchorCaret;
+ else anchorCaret = focusCaret;
+ if (moveMode == "normal") dontMove = true;
+ }
+ else {
+ // collapse, will mutate both together
+ anchorCaret = focusCaret;
+ }
+ }
+ if (! dontMove) {
+ function lineLength(i) {
+ var entry = rep.lines.atIndex(i);
+ return entry.text.length - entry.lineMarker;
+ }
+ function lineText(i) {
+ var entry = rep.lines.atIndex(i);
+ return entry.text.substring(entry.lineMarker);
+ }
+
+ if (keyCode == K_UP || keyCode == K_DOWN) {
+ var up = (keyCode == K_UP);
+ var canChangeLines = ((up && focusCaret[0]) ||
+ ((!up) && focusCaret[0] < rep.lines.length()-1));
+ var virtualLineView, virtualLineSpot, canChangeVirtualLines = false;
+ if (doesWrap) {
+ virtualLineView = getVirtualLineView(focusCaret[0]);
+ virtualLineSpot = virtualLineView.getVLineAndOffsetForChar(focusCaret[1]);
+ canChangeVirtualLines = ((up && virtualLineSpot.vline > 0) ||
+ ((!up) && virtualLineSpot.vline < (
+ virtualLineView.getNumVirtualLines() - 1)));
+ }
+ var newColByVirtualLineChange;
+ if (moveMode == "toEnd") {
+ if (up) {
+ focusCaret[0] = 0;
+ focusCaret[1] = 0;
+ }
+ else {
+ focusCaret[0] = rep.lines.length()-1;
+ focusCaret[1] = lineLength(focusCaret[0]);
+ }
+ }
+ else if (moveMode == "byWord") {
+ // move by "paragraph", a feature that Firefox lacks but IE and Safari both have
+ if (up) {
+ if (focusCaret[1] == 0 && canChangeLines) {
+ focusCaret[0]--;
+ focusCaret[1] = 0;
+ }
+ else focusCaret[1] = 0;
+ }
+ else {
+ var lineLen = lineLength(focusCaret[0]);
+ if (browser.windows) {
+ if (canChangeLines) {
+ focusCaret[0]++;
+ focusCaret[1] = 0;
+ }
+ else {
+ focusCaret[1] = lineLen;
+ }
+ }
+ else {
+ if (focusCaret[1] == lineLen && canChangeLines) {
+ focusCaret[0]++;
+ focusCaret[1] = lineLength(focusCaret[0]);
+ }
+ else {
+ focusCaret[1] = lineLen;
+ }
+ }
+ }
+ savedFocusColumn = 0;
+ }
+ else if (canChangeVirtualLines) {
+ var vline = virtualLineSpot.vline;
+ var offset = virtualLineSpot.offset;
+ if (up) vline--;
+ else vline++;
+ if (savedFocusColumn > offset) offset = savedFocusColumn;
+ else {
+ savedFocusColumn = offset;
+ }
+ var newSpot = virtualLineView.getCharForVLineAndOffset(vline, offset);
+ focusCaret[1] = newSpot.lineChar;
+ }
+ else if (canChangeLines) {
+ if (up) focusCaret[0]--;
+ else focusCaret[0]++;
+ var offset = focusCaret[1];
+ if (doesWrap) {
+ offset = virtualLineSpot.offset;
+ }
+ if (savedFocusColumn > offset) offset = savedFocusColumn;
+ else {
+ savedFocusColumn = offset;
+ }
+ if (doesWrap) {
+ var newLineView = getVirtualLineView(focusCaret[0]);
+ var vline = (up ? newLineView.getNumVirtualLines()-1 : 0);
+ var newSpot = newLineView.getCharForVLineAndOffset(vline, offset);
+ focusCaret[1] = newSpot.lineChar;
+ }
+ else {
+ var lineLen = lineLength(focusCaret[0]);
+ if (offset > lineLen) offset = lineLen;
+ focusCaret[1] = offset;
+ }
+ }
+ else {
+ if (up) focusCaret[1] = 0;
+ else focusCaret[1] = lineLength(focusCaret[0]);
+ savedFocusColumn = 0;
+ }
+ }
+ else if (keyCode == K_LEFT || keyCode == K_RIGHT) {
+ var left = (keyCode == K_LEFT);
+ if (left) {
+ if (moveMode == "toEnd") focusCaret[1] = 0;
+ else if (focusCaret[1] > 0) {
+ if (moveMode == "byWord") {
+ focusCaret[1] = moveByWordInLine(lineText(focusCaret[0]), focusCaret[1], false);
+ }
+ else {
+ focusCaret[1]--;
+ }
+ }
+ else if (focusCaret[0] > 0) {
+ focusCaret[0]--;
+ focusCaret[1] = lineLength(focusCaret[0]);
+ if (moveMode == "byWord") {
+ focusCaret[1] = moveByWordInLine(lineText(focusCaret[0]), focusCaret[1], false);
+ }
+ }
+ }
+ else {
+ var lineLen = lineLength(focusCaret[0]);
+ if (moveMode == "toEnd") focusCaret[1] = lineLen;
+ else if (focusCaret[1] < lineLen) {
+ if (moveMode == "byWord") {
+ focusCaret[1] = moveByWordInLine(lineText(focusCaret[0]), focusCaret[1], true);
+ }
+ else {
+ focusCaret[1]++;
+ }
+ }
+ else if (focusCaret[0] < rep.lines.length()-1) {
+ focusCaret[0]++;
+ focusCaret[1] = 0;
+ if (moveMode == "byWord") {
+ focusCaret[1] = moveByWordInLine(lineText(focusCaret[0]), focusCaret[1], true);
+ }
+ }
+ }
+ savedFocusColumn = 0;
+ }
+ }
+
+ var newSelFocusAtStart = ((focusCaret[0] < anchorCaret[0]) ||
+ (focusCaret[0] == anchorCaret[0] &&
+ focusCaret[1] < anchorCaret[1]));
+ var newSelStart = (newSelFocusAtStart ? focusCaret : anchorCaret);
+ var newSelEnd = (newSelFocusAtStart ? anchorCaret : focusCaret);
+ updatingSelectionNow = true;
+ performSelectionChange(markerfulLineAndChar(newSelStart[0],
+ newSelStart[1]),
+ markerfulLineAndChar(newSelEnd[0],
+ newSelEnd[1]),
+ newSelFocusAtStart);
+ updatingSelectionNow = false;
+ currentCallStack.userChangedSelection = true;
+ return true;
+ }
+ };
+ })());
+
+
+ // stolen from jquery-1.2.1
+ function fixEvent(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target && event.srcElement )
+ event.target = event.srcElement;
+
+ // check if target is a textnode (safari)
+ if (browser.safari && event.target.nodeType == 3)
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var e = document.documentElement, b = document.body;
+ event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
+ event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && (event.charCode || event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ }
+
+ var lineNumbersShown;
+ var sideDivInner;
+ function initLineNumbers() {
+ lineNumbersShown = 1;
+ sideDiv.innerHTML =
+ '<table border="0" cellpadding="0" cellspacing="0" align="right">'+
+ '<tr><td id="sidedivinner"><div>1</div></td></tr></table>';
+ sideDivInner = outerWin.document.getElementById("sidedivinner");
+ }
+
+ function updateLineNumbers() {
+ var newNumLines = rep.lines.length();
+ if (newNumLines < 1) newNumLines = 1;
+ if (newNumLines != lineNumbersShown) {
+ var container = sideDivInner;
+ var odoc = outerWin.document;
+ while (lineNumbersShown < newNumLines) {
+ lineNumbersShown++;
+ var n = lineNumbersShown;
+ var div = odoc.createElement("DIV");
+ div.appendChild(odoc.createTextNode(String(n)));
+ container.appendChild(div);
+ }
+ while (lineNumbersShown > newNumLines) {
+ container.removeChild(container.lastChild);
+ lineNumbersShown--;
+ }
+ }
+
+ if (currentCallStack && currentCallStack.domClean) {
+ var a = sideDivInner.firstChild;
+ var b = doc.body.firstChild;
+ while (a && b) {
+ var h = (b.clientHeight || b.offsetHeight);
+ if (b.nextSibling) {
+ // when text is zoomed in mozilla, divs have fractional
+ // heights (though the properties are always integers)
+ // and the line-numbers don't line up unless we pay
+ // attention to where the divs are actually placed...
+ // (also: padding on TTs/SPANs in IE...)
+ h = b.nextSibling.offsetTop - b.offsetTop;
+ }
+ if (h) {
+ var hpx = h+"px";
+ if (a.style.height != hpx)
+ a.style.height = hpx;
+ }
+ a = a.nextSibling;
+ b = b.nextSibling;
+ }
+ }
+ }
+
+};
+
+OUTER(this);
diff --git a/infrastructure/ace/www/ace2_outer.js b/infrastructure/ace/www/ace2_outer.js
new file mode 100644
index 0000000..b0fc20c
--- /dev/null
+++ b/infrastructure/ace/www/ace2_outer.js
@@ -0,0 +1,214 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+Ace2Editor.registry = { nextId: 1 };
+
+function Ace2Editor() {
+ var thisFunctionsName = "Ace2Editor";
+ var ace2 = Ace2Editor;
+
+ var editor = {};
+ var info = { editor: editor, id: (ace2.registry.nextId++) };
+ var loaded = false;
+
+ var actionsPendingInit = [];
+ function pendingInit(func, optDoNow) {
+ return function() {
+ var that = this;
+ var args = arguments;
+ function action() {
+ func.apply(that, args);
+ }
+ if (optDoNow) {
+ optDoNow.apply(that, args);
+ }
+ if (loaded) {
+ action();
+ }
+ else {
+ actionsPendingInit.push(action);
+ }
+ };
+ }
+ function doActionsPendingInit() {
+ for(var i=0;i<actionsPendingInit.length;i++) {
+ actionsPendingInit[i]();
+ }
+ actionsPendingInit = [];
+ }
+
+ ace2.registry[info.id] = info;
+
+ editor.importText = pendingInit(function(newCode, undoable) {
+ info.ace_importText(newCode, undoable); });
+ editor.importAText = pendingInit(function(newCode, apoolJsonObj, undoable) {
+ info.ace_importAText(newCode, apoolJsonObj, undoable); });
+ editor.exportText = function() {
+ if (! loaded) return "(awaiting init)\n";
+ return info.ace_exportText();
+ };
+ editor.getFrame = function() { return info.frame || null; };
+ editor.focus = pendingInit(function() { info.ace_focus(); });
+ editor.adjustSize = pendingInit(function() {
+ var frameParent = info.frame.parentNode;
+ var parentHeight = frameParent.clientHeight;
+ // deal with case where iframe is hidden, no clientHeight
+ info.frame.style.height = (parentHeight ? parentHeight+"px" :
+ frameParent.style.height);
+ info.ace_editorChangedSize();
+ });
+ editor.setEditable = pendingInit(function(newVal) { info.ace_setEditable(newVal); });
+ editor.getFormattedCode = function() { return info.ace_getFormattedCode(); };
+ editor.setOnKeyPress = pendingInit(function (handler) { info.ace_setOnKeyPress(handler); });
+ editor.setOnKeyDown = pendingInit(function (handler) { info.ace_setOnKeyDown(handler); });
+ editor.setNotifyDirty = pendingInit(function (handler) { info.ace_setNotifyDirty(handler); });
+
+ editor.setProperty = pendingInit(function(key, value) { info.ace_setProperty(key, value); });
+ editor.getDebugProperty = function(prop) { return info.ace_getDebugProperty(prop); };
+
+ editor.setBaseText = pendingInit(function(txt) { info.ace_setBaseText(txt); });
+ editor.setBaseAttributedText = pendingInit(function(atxt, apoolJsonObj) {
+ info.ace_setBaseAttributedText(atxt, apoolJsonObj); });
+ editor.applyChangesToBase = pendingInit(function (changes, optAuthor,apoolJsonObj) {
+ info.ace_applyChangesToBase(changes, optAuthor, apoolJsonObj); });
+ // prepareUserChangeset:
+ // Returns null if no new changes or ACE not ready. Otherwise, bundles up all user changes
+ // to the latest base text into a Changeset, which is returned (as a string if encodeAsString).
+ // If this method returns a truthy value, then applyPreparedChangesetToBase can be called
+ // at some later point to consider these changes part of the base, after which prepareUserChangeset
+ // must be called again before applyPreparedChangesetToBase. Multiple consecutive calls
+ // to prepareUserChangeset will return an updated changeset that takes into account the
+ // latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
+ // accordingly.
+ editor.prepareUserChangeset = function() {
+ if (! loaded) return null;
+ return info.ace_prepareUserChangeset();
+ };
+ editor.applyPreparedChangesetToBase = pendingInit(
+ function() { info.ace_applyPreparedChangesetToBase(); });
+ editor.setUserChangeNotificationCallback = pendingInit(function(callback) {
+ info.ace_setUserChangeNotificationCallback(callback);
+ });
+ editor.setAuthorInfo = pendingInit(function(author, authorInfo) {
+ info.ace_setAuthorInfo(author, authorInfo);
+ });
+ editor.setAuthorSelectionRange = pendingInit(function(author, start, end) {
+ info.ace_setAuthorSelectionRange(author, start, end);
+ });
+
+ editor.getUnhandledErrors = function() {
+ if (! loaded) return [];
+ // returns array of {error: <browser Error object>, time: +new Date()}
+ return info.ace_getUnhandledErrors();
+ };
+ editor.execCommand = pendingInit(function(cmd, arg1) {
+ info.ace_execCommand(cmd, arg1);
+ });
+
+ // calls to these functions ($$INCLUDE_...) are replaced when this file is processed
+ // and compressed, putting the compressed code from the named file directly into the
+ // source here.
+
+ var $$INCLUDE_CSS = function(fileName) {
+ return '<link rel="stylesheet" type="text/css" href="'+fileName+'"/>';
+ };
+ var $$INCLUDE_JS = function(fileName) {
+ return '\x3cscript type="text/javascript" src="'+fileName+'">\x3c/script>';
+ };
+ var $$INCLUDE_JS_DEV = $$INCLUDE_JS;
+ var $$INCLUDE_CSS_DEV = $$INCLUDE_CSS;
+
+ var $$INCLUDE_CSS_Q = function(fileName) {
+ return '\'<link rel="stylesheet" type="text/css" href="'+fileName+'"/>\'';
+ };
+ var $$INCLUDE_JS_Q = function(fileName) {
+ return '\'\\x3cscript type="text/javascript" src="'+fileName+'">\\x3c/script>\'';
+ };
+ var $$INCLUDE_JS_Q_DEV = $$INCLUDE_JS_Q;
+ var $$INCLUDE_CSS_Q_DEV = $$INCLUDE_CSS_Q;
+
+ editor.destroy = pendingInit(function() {
+ info.ace_dispose();
+ info.frame.parentNode.removeChild(info.frame);
+ delete ace2.registry[info.id];
+ info = null; // prevent IE 6 closure memory leaks
+ });
+
+ editor.init = function(containerId, initialCode, doneFunc) {
+
+ editor.importText(initialCode);
+
+ info.onEditorReady = function() {
+ loaded = true;
+ doActionsPendingInit();
+ doneFunc();
+ };
+
+ (function() {
+ var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '+
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
+
+ var iframeHTML = ["'"+doctype+"<html><head>'"];
+ // these lines must conform to a specific format because they are passed by the build script:
+ iframeHTML.push($$INCLUDE_CSS_Q("editor.css syntax.css inner.css"));
+ //iframeHTML.push(INCLUDE_JS_Q_DEV("ace2_common_dev.js"));
+ //iframeHTML.push(INCLUDE_JS_Q_DEV("profiler.js"));
+ iframeHTML.push($$INCLUDE_JS_Q("ace2_common.js skiplist.js virtual_lines.js easysync2.js cssmanager.js colorutils.js undomodule.js contentcollector.js changesettracker.js linestylefilter.js domline.js"));
+ iframeHTML.push($$INCLUDE_JS_Q("ace2_inner.js"));
+ iframeHTML.push('\'\\n<style type="text/css" title="dynamicsyntax"></style>\\n\'');
+ iframeHTML.push('\'</head><body id="innerdocbody" class="syntax" spellcheck="false">&nbsp;</body></html>\'');
+
+ var outerScript = 'editorId = "'+info.id+'"; editorInfo = parent.'+
+ thisFunctionsName+'.registry[editorId]; '+
+ 'window.onload = function() '+
+ '{ window.onload = null; setTimeout'+
+ '(function() '+
+ '{ var iframe = document.createElement("IFRAME"); '+
+ 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); '+
+ 'iframe.frameBorder = 0; iframe.allowTransparency = true; '+ // for IE
+ 'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); '+
+ 'iframe.ace_outerWin = window; '+
+ 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; '+
+ 'var doc = iframe.contentWindow.document; doc.open(); doc.write('+
+ iframeHTML.join('+')+'); doc.close(); '+
+ '}, 0); }';
+
+ var outerHTML = [doctype, '<html><head>',
+ $$INCLUDE_CSS("editor.css"),
+ // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
+ // (throbs busy while typing)
+ '<link rel="stylesheet" type="text/css" href="data:text/css,"/>',
+ '\x3cscript>', outerScript, '\x3c/script>',
+ '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>'];
+
+ var outerFrame = document.createElement("IFRAME");
+ outerFrame.frameBorder = 0; // for IE
+ info.frame = outerFrame;
+ document.getElementById(containerId).appendChild(outerFrame);
+
+ var editorDocument = outerFrame.contentWindow.document;
+
+ editorDocument.open();
+ editorDocument.write(outerHTML.join(''));
+ editorDocument.close();
+
+ editor.adjustSize();
+ })();
+ };
+
+ return editor;
+}
diff --git a/infrastructure/ace/www/ace2_wrapper.js b/infrastructure/ace/www/ace2_wrapper.js
new file mode 100644
index 0000000..b62e09d
--- /dev/null
+++ b/infrastructure/ace/www/ace2_wrapper.js
@@ -0,0 +1,226 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Exposes interface of Aaron's ace.js, including switching between plain and fancy editor.
+// Currently uses Aaron's code and depends on JQuery for plain editor.
+// -- David
+
+
+AppjetCodeEditor = function() {
+ this.browserSupportsModern = false;
+ this.aceImpl = null;
+ this.containerDiv = null;
+ this.containerId = null;
+ this.onKeyPress = null;
+ this.onKeyDown = null;
+ this.notifyDirty = null;
+ this.isEditable = true;
+};
+
+// TODO: take editorType as a param
+
+AppjetCodeEditor.prototype.init = function(containerId,
+ initialCode,
+ startModern,
+ done) {
+ this.containerId = containerId;
+ this.containerDiv = document.getElementById(containerId);
+
+ if (startModern) {
+ this.aceImplModern = new Ace2Editor();
+ this.aceImpl = this.aceImplModern;
+ } else {
+ this.aceImplPlain = new ACEPlain();
+ this.aceImpl = this.aceImplPlain;
+ }
+ this.aceImpl.init(containerId, initialCode, done);
+};
+
+AppjetCodeEditor.prototype.updateBottomLinks = function() {
+ if (ACEPlain.prototype.isPrototypeOf(this.aceImpl)) {
+ this.toggleModernLink.innerHTML = 'switch to rich text';
+ } else {
+ this.toggleModernLink.innerHTML = 'switch to plaintext';
+ }
+};
+
+AppjetCodeEditor.prototype.toggleModernImpl = function() {
+ var codeSave = this.aceImpl.exportCode();
+
+ if (ACEPlain.prototype.isPrototypeOf(this.aceImpl)) {
+ this.aceImpl.destroy();
+ this.aceImpl = new Ace2Editor();
+ } else {
+ this.aceImpl.destroy();
+ this.aceImpl = new ACEPlain();
+ }
+ var cont = this.containerDiv;
+ while (cont.firstChild) {
+ cont.removeChild(cont.firstChild);
+ }
+ this.aceImpl.init(this.containerId, codeSave, function() {} );
+
+ var ace = this;
+ function capitalize(str) { return str.substr(0,1).toUpperCase()+str.substr(1); }
+ $.each(["onKeyPress", "onKeyDown", "notifyDirty"], function() {
+ var setter = 'set'+capitalize(this);
+ if (ace[this]) {
+ ace.aceImpl[setter](ace[this]);
+ }
+ });
+ this.aceImpl.setEditable(this.isEditable);
+};
+
+AppjetCodeEditor.prototype.adjustContainerSizes = function() {
+ // TODO: adjust container sizes here.
+};
+
+//================================================================
+// Interface to ACE
+//================================================================
+
+AppjetCodeEditor.prototype.setOnKeyPress = function(f) {
+ this.onKeyPress = f;
+ this.aceImpl.setOnKeyPress(this.onKeyPress);
+};
+
+AppjetCodeEditor.prototype.setOnKeyDown = function(f) {
+ this.onKeyDown = f;
+ this.aceImpl.setOnKeyDown(this.onKeyDown);
+};
+
+AppjetCodeEditor.prototype.setNotifyDirty = function(f) {
+ this.notifyDirty = f;
+ this.aceImpl.setNotifyDirty(this.notifyDirty);
+};
+
+AppjetCodeEditor.prototype.setEditable = function(x) {
+ this.isEditable = x;
+ this.aceImpl.setEditable(x);
+};
+
+AppjetCodeEditor.prototype.adjustSize = function() {
+ this.adjustContainerSizes();
+ this.aceImpl.adjustSize();
+};
+
+//------- straight pass-through functions ---------------
+
+AppjetCodeEditor.prototype.importCode = function(rawCode) {
+ this.aceImpl.importCode(rawCode);
+};
+
+AppjetCodeEditor.prototype.exportCode = function() {
+ return this.aceImpl.exportCode();
+};
+
+AppjetCodeEditor.prototype.getFormattedCode = function() {
+ return this.aceImpl.getFormattedCode();
+};
+
+AppjetCodeEditor.prototype.focus = function() {
+ this.aceImpl.focus();
+};
+
+/* implementation of ACE with simple textarea */
+
+ACEPlain = function() {
+ this.containerDiv = null;
+ this.textArea = null;
+ this.onKeyPress = null;
+ this.onKeyDown = null;
+ this.notifyDirty = null;
+};
+
+ACEPlain.prototype.init = function(containerId, initialCode, done) {
+ var container = $('#'+containerId); //document.getElementById(containerId);
+
+ // empty container div
+ container.empty();
+ container.css('padding', 0);
+
+ // create textarea
+ var textArea = $('<textarea></textarea>');
+ textArea.css('border', 0).
+ css('margin', 0).
+ css('padding', 0).
+ css('background', 'transparent').
+ css('color', '#000').
+ attr('spellcheck', false);
+
+ // add textarea to container
+ container.append(textArea);
+
+ // remember nodes
+ this.textArea = textArea;
+ this.containerDiv = container;
+
+ // first-time size adjustments
+ this.adjustSize();
+
+ // remember keystrokes
+ var ace = this;
+ textArea.keydown(function(e) {
+ if (ace.onKeyDown) { ace.onKeyDown(e); }
+ });
+ textArea.keypress(function(e) {
+ if (ace.notifyDirty) { ace.notifyDirty(); }
+ if (ace.onKeyPress) { ace.onKeyPress(e); }
+ });
+
+ // set initial code
+ textArea.get(0).value = initialCode;
+
+ // callback
+ done();
+};
+
+ACEPlain.prototype.importCode = function(rawCode) {
+ this.textArea.attr('value', rawCode);
+};
+
+ACEPlain.prototype.exportCode = function() {
+ return this.textArea.attr('value');
+};
+
+ACEPlain.prototype.adjustSize = function() {
+ this.textArea.width('100%');
+ this.textArea.height(this.containerDiv.height());
+};
+
+ACEPlain.prototype.setOnKeyPress = function(f) { this.onKeyPress = f; };
+ACEPlain.prototype.setOnKeyDown = function(f) { this.onKeyDown = f; };
+ACEPlain.prototype.setNotifyDirty = function(f) { this.notifyDirty = f; };
+
+ACEPlain.prototype.getFormattedCode = function() {
+ return ('<pre>' + this.textArea.attr('value') + '</pre>');
+};
+
+ACEPlain.prototype.setEditable = function(editable) {
+ if (editable) {
+ this.textArea.removeAttr('disabled');
+ } else {
+ this.textArea.attr('disabled', true);
+ }
+};
+
+ACEPlain.prototype.focus = function() {
+ this.textArea.focus();
+};
+
+ACEPlain.prototype.destroy = function() {
+ // nothing
+};
diff --git a/infrastructure/ace/www/bbtree.js b/infrastructure/ace/www/bbtree.js
new file mode 100644
index 0000000..70cb8c0
--- /dev/null
+++ b/infrastructure/ace/www/bbtree.js
@@ -0,0 +1,372 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+function makeBBTree(transferContents, augment) {
+
+ var nil = [];
+ nil.push(nil,nil);
+ nil.level = 0;
+ var root = nil;
+ augment = (augment || (function(n) {}));
+
+ function skew(t) {
+ if (t != nil && t[0].level == t.level) {
+ // rotate right
+ var tmp = t;
+ t = t[0];
+ tmp[0] = t[1];
+ t[1] = tmp;
+ reaugment(tmp);
+ reaugment(t);
+ }
+ return t;
+ }
+
+ function split(t) {
+ if (t != nil && t[1][1].level == t.level) {
+ // rotate left
+ var tmp = t;
+ t = t[1];
+ tmp[1] = t[0];
+ t[0] = tmp;
+ t.level++;
+ reaugment(tmp);
+ reaugment(t);
+ }
+ return t;
+ }
+
+ function reaugment(n) {
+ if (n != nil) augment(n);
+ }
+
+ var self = {};
+
+ self.insert = function(compare) {
+ var n;
+ function recurse(t) {
+ if (t == nil) {
+ t = [nil,nil];
+ t.level = 1;
+ n = t;
+ }
+ else {
+ var cmp = compare(t);
+ if (cmp < 0) {
+ t[0] = recurse(t[0]);
+ }
+ else if (cmp > 0) {
+ t[1] = recurse(t[1]);
+ }
+ t = skew(t);
+ t = split(t);
+ }
+ reaugment(t);
+ return t;
+ }
+ root = recurse(root);
+ return n;
+ }
+
+ self.remove = function(compare) {
+ var deleted = nil;
+ var last;
+ var deletedEqual = false;
+ function recurse(t) {
+ if (t != nil) {
+ last = t;
+ var cmp = compare(t);
+ if (cmp < 0) {
+ t[0] = recurse(t[0]);
+ }
+ else {
+ deleted = t;
+ // whether the node called "deleted" is actually a
+ // match for deletion
+ deletedEqual = (cmp == 0);
+ t[1] = recurse(t[1]);
+ }
+ if (t == last && deleted != nil && deletedEqual) {
+ // t may be same node as deleted
+ transferContents(t, deleted);
+ t = t[1];
+ reaugment(deleted);
+ deleted = nil;
+ }
+ else {
+ reaugment(t);
+ if (t[0].level < t.level-1 ||
+ t[1].level < t.level-1) {
+ t.level--;
+ if (t[1].level > t.level)
+ t[1].level = t.level;
+ t = skew(t);
+ t[1] = skew(t[1]);
+ t[1][1] = skew(t[1][1]);
+ t = split(t);
+ t[1] = split(t[1]);
+ }
+ }
+ }
+ return t;
+ }
+ root = recurse(root);
+ }
+
+ self.find = function(compare) {
+ function recurse(t) {
+ if (t == nil) return t;
+ var cmp = compare(t);
+ if (cmp < 0) {
+ return recurse(t[0]);
+ }
+ else if (cmp > 0) {
+ return recurse(t[1]);
+ }
+ else {
+ return t;
+ }
+ }
+ var result = recurse(root);
+ return (result != nil && result) || null;
+ }
+
+ self.root = function() { return root; }
+
+ self.forEach = function(func) {
+ function recurse(t) {
+ if (t != nil) {
+ recurse(t[0]);
+ func(t);
+ recurse(t[1]);
+ }
+ }
+ recurse(root);
+ }
+
+ return self;
+}
+
+function makeBBList() {
+ var length = 0;
+ var totalWidth = 0;
+
+ function _treeSize(n) { return n.size || 0; }
+ function _treeWidth(n) { return n.width || 0; }
+ function _width(n) { return (n && n.entry && n.entry.width) || 0; }
+
+ function _transferContents(a, b) {
+ b.key = a.key;
+ b.entry = a.entry;
+ }
+ function _augment(n) {
+ n.size = _treeSize(n[0]) + _treeSize(n[1]) + 1;
+ n.width = _treeWidth(n[0]) + _treeWidth(n[1]) + _width(n);
+ }
+
+ var keyToEntry = {};
+
+ var bb = makeBBTree(transferContents, augment);
+
+ function makeIndexComparator(indexFunc) {
+ var curIndex = _treeSize(bb.root()[0]);
+ return function (n) {
+ var dir = indexFunc(curIndex, n);
+ if (dir < 0) {
+ curIndex -= _treeSize(n[0][1]) + 1;
+ }
+ else if (dir >= 0) {
+ curIndex += _treeSize(n[1][0]) + 1;
+ }
+ return dir;
+ }
+ }
+
+ function makeWidthComparator(widthFunc) {
+ var curIndex = _treeWidth(bb.root()[0]);
+ return function (n) {
+ var dir = indexFunc(curIndex, n);
+ if (dir < 0) {
+ curIndex -= _treeWidth(n[0][1]) + _width(n[0]);
+ }
+ else if (dir >= 0) {
+ curIndex += _treeWidth(n[1][0]) + _width(n);
+ }
+ return dir;
+ }
+ }
+
+ function numcomp(a,b) { if (a < b) return -1; if (a > b) return 1; return 0; }
+
+ function removeByIndex(idx) {
+ var entry;
+ bb.remove(makeComparator(function (curIndex, n) {
+ var cmp = numcomp(idx, curIndex);
+ if (cmp == 0) entry = n.entry;
+ return cmp;
+ }));
+ return entry;
+ }
+
+ function insertAtIndex(idx, entry) {
+ var newNode = bb.insert(makeComparator(function (curIndex) {
+ if (idx <= curIndex) return -1;
+ return 1;
+ }));
+ newNode.entry = entry;
+ return newNode;
+ }
+
+ var entriesByKey = {};
+
+ var self = {
+ splice: function (start, deleteCount, newEntryArray) {
+ for(var i=0;i<deleteCount;i++) {
+ var oldEntry = removeByIndex(start);
+ length--;
+ totalWidth -= (entry.width || 0);
+ delete entriesByKey[oldEntry.key];
+ }
+ for(var i=0;i<newEntryArray.length;i++) {
+ var entry = newEntryArray[i];
+ var newNode = insertAtIndex(start+i, entry);
+ length++;
+ totalWidth += (entry.width || 0);
+ entriesByKey[entry.key] = entry;
+ }
+ },
+ next: function (entry) {
+
+ }
+ };
+
+ return self;
+}
+
+/*function size(n) {
+ return n.size || 0;
+}
+
+var a = makeBBTree(function (a,b) {
+ b.data = a.data;
+},
+ function (n) {
+ n.size = size(n[0]) + size(n[1]) + 1;
+ });
+
+var arrayRep = [];
+
+function makeComparator(indexFunc) {
+ var curIndex = size(a.root()[0]);
+ return function (n) {
+ var dir = indexFunc(curIndex);
+ if (dir < 0) {
+ curIndex -= size(n[0][1]) + 1;
+ }
+ else if (dir >= 0) {
+ curIndex += size(n[1][0]) + 1;
+ }
+ return dir;
+ }
+}
+
+function insert(idx, data) {
+ arrayRep.splice(idx, 0, data);
+ var newNode = a.insert(makeComparator(function (curIndex) {
+ if (idx <= curIndex) return -1;
+ return 1;
+ }));
+ newNode.data = data;
+ checkRep();
+}
+
+function remove(idx) {
+ arrayRep.splice(idx, 1);
+ a.remove(makeComparator(function (curIndex) {
+ return numcomp(idx, curIndex);
+ }));
+ checkRep();
+}
+
+function genArray() {
+ var array = [];
+ a.forEach(function (n) { array.push(n.data); });
+ return array;
+}
+
+function checkRep() {
+ var array2 = genArray();
+ var str1 = array2.join(',');
+ var str2 = arrayRep.join(',');
+ if (str1 != str2) console.error(str1+" != "+str2);
+
+ a.forEach(function(n) {
+ if (size(n) != size(n[0]) + size(n[1]) + 1) {
+ console.error("size of "+n.data+" is wrong");
+ }
+ });
+}
+
+function print() {
+ console.log(genArray().join(','));
+}
+
+insert(0,1);
+insert(0,2);
+insert(0,3);
+insert(1,4);
+insert(4,5);
+insert(0,6);
+print();
+
+function numcomp(a,b) { if (a < b) return -1; if (a > b) return 1; return 0; }
+*/
+/*var tree = makeBBTree(function(a, b) { b.key = a.key; });
+function insert(x) { tree.insert(function(n) { return numcomp(x, n.key) }).key = x; }
+function remove(x) { tree.remove(function (n) { return numcomp(x, n.key); }); }
+function contains(x) { return !! tree.find(function (n) { return numcomp(x, n.key); }); }
+
+function print() {
+ function recurse(t) {
+ if (! ('key' in t)) return '';
+ return '('+recurse(t[0])+','+t.key+','+recurse(t[1])+')';
+ }
+ return recurse(tree.root());
+}
+
+
+insert(2);
+insert(1);
+insert(8);
+insert(7);
+console.log(print());
+insert(6);
+insert(3);
+insert(5);
+insert(4);
+console.log(print());
+remove(2);
+remove(1);
+remove(8);
+remove(7);
+console.log(print());
+//remove(6);
+//remove(3);
+//remove(5);
+//remove(4);
+//console.log(print());
+*/ \ No newline at end of file
diff --git a/infrastructure/ace/www/changesettracker.js b/infrastructure/ace/www/changesettracker.js
new file mode 100644
index 0000000..d6fe018
--- /dev/null
+++ b/infrastructure/ace/www/changesettracker.js
@@ -0,0 +1,170 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) {
+
+ // latest official text from server
+ var baseAText = Changeset.makeAText("\n");
+ // changes applied to baseText that have been submitted
+ var submittedChangeset = null;
+ // changes applied to submittedChangeset since it was prepared
+ var userChangeset = Changeset.identity(1);
+ // is the changesetTracker enabled
+ var tracking = false;
+ // stack state flag so that when we change the rep we don't
+ // handle the notification recursively. When setting, always
+ // unset in a "finally" block. When set to true, the setter
+ // takes change of userChangeset.
+ var applyingNonUserChanges = false;
+
+ var changeCallback = null;
+
+ var changeCallbackTimeout = null;
+ function setChangeCallbackTimeout() {
+ // can call this multiple times per call-stack, because
+ // we only schedule a call to changeCallback if it exists
+ // and if there isn't a timeout already scheduled.
+ if (changeCallback && changeCallbackTimeout === null) {
+ changeCallbackTimeout = scheduler.setTimeout(function() {
+ try {
+ changeCallback();
+ }
+ finally {
+ changeCallbackTimeout = null;
+ }
+ }, 0);
+ }
+ }
+
+ var self;
+ return self = {
+ isTracking: function() { return tracking; },
+ setBaseText: function(text) {
+ self.setBaseAttributedText(Changeset.makeAText(text), null);
+ },
+ setBaseAttributedText: function(atext, apoolJsonObj) {
+ aceCallbacksProvider.withCallbacks("setBaseText", function(callbacks) {
+ tracking = true;
+ baseAText = Changeset.cloneAText(atext);
+ if (apoolJsonObj) {
+ var wireApool = (new AttribPool()).fromJsonable(apoolJsonObj);
+ baseAText.attribs = Changeset.moveOpsToNewPool(baseAText.attribs, wireApool, apool);
+ }
+ submittedChangeset = null;
+ userChangeset = Changeset.identity(atext.text.length);
+ applyingNonUserChanges = true;
+ try {
+ callbacks.setDocumentAttributedText(atext);
+ }
+ finally {
+ applyingNonUserChanges = false;
+ }
+ });
+ },
+ composeUserChangeset: function(c) {
+ if (! tracking) return;
+ if (applyingNonUserChanges) return;
+ if (Changeset.isIdentity(c)) return;
+ userChangeset = Changeset.compose(userChangeset, c, apool);
+
+ setChangeCallbackTimeout();
+ },
+ applyChangesToBase: function (c, optAuthor, apoolJsonObj) {
+ if (! tracking) return;
+
+ aceCallbacksProvider.withCallbacks("applyChangesToBase", function(callbacks) {
+
+ if (apoolJsonObj) {
+ var wireApool = (new AttribPool()).fromJsonable(apoolJsonObj);
+ c = Changeset.moveOpsToNewPool(c, wireApool, apool);
+ }
+
+ baseAText = Changeset.applyToAText(c, baseAText, apool);
+
+ var c2 = c;
+ if (submittedChangeset) {
+ var oldSubmittedChangeset = submittedChangeset;
+ submittedChangeset = Changeset.follow(c, oldSubmittedChangeset, false, apool);
+ c2 = Changeset.follow(oldSubmittedChangeset, c, true, apool);
+ }
+
+ var preferInsertingAfterUserChanges = true;
+ var oldUserChangeset = userChangeset;
+ userChangeset = Changeset.follow(c2, oldUserChangeset, preferInsertingAfterUserChanges, apool);
+ var postChange =
+ Changeset.follow(oldUserChangeset, c2, ! preferInsertingAfterUserChanges, apool);
+
+ var preferInsertionAfterCaret = true; //(optAuthor && optAuthor > thisAuthor);
+
+ applyingNonUserChanges = true;
+ try {
+ callbacks.applyChangesetToDocument(postChange, preferInsertionAfterCaret);
+ }
+ finally {
+ applyingNonUserChanges = false;
+ }
+ });
+ },
+ prepareUserChangeset: function() {
+ // If there are user changes to submit, 'changeset' will be the
+ // changeset, else it will be null.
+ var toSubmit;
+ if (submittedChangeset) {
+ // submission must have been canceled, prepare new changeset
+ // that includes old submittedChangeset
+ toSubmit = Changeset.compose(submittedChangeset, userChangeset, apool);
+ }
+ else {
+ if (Changeset.isIdentity(userChangeset)) toSubmit = null;
+ else toSubmit = userChangeset;
+ }
+
+ var cs = null;
+ if (toSubmit) {
+ submittedChangeset = toSubmit;
+ userChangeset = Changeset.identity(Changeset.newLen(toSubmit));
+
+ cs = toSubmit;
+ }
+ var wireApool = null;
+ if (cs) {
+ var forWire = Changeset.prepareForWire(cs, apool);
+ wireApool = forWire.pool.toJsonable();
+ cs = forWire.translated;
+ }
+
+ var data = { changeset: cs, apool: wireApool };
+ return data;
+ },
+ applyPreparedChangesetToBase: function() {
+ if (! submittedChangeset) {
+ // violation of protocol; use prepareUserChangeset first
+ throw new Error("applySubmittedChangesToBase: no submitted changes to apply");
+ }
+ //bumpDebug("applying committed changeset: "+submittedChangeset.encodeToString(false));
+ baseAText = Changeset.applyToAText(submittedChangeset, baseAText, apool);
+ submittedChangeset = null;
+ },
+ setUserChangeNotificationCallback: function (callback) {
+ changeCallback = callback;
+ },
+ hasUncommittedChanges: function() {
+ return !!(submittedChangeset || (! Changeset.isIdentity(userChangeset)));
+ }
+ };
+
+}
diff --git a/infrastructure/ace/www/colorutils.js b/infrastructure/ace/www/colorutils.js
new file mode 100644
index 0000000..bb61de3
--- /dev/null
+++ b/infrastructure/ace/www/colorutils.js
@@ -0,0 +1,91 @@
+// THIS FILE IS ALSO SERVED AS CLIENT-SIDE JS
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var colorutils = {};
+
+// "#ffffff" or "#fff" or "ffffff" or "fff" to [1.0, 1.0, 1.0]
+colorutils.css2triple = function(cssColor) {
+ var sixHex = colorutils.css2sixhex(cssColor);
+ function hexToFloat(hh) {
+ return Number("0x"+hh)/255;
+ }
+ return [hexToFloat(sixHex.substr(0,2)),
+ hexToFloat(sixHex.substr(2,2)),
+ hexToFloat(sixHex.substr(4,2))];
+}
+
+// "#ffffff" or "#fff" or "ffffff" or "fff" to "ffffff"
+colorutils.css2sixhex = function(cssColor) {
+ var h = /[0-9a-fA-F]+/.exec(cssColor)[0];
+ if (h.length != 6) {
+ var a = h.charAt(0);
+ var b = h.charAt(1);
+ var c = h.charAt(2);
+ h = a+a+b+b+c+c;
+ }
+ return h;
+}
+
+// [1.0, 1.0, 1.0] -> "#ffffff"
+colorutils.triple2css = function(triple) {
+ function floatToHex(n) {
+ var n2 = colorutils.clamp(Math.round(n*255), 0, 255);
+ return ("0"+n2.toString(16)).slice(-2);
+ }
+ return "#" + floatToHex(triple[0]) +
+ floatToHex(triple[1]) + floatToHex(triple[2]);
+}
+
+
+colorutils.clamp = function(v,bot,top) { return v < bot ? bot : (v > top ? top : v); };
+colorutils.min3 = function(a,b,c) { return (a < b) ? (a < c ? a : c) : (b < c ? b : c); };
+colorutils.max3 = function(a,b,c) { return (a > b) ? (a > c ? a : c) : (b > c ? b : c); };
+colorutils.colorMin = function(c) { return colorutils.min3(c[0], c[1], c[2]); };
+colorutils.colorMax = function(c) { return colorutils.max3(c[0], c[1], c[2]); };
+colorutils.scale = function(v, bot, top) { return colorutils.clamp(bot + v*(top-bot), 0, 1); };
+colorutils.unscale = function(v, bot, top) { return colorutils.clamp((v-bot)/(top-bot), 0, 1); };
+
+colorutils.scaleColor = function(c, bot, top) {
+ return [colorutils.scale(c[0], bot, top),
+ colorutils.scale(c[1], bot, top),
+ colorutils.scale(c[2], bot, top)];
+}
+
+colorutils.unscaleColor = function(c, bot, top) {
+ return [colorutils.unscale(c[0], bot, top),
+ colorutils.unscale(c[1], bot, top),
+ colorutils.unscale(c[2], bot, top)];
+}
+
+colorutils.luminosity = function(c) {
+ // rule of thumb for RGB brightness; 1.0 is white
+ return c[0]*0.30 + c[1]*0.59 + c[2]*0.11;
+}
+
+colorutils.saturate = function(c) {
+ var min = colorutils.colorMin(c);
+ var max = colorutils.colorMax(c);
+ if (max - min <= 0) return [1.0, 1.0, 1.0];
+ return colorutils.unscaleColor(c, min, max);
+}
+
+colorutils.blend = function(c1, c2, t) {
+ return [colorutils.scale(t, c1[0], c2[0]),
+ colorutils.scale(t, c1[1], c2[1]),
+ colorutils.scale(t, c1[2], c2[2])];
+}
diff --git a/infrastructure/ace/www/contentcollector.js b/infrastructure/ace/www/contentcollector.js
new file mode 100644
index 0000000..c5d8ddb
--- /dev/null
+++ b/infrastructure/ace/www/contentcollector.js
@@ -0,0 +1,509 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.contentcollector
+// %APPJET%: import("etherpad.collab.ace.easysync2.Changeset")
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _MAX_LIST_LEVEL = 8;
+
+function sanitizeUnicode(s) {
+ return s.replace(/[\uffff\ufffe\ufeff\ufdd0-\ufdef\ud800-\udfff]/g, '?');
+}
+
+function makeContentCollector(collectStyles, browser, apool, domInterface,
+ className2Author) {
+ browser = browser || {};
+
+ var dom = domInterface || {
+ isNodeText: function(n) {
+ return (n.nodeType == 3);
+ },
+ nodeTagName: function(n) {
+ return n.tagName;
+ },
+ nodeValue: function(n) {
+ return n.nodeValue;
+ },
+ nodeNumChildren: function(n) {
+ return n.childNodes.length;
+ },
+ nodeChild: function(n, i) {
+ return n.childNodes.item(i);
+ },
+ nodeProp: function(n, p) {
+ return n[p];
+ },
+ nodeAttr: function(n, a) {
+ return n.getAttribute(a);
+ },
+ optNodeInnerHTML: function(n) {
+ return n.innerHTML;
+ }
+ };
+
+ var _blockElems = { "div":1, "p":1, "pre":1, "li":1 };
+ function isBlockElement(n) {
+ return !!_blockElems[(dom.nodeTagName(n) || "").toLowerCase()];
+ }
+ function textify(str) {
+ return sanitizeUnicode(
+ str.replace(/[\n\r ]/g, ' ').replace(/\xa0/g, ' ').replace(/\t/g, ' '));
+ }
+ function getAssoc(node, name) {
+ return dom.nodeProp(node, "_magicdom_"+name);
+ }
+
+ var lines = (function() {
+ var textArray = [];
+ var attribsArray = [];
+ var attribsBuilder = null;
+ var op = Changeset.newOp('+');
+ var self = {
+ length: function() { return textArray.length; },
+ atColumnZero: function() {
+ return textArray[textArray.length-1] === "";
+ },
+ startNew: function() {
+ textArray.push("");
+ self.flush(true);
+ attribsBuilder = Changeset.smartOpAssembler();
+ },
+ textOfLine: function(i) { return textArray[i]; },
+ appendText: function(txt, attrString) {
+ textArray[textArray.length-1] += txt;
+ //dmesg(txt+" / "+attrString);
+ op.attribs = attrString;
+ op.chars = txt.length;
+ attribsBuilder.append(op);
+ },
+ textLines: function() { return textArray.slice(); },
+ attribLines: function() { return attribsArray; },
+ // call flush only when you're done
+ flush: function(withNewline) {
+ if (attribsBuilder) {
+ attribsArray.push(attribsBuilder.toString());
+ attribsBuilder = null;
+ }
+ }
+ };
+ self.startNew();
+ return self;
+ }());
+ var cc = {};
+ function _ensureColumnZero(state) {
+ if (! lines.atColumnZero()) {
+ _startNewLine(state);
+ }
+ }
+ var selection, startPoint, endPoint;
+ var selStart = [-1,-1], selEnd = [-1,-1];
+ var blockElems = { "div":1, "p":1, "pre":1 };
+ function _isEmpty(node, state) {
+ // consider clean blank lines pasted in IE to be empty
+ if (dom.nodeNumChildren(node) == 0) return true;
+ if (dom.nodeNumChildren(node) == 1 &&
+ getAssoc(node, "shouldBeEmpty") && dom.optNodeInnerHTML(node) == "&nbsp;"
+ && ! getAssoc(node, "unpasted")) {
+ if (state) {
+ var child = dom.nodeChild(node, 0);
+ _reachPoint(child, 0, state);
+ _reachPoint(child, 1, state);
+ }
+ return true;
+ }
+ return false;
+ }
+ function _pointHere(charsAfter, state) {
+ var ln = lines.length()-1;
+ var chr = lines.textOfLine(ln).length;
+ if (chr == 0 && state.listType && state.listType != 'none') {
+ chr += 1; // listMarker
+ }
+ chr += charsAfter;
+ return [ln, chr];
+ }
+ function _reachBlockPoint(nd, idx, state) {
+ if (! dom.isNodeText(nd)) _reachPoint(nd, idx, state);
+ }
+ function _reachPoint(nd, idx, state) {
+ if (startPoint && nd == startPoint.node && startPoint.index == idx) {
+ selStart = _pointHere(0, state);
+ }
+ if (endPoint && nd == endPoint.node && endPoint.index == idx) {
+ selEnd = _pointHere(0, state);
+ }
+ }
+ function _incrementFlag(state, flagName) {
+ state.flags[flagName] = (state.flags[flagName] || 0)+1;
+ }
+ function _decrementFlag(state, flagName) {
+ state.flags[flagName]--;
+ }
+ function _incrementAttrib(state, attribName) {
+ if (! state.attribs[attribName]) {
+ state.attribs[attribName] = 1;
+ }
+ else {
+ state.attribs[attribName]++;
+ }
+ _recalcAttribString(state);
+ }
+ function _decrementAttrib(state, attribName) {
+ state.attribs[attribName]--;
+ _recalcAttribString(state);
+ }
+ function _enterList(state, listType) {
+ var oldListType = state.listType;
+ state.listLevel = (state.listLevel || 0)+1;
+ if (listType != 'none') {
+ state.listNesting = (state.listNesting || 0)+1;
+ }
+ state.listType = listType;
+ _recalcAttribString(state);
+ return oldListType;
+ }
+ function _exitList(state, oldListType) {
+ state.listLevel--;
+ if (state.listType != 'none') {
+ state.listNesting--;
+ }
+ state.listType = oldListType;
+ _recalcAttribString(state);
+ }
+ function _enterAuthor(state, author) {
+ var oldAuthor = state.author;
+ state.authorLevel = (state.authorLevel || 0)+1;
+ state.author = author;
+ _recalcAttribString(state);
+ return oldAuthor;
+ }
+ function _exitAuthor(state, oldAuthor) {
+ state.authorLevel--;
+ state.author = oldAuthor;
+ _recalcAttribString(state);
+ }
+ function _recalcAttribString(state) {
+ var lst = [];
+ for(var a in state.attribs) {
+ if (state.attribs[a]) {
+ lst.push([a,'true']);
+ }
+ }
+ if (state.authorLevel > 0) {
+ var authorAttrib = ['author', state.author];
+ if (apool.putAttrib(authorAttrib, true) >= 0) {
+ // require that author already be in pool
+ // (don't add authors from other documents, etc.)
+ lst.push(authorAttrib);
+ }
+ }
+ state.attribString = Changeset.makeAttribsString('+', lst, apool);
+ }
+ function _produceListMarker(state) {
+ lines.appendText('*', Changeset.makeAttribsString(
+ '+', [['list', state.listType],
+ ['insertorder', 'first']],
+ apool));
+ }
+ function _startNewLine(state) {
+ if (state) {
+ var atBeginningOfLine = lines.textOfLine(lines.length()-1).length == 0;
+ if (atBeginningOfLine && state.listType && state.listType != 'none') {
+ _produceListMarker(state);
+ }
+ }
+ lines.startNew();
+ }
+ cc.notifySelection = function (sel) {
+ if (sel) {
+ selection = sel;
+ startPoint = selection.startPoint;
+ endPoint = selection.endPoint;
+ }
+ };
+ cc.collectContent = function (node, state) {
+ if (! state) {
+ state = {flags: {/*name -> nesting counter*/},
+ attribs: {/*name -> nesting counter*/},
+ attribString: ''};
+ }
+ var isBlock = isBlockElement(node);
+ var isEmpty = _isEmpty(node, state);
+ if (isBlock) _ensureColumnZero(state);
+ var startLine = lines.length()-1;
+ _reachBlockPoint(node, 0, state);
+ if (dom.isNodeText(node)) {
+ var txt = dom.nodeValue(node);
+ var rest = '';
+ var x = 0; // offset into original text
+ if (txt.length == 0) {
+ if (startPoint && node == startPoint.node) {
+ selStart = _pointHere(0, state);
+ }
+ if (endPoint && node == endPoint.node) {
+ selEnd = _pointHere(0, state);
+ }
+ }
+ while (txt.length > 0) {
+ var consumed = 0;
+ if (state.flags.preMode) {
+ var firstLine = txt.split('\n',1)[0];
+ consumed = firstLine.length+1;
+ rest = txt.substring(consumed);
+ txt = firstLine;
+ }
+ else { /* will only run this loop body once */ }
+ if (startPoint && node == startPoint.node &&
+ startPoint.index-x <= txt.length) {
+ selStart = _pointHere(startPoint.index-x, state);
+ }
+ if (endPoint && node == endPoint.node &&
+ endPoint.index-x <= txt.length) {
+ selEnd = _pointHere(endPoint.index-x, state);
+ }
+ var txt2 = txt;
+ if ((! state.flags.preMode) && /^[\r\n]*$/.exec(txt)) {
+ // prevents textnodes containing just "\n" from being significant
+ // in safari when pasting text, now that we convert them to
+ // spaces instead of removing them, because in other cases
+ // removing "\n" from pasted HTML will collapse words together.
+ txt2 = "";
+ }
+ var atBeginningOfLine = lines.textOfLine(lines.length()-1).length == 0;
+ if (atBeginningOfLine) {
+ // newlines in the source mustn't become spaces at beginning of line box
+ txt2 = txt2.replace(/^\n*/, '');
+ }
+ if (atBeginningOfLine && state.listType && state.listType != 'none') {
+ _produceListMarker(state);
+ }
+ lines.appendText(textify(txt2), state.attribString);
+ x += consumed;
+ txt = rest;
+ if (txt.length > 0) {
+ _startNewLine(state);
+ }
+ }
+ }
+ else {
+ var tname = (dom.nodeTagName(node) || "").toLowerCase();
+ if (tname == "br") {
+ _startNewLine(state);
+ }
+ else if (tname == "script" || tname == "style") {
+ // ignore
+ }
+ else if (! isEmpty) {
+ var styl = dom.nodeAttr(node, "style");
+ var cls = dom.nodeProp(node, "className");
+
+ var isPre = (tname == "pre");
+ if ((! isPre) && browser.safari) {
+ isPre = (styl && /\bwhite-space:\s*pre\b/i.exec(styl));
+ }
+ if (isPre) _incrementFlag(state, 'preMode');
+ var attribs = null;
+ var oldListTypeOrNull = null;
+ var oldAuthorOrNull = null;
+ if (collectStyles) {
+ function doAttrib(na) {
+ attribs = (attribs || []);
+ attribs.push(na);
+ _incrementAttrib(state, na);
+ }
+ if (tname == "b" || (styl && /\bfont-weight:\s*bold\b/i.exec(styl)) ||
+ tname == "strong") {
+ doAttrib("bold");
+ }
+ if (tname == "i" || (styl && /\bfont-style:\s*italic\b/i.exec(styl)) ||
+ tname == "em") {
+ doAttrib("italic");
+ }
+ if (tname == "u" || (styl && /\btext-decoration:\s*underline\b/i.exec(styl)) ||
+ tname == "ins") {
+ doAttrib("underline");
+ }
+ if (tname == "s" || (styl && /\btext-decoration:\s*line-through\b/i.exec(styl)) ||
+ tname == "del") {
+ doAttrib("strikethrough");
+ }
+ if (tname == "ul") {
+ var type;
+ var rr = cls && /(?:^| )list-(bullet[12345678])\b/.exec(cls);
+ type = rr && rr[1] || "bullet"+
+ String(Math.min(_MAX_LIST_LEVEL, (state.listNesting||0)+1));
+ oldListTypeOrNull = (_enterList(state, type) || 'none');
+ }
+ else if ((tname == "div" || tname == "p") && cls &&
+ cls.match(/(?:^| )ace-line\b/)) {
+ oldListTypeOrNull = (_enterList(state, type) || 'none');
+ }
+ if (className2Author && cls) {
+ var classes = cls.match(/\S+/g);
+ if (classes && classes.length > 0) {
+ for(var i=0;i<classes.length;i++) {
+ var c = classes[i];
+ var a = className2Author(c);
+ if (a) {
+ oldAuthorOrNull = (_enterAuthor(state, a) || 'none');
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ var nc = dom.nodeNumChildren(node);
+ for(var i=0;i<nc;i++) {
+ var c = dom.nodeChild(node, i);
+ cc.collectContent(c, state);
+ }
+
+ if (isPre) _decrementFlag(state, 'preMode');
+ if (attribs) {
+ for(var i=0;i<attribs.length;i++) {
+ _decrementAttrib(state, attribs[i]);
+ }
+ }
+ if (oldListTypeOrNull) {
+ _exitList(state, oldListTypeOrNull);
+ }
+ if (oldAuthorOrNull) {
+ _exitAuthor(state, oldAuthorOrNull);
+ }
+ }
+ }
+ if (! browser.msie) {
+ _reachBlockPoint(node, 1, state);
+ }
+ if (isBlock) {
+ if (lines.length()-1 == startLine) {
+ _startNewLine(state);
+ }
+ else {
+ _ensureColumnZero(state);
+ }
+ }
+
+ if (browser.msie) {
+ // in IE, a point immediately after a DIV appears on the next line
+ _reachBlockPoint(node, 1, state);
+ }
+ };
+ // can pass a falsy value for end of doc
+ cc.notifyNextNode = function (node) {
+ // an "empty block" won't end a line; this addresses an issue in IE with
+ // typing into a blank line at the end of the document. typed text
+ // goes into the body, and the empty line div still looks clean.
+ // it is incorporated as dirty by the rule that a dirty region has
+ // to end a line.
+ if ((!node) || (isBlockElement(node) && !_isEmpty(node))) {
+ _ensureColumnZero(null);
+ }
+ };
+ // each returns [line, char] or [-1,-1]
+ var getSelectionStart = function() { return selStart; };
+ var getSelectionEnd = function() { return selEnd; };
+
+ // returns array of strings for lines found, last entry will be "" if
+ // last line is complete (i.e. if a following span should be on a new line).
+ // can be called at any point
+ cc.getLines = function() { return lines.textLines(); };
+
+ //cc.applyHints = function(hints) {
+ //if (hints.pastedLines) {
+ //
+ //}
+ //}
+
+ cc.finish = function() {
+ lines.flush();
+ var lineAttribs = lines.attribLines();
+ var lineStrings = cc.getLines();
+
+ lineStrings.length--;
+ lineAttribs.length--;
+
+ var ss = getSelectionStart();
+ var se = getSelectionEnd();
+
+ function fixLongLines() {
+ // design mode does not deal with with really long lines!
+ var lineLimit = 2000; // chars
+ var buffer = 10; // chars allowed over before wrapping
+ var linesWrapped = 0;
+ var numLinesAfter = 0;
+ for(var i=lineStrings.length-1; i>=0; i--) {
+ var oldString = lineStrings[i];
+ var oldAttribString = lineAttribs[i];
+ if (oldString.length > lineLimit+buffer) {
+ var newStrings = [];
+ var newAttribStrings = [];
+ while (oldString.length > lineLimit) {
+ //var semiloc = oldString.lastIndexOf(';', lineLimit-1);
+ //var lengthToTake = (semiloc >= 0 ? (semiloc+1) : lineLimit);
+ lengthToTake = lineLimit;
+ newStrings.push(oldString.substring(0, lengthToTake));
+ oldString = oldString.substring(lengthToTake);
+ newAttribStrings.push(Changeset.subattribution(oldAttribString,
+ 0, lengthToTake));
+ oldAttribString = Changeset.subattribution(oldAttribString,
+ lengthToTake);
+ }
+ if (oldString.length > 0) {
+ newStrings.push(oldString);
+ newAttribStrings.push(oldAttribString);
+ }
+ function fixLineNumber(lineChar) {
+ if (lineChar[0] < 0) return;
+ var n = lineChar[0];
+ var c = lineChar[1];
+ if (n > i) {
+ n += (newStrings.length-1);
+ }
+ else if (n == i) {
+ var a = 0;
+ while (c > newStrings[a].length) {
+ c -= newStrings[a].length;
+ a++;
+ }
+ n += a;
+ }
+ lineChar[0] = n;
+ lineChar[1] = c;
+ }
+ fixLineNumber(ss);
+ fixLineNumber(se);
+ linesWrapped++;
+ numLinesAfter += newStrings.length;
+
+ newStrings.unshift(i, 1);
+ lineStrings.splice.apply(lineStrings, newStrings);
+ newAttribStrings.unshift(i, 1);
+ lineAttribs.splice.apply(lineAttribs, newAttribStrings);
+ }
+ }
+ return {linesWrapped:linesWrapped, numLinesAfter:numLinesAfter};
+ }
+ var wrapData = fixLongLines();
+
+ return { selStart: ss, selEnd: se, linesWrapped: wrapData.linesWrapped,
+ numLinesAfter: wrapData.numLinesAfter,
+ lines: lineStrings, lineAttribs: lineAttribs };
+ }
+
+ return cc;
+}
diff --git a/infrastructure/ace/www/cssmanager.js b/infrastructure/ace/www/cssmanager.js
new file mode 100644
index 0000000..a5c549b
--- /dev/null
+++ b/infrastructure/ace/www/cssmanager.js
@@ -0,0 +1,88 @@
+
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function makeCSSManager(emptyStylesheetTitle) {
+
+ function getSheetByTitle(title) {
+ var allSheets = document.styleSheets;
+ for(var i=0;i<allSheets.length;i++) {
+ var s = allSheets[i];
+ if (s.title == title) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ /*function getSheetTagByTitle(title) {
+ var allStyleTags = document.getElementsByTagName("style");
+ for(var i=0;i<allStyleTags.length;i++) {
+ var t = allStyleTags[i];
+ if (t.title == title) {
+ return t;
+ }
+ }
+ return null;
+ }*/
+
+ var browserSheet = getSheetByTitle(emptyStylesheetTitle);
+ //var browserTag = getSheetTagByTitle(emptyStylesheetTitle);
+ function browserRules() { return (browserSheet.cssRules || browserSheet.rules); }
+ function browserDeleteRule(i) {
+ if (browserSheet.deleteRule) browserSheet.deleteRule(i);
+ else browserSheet.removeRule(i);
+ }
+ function browserInsertRule(i, selector) {
+ if (browserSheet.insertRule) browserSheet.insertRule(selector+' {}', i);
+ else browserSheet.addRule(selector, null, i);
+ }
+ var selectorList = [];
+
+ function indexOfSelector(selector) {
+ for(var i=0;i<selectorList.length;i++) {
+ if (selectorList[i] == selector) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ function selectorStyle(selector) {
+ var i = indexOfSelector(selector);
+ if (i < 0) {
+ // add selector
+ browserInsertRule(0, selector);
+ selectorList.splice(0, 0, selector);
+ i = 0;
+ }
+ return browserRules().item(i).style;
+ }
+
+ function removeSelectorStyle(selector) {
+ var i = indexOfSelector(selector);
+ if (i >= 0) {
+ browserDeleteRule(i);
+ selectorList.splice(i, 1);
+ }
+ }
+
+ return {selectorStyle:selectorStyle, removeSelectorStyle:removeSelectorStyle,
+ info: function() {
+ return selectorList.length+":"+browserRules().length;
+ }};
+}
diff --git a/infrastructure/ace/www/dev.html b/infrastructure/ace/www/dev.html
new file mode 100644
index 0000000..0a9768e
--- /dev/null
+++ b/infrastructure/ace/www/dev.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html debug="true">
+ <head>
+ <script src="jquery-1.2.1.js"></script>
+ <script src="ace2_common.js"></script>
+ <script src="ace2_outer.js"></script>
+ <script src="firebug/firebug.js"></script>
+ <script>
+function updateHTMLDisplay(html) {
+ $("#htmldisplay").html(html);
+}
+
+function addMessage(str) {
+ var li = document.createElement("li");
+ li.innerHTML = str;
+ $("#messages").prepend(li);
+}
+ </script>
+ <style>
+ #devstuff {
+ background-color: #ddd;
+ padding: 1em;
+ }
+ #iframecontainer iframe { width: 500px; height: 300px; }
+ </style>
+ </head>
+ <body>
+ <div id="iframecontainer"><!-- --></div>
+ <hr>
+ <div id="devstuff">
+ <p><input type="text" id="cmdinput" size="100">
+ <button onclick="$('#cmdresult').html(htmlPrettyEscape(String(eval($('#cmdinput').get(0).value))))">Execute</button></p>
+ <p id="cmdresult"><!-- --></p>
+ <p id="htmldisplay"><!-- --></p>
+ <ul id="messages"><!-- --></ul>
+ </div>
+ </body>
+</html>
diff --git a/infrastructure/ace/www/domline.js b/infrastructure/ace/www/domline.js
new file mode 100644
index 0000000..70f86cc
--- /dev/null
+++ b/infrastructure/ace/www/domline.js
@@ -0,0 +1,210 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.domline
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var domline = {};
+domline.noop = function() {};
+domline.identity = function(x) { return x; };
+
+domline.addToLineClass = function(lineClass, cls) {
+ // an "empty span" at any point can be used to add classes to
+ // the line, using line:className. otherwise, we ignore
+ // the span.
+ cls.replace(/\S+/g, function (c) {
+ if (c.indexOf("line:") == 0) {
+ // add class to line
+ lineClass = (lineClass ? lineClass+' ' : '')+c.substring(5);
+ }
+ });
+ return lineClass;
+}
+
+// if "document" is falsy we don't create a DOM node, just
+// an object with innerHTML and className
+domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) {
+ var result = { node: null,
+ appendSpan: domline.noop,
+ prepareForAdd: domline.noop,
+ notifyAdded: domline.noop,
+ clearSpans: domline.noop,
+ finishUpdate: domline.noop,
+ lineMarker: 0 };
+
+ var browser = (optBrowser || {});
+ var document = optDocument;
+
+ if (document) {
+ result.node = document.createElement("div");
+ }
+ else {
+ result.node = {innerHTML: '', className: ''};
+ }
+
+ var html = [];
+ var preHtml, postHtml;
+ var curHTML = null;
+ function processSpaces(s) {
+ return domline.processSpaces(s, doesWrap);
+ }
+ var identity = domline.identity;
+ var perTextNodeProcess = (doesWrap ? identity : processSpaces);
+ var perHtmlLineProcess = (doesWrap ? processSpaces : identity);
+ var lineClass = 'ace-line';
+ result.appendSpan = function(txt, cls) {
+ if (cls.indexOf('list') >= 0) {
+ var listType = /(?:^| )list:(\S+)/.exec(cls);
+ if (listType) {
+ listType = listType[1];
+ if (listType) {
+ preHtml = '<ul class="list-'+listType+'"><li>';
+ postHtml = '</li></ul>';
+ }
+ result.lineMarker += txt.length;
+ return; // don't append any text
+ }
+ }
+ var href = null;
+ var simpleTags = null;
+ if (cls.indexOf('url') >= 0) {
+ cls = cls.replace(/(^| )url:(\S+)/g, function(x0, space, url) {
+ href = url;
+ return space+"url";
+ });
+ }
+ if (cls.indexOf('tag') >= 0) {
+ cls = cls.replace(/(^| )tag:(\S+)/g, function(x0, space, tag) {
+ if (! simpleTags) simpleTags = [];
+ simpleTags.push(tag.toLowerCase());
+ return space+tag;
+ });
+ }
+ if ((! txt) && cls) {
+ lineClass = domline.addToLineClass(lineClass, cls);
+ }
+ else if (txt) {
+ var extraOpenTags = "";
+ var extraCloseTags = "";
+ if (href) {
+ extraOpenTags = extraOpenTags+'<a href="'+
+ href.replace(/\"/g, '&quot;')+'">';
+ extraCloseTags = '</a>'+extraCloseTags;
+ }
+ if (simpleTags) {
+ simpleTags.sort();
+ extraOpenTags = extraOpenTags+'<'+simpleTags.join('><')+'>';
+ simpleTags.reverse();
+ extraCloseTags = '</'+simpleTags.join('></')+'>'+extraCloseTags;
+ }
+ html.push('<span class="',cls||'','">',extraOpenTags,
+ perTextNodeProcess(domline.escapeHTML(txt)),
+ extraCloseTags,'</span>');
+ }
+ };
+ result.clearSpans = function() {
+ html = [];
+ lineClass = ''; // non-null to cause update
+ result.lineMarker = 0;
+ };
+ function writeHTML() {
+ var newHTML = perHtmlLineProcess(html.join(''));
+ if (! newHTML) {
+ if ((! document) || (! optBrowser)) {
+ newHTML += '&nbsp;';
+ }
+ else if (! browser.msie) {
+ newHTML += '<br/>';
+ }
+ }
+ if (nonEmpty) {
+ newHTML = (preHtml||'')+newHTML+(postHtml||'');
+ }
+ html = preHtml = postHtml = null; // free memory
+ if (newHTML !== curHTML) {
+ curHTML = newHTML;
+ result.node.innerHTML = curHTML;
+ }
+ if (lineClass !== null) result.node.className = lineClass;
+ }
+ result.prepareForAdd = writeHTML;
+ result.finishUpdate = writeHTML;
+ result.getInnerHTML = function() { return curHTML || ''; };
+
+ return result;
+};
+
+domline.escapeHTML = function(s) {
+ var re = /[&<>'"]/g; /']/; // stupid indentation thing
+ if (! re.MAP) {
+ // persisted across function calls!
+ re.MAP = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;'
+ };
+ }
+ return s.replace(re, function(c) { return re.MAP[c]; });
+};
+
+domline.processSpaces = function(s, doesWrap) {
+ if (s.indexOf("<") < 0 && ! doesWrap) {
+ // short-cut
+ return s.replace(/ /g, '&nbsp;');
+ }
+ var parts = [];
+ s.replace(/<[^>]*>?| |[^ <]+/g, function(m) { parts.push(m); });
+ if (doesWrap) {
+ var endOfLine = true;
+ var beforeSpace = false;
+ // last space in a run is normal, others are nbsp,
+ // end of line is nbsp
+ for(var i=parts.length-1;i>=0;i--) {
+ var p = parts[i];
+ if (p == " ") {
+ if (endOfLine || beforeSpace)
+ parts[i] = '&nbsp;';
+ endOfLine = false;
+ beforeSpace = true;
+ }
+ else if (p.charAt(0) != "<") {
+ endOfLine = false;
+ beforeSpace = false;
+ }
+ }
+ // beginning of line is nbsp
+ for(var i=0;i<parts.length;i++) {
+ var p = parts[i];
+ if (p == " ") {
+ parts[i] = '&nbsp;';
+ break;
+ }
+ else if (p.charAt(0) != "<") {
+ break;
+ }
+ }
+ }
+ else {
+ for(var i=0;i<parts.length;i++) {
+ var p = parts[i];
+ if (p == " ") {
+ parts[i] = '&nbsp;';
+ }
+ }
+ }
+ return parts.join('');
+};
diff --git a/infrastructure/ace/www/easy_sync.js b/infrastructure/ace/www/easy_sync.js
new file mode 100644
index 0000000..86a4327
--- /dev/null
+++ b/infrastructure/ace/www/easy_sync.js
@@ -0,0 +1,923 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.easysync1
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function Changeset(arg) {
+
+ var array;
+ if ((typeof arg) == "string") {
+ // constant
+ array = [Changeset.MAGIC, 0, arg.length, 0, 0, arg];
+ }
+ else if ((typeof arg) == "number") {
+ var n = Math.round(arg);
+ // delete-all on n-length text (useful for making a "builder")
+ array = [Changeset.MAGIC, n, 0, 0, 0, ""];
+ }
+ else if (! arg) {
+ // identity on 0-length text
+ array = [Changeset.MAGIC, 0, 0, 0, 0, ""];
+ }
+ else if (arg.isChangeset) {
+ return arg;
+ }
+ else array = arg;
+
+ array.isChangeset = true;
+
+ // OOP style: attach generic methods to array object, hold no state in environment
+
+ //function error(msg) { top.console.error(msg); top.console.trace(); }
+ function error(msg) { var e = new Error(msg); e.easysync = true; throw e; }
+ function assert(b, msg) { if (! b) error("Changeset: "+String(msg)); }
+ function min(x, y) { return (x < y) ? x : y; }
+ Changeset._assert = assert;
+
+ array.isIdentity = function() {
+ return this.length == 6 && this[1] == this[2] && this[3] == 0 &&
+ this[4] == this[1] && this[5] == "";
+ }
+
+ array.eachStrip = function(func, thisObj) {
+ // inside "func", the method receiver will be "this" by default,
+ // or you can pass an object.
+ for(var i=0;i<this.numStrips();i++) {
+ var ptr = 3 + i*3;
+ if (func.call(thisObj || this, this[ptr], this[ptr+1], this[ptr+2], i))
+ return true;
+ }
+ return false;
+ }
+
+ array.numStrips = function() { return (this.length-3)/3; };
+ array.oldLen = function() { return this[1]; };
+ array.newLen = function() { return this[2]; };
+
+ array.checkRep = function() {
+ assert(this[0] == Changeset.MAGIC, "bad magic");
+ assert(this[1] >= 0, "bad old text length");
+ assert(this[2] >= 0, "bad new text length");
+ assert((this.length % 3) == 0, "bad array length");
+ assert(this.length >= 6, "must be at least one strip");
+ var numStrips = this.numStrips();
+ var oldLen = this[1];
+ var newLen = this[2];
+ // iterate over the "text strips"
+ var actualNewLen = 0;
+ this.eachStrip(function(startIndex, numTaken, newText, i) {
+ var s = startIndex, t = numTaken, n = newText;
+ var isFirst = (i == 0);
+ var isLast = (i == numStrips-1);
+ assert(t >= 0, "can't take negative number of chars");
+ assert(isFirst || t > 0, "all strips but first must take");
+ assert((t > 0) || (s == 0), "if first strip doesn't take, must have 0 startIndex");
+ assert(s >= 0 && s + t <= oldLen, "bad index: "+this.toString());
+ assert(t > 0 || n.length > 0 || (isFirst && isLast), "empty strip must be first and only");
+ if (! isLast) {
+ var s2 = this[3 + i*3 + 3]; // startIndex of following strip
+ var gap = s2 - (s + t);
+ assert(gap >= 0, "overlapping or out-of-order strips: "+this.toString());
+ assert(gap > 0 || n.length > 0, "touching strips with no added text");
+ }
+ actualNewLen += t + n.length;
+ });
+ assert(newLen == actualNewLen, "calculated new text length doesn't match");
+ }
+
+ array.applyToText = function(text) {
+ assert(text.length == this.oldLen(), "mismatched apply: "+text.length+" / "+this.oldLen());
+ var buf = [];
+ this.eachStrip(function (s, t, n) {
+ buf.push(text.substr(s, t), n);
+ });
+ return buf.join('');
+ }
+
+ function _makeBuilder(oldLen, supportAuthors) {
+ var C = Changeset(oldLen);
+ if (supportAuthors) {
+ _ensureAuthors(C);
+ }
+ return C.builder();
+ }
+
+ function _getNumInserted(C) {
+ var numChars = 0;
+ C.eachStrip(function(s,t,n) {
+ numChars += n.length;
+ });
+ return numChars;
+ }
+
+ function _ensureAuthors(C) {
+ if (! C.authors) {
+ C.setAuthor();
+ }
+ return C;
+ }
+
+ array.setAuthor = function(author) {
+ var C = this;
+ // authors array has even length >= 2;
+ // alternates [numChars1, author1, numChars2, author2];
+ // all numChars > 0 unless there is exactly one, in which
+ // case it can be == 0.
+ C.authors = [_getNumInserted(C), author || ''];
+ return C;
+ }
+
+ array.builder = function() {
+ // normal pattern is Changeset(oldLength).builder().appendOldText(...). ...
+ // builder methods mutate this!
+ var C = this;
+ // OOP style: state in environment
+ var self;
+ return self = {
+ appendNewText: function(str, author) {
+ C[C.length-1] += str;
+ C[2] += str.length;
+
+ if (C.authors) {
+ var a = (author || '');
+ var lastAuthorPtr = C.authors.length-1;
+ var lastAuthorLengthPtr = C.authors.length-2;
+ if ((!a) || a == C.authors[lastAuthorPtr]) {
+ C.authors[lastAuthorLengthPtr] += str.length;
+ }
+ else if (0 == C.authors[lastAuthorLengthPtr]) {
+ C.authors[lastAuthorLengthPtr] = str.length;
+ C.authors[lastAuthorPtr] = (a || C.authors[lastAuthorPtr]);
+ }
+ else {
+ C.authors.push(str.length, a);
+ }
+ }
+
+ return self;
+ },
+ appendOldText: function(startIndex, numTaken) {
+ if (numTaken == 0) return self;
+ // properties of last strip...
+ var s = C[C.length-3], t = C[C.length-2], n = C[C.length-1];
+ if (t == 0 && n == "") {
+ // must be empty changeset, one strip that doesn't take old chars or add new ones
+ C[C.length-3] = startIndex;
+ C[C.length-2] = numTaken;
+ }
+ else if (n == "" && (s+t == startIndex)) {
+ C[C.length-2] += numTaken; // take more
+ }
+ else C.push(startIndex, numTaken, ""); // add a strip
+ C[2] += numTaken;
+ C.checkRep();
+ return self;
+ },
+ toChangeset: function() { return C; }
+ };
+ }
+
+ array.authorSlicer = function(outputBuilder) {
+ return _makeAuthorSlicer(this, outputBuilder);
+ }
+
+ function _makeAuthorSlicer(changesetOrAuthorsIn, builderOut) {
+ // "builderOut" only needs to support appendNewText
+ var authors; // considered immutable
+ if (changesetOrAuthorsIn.isChangeset) {
+ authors = changesetOrAuthorsIn.authors;
+ }
+ else {
+ authors = changesetOrAuthorsIn;
+ }
+
+ // OOP style: state in environment
+ var authorPtr = 0;
+ var charIndex = 0;
+ var charWithinAuthor = 0; // 0 <= charWithinAuthor <= authors[authorPtr]; max value iff atEnd
+ var atEnd = false;
+ function curAuthor() { return authors[authorPtr+1]; }
+ function curAuthorWidth() { return authors[authorPtr]; }
+ function assertNotAtEnd() { assert(! atEnd, "_authorSlicer: can't move past end"); }
+ function forwardInAuthor(numChars) {
+ charWithinAuthor += numChars;
+ charIndex += numChars;
+ }
+ function nextAuthor() {
+ assertNotAtEnd();
+ assert(charWithinAuthor == curAuthorWidth(), "_authorSlicer: not at author end");
+ charWithinAuthor = 0;
+ authorPtr += 2;
+ if (authorPtr == authors.length) {
+ atEnd = true;
+ }
+ }
+
+ var self;
+ return self = {
+ skipChars: function(n) {
+ assert(n >= 0, "_authorSlicer: can't skip negative n");
+ if (n == 0) return;
+ assertNotAtEnd();
+
+ var leftToSkip = n;
+ while (leftToSkip > 0) {
+ var leftInAuthor = curAuthorWidth() - charWithinAuthor;
+ if (leftToSkip >= leftInAuthor) {
+ forwardInAuthor(leftInAuthor);
+ leftToSkip -= leftInAuthor;
+ nextAuthor();
+ }
+ else {
+ forwardInAuthor(leftToSkip);
+ leftToSkip = 0;
+ }
+ }
+ },
+ takeChars: function(n, text) {
+ assert(n >= 0, "_authorSlicer: can't take negative n");
+ if (n == 0) return;
+ assertNotAtEnd();
+ assert(n == text.length, "_authorSlicer: bad text length");
+
+ var textLeft = text;
+ var leftToTake = n;
+ while (leftToTake > 0) {
+ if (curAuthorWidth() > 0 && charWithinAuthor < curAuthorWidth()) {
+ // at least one char to take from current author
+ var leftInAuthor = (curAuthorWidth() - charWithinAuthor);
+ assert(leftInAuthor > 0, "_authorSlicer: should have leftInAuthor > 0");
+ var toTake = min(leftInAuthor, leftToTake);
+ assert(toTake > 0, "_authorSlicer: should have toTake > 0");
+ builderOut.appendNewText(textLeft.substring(0, toTake), curAuthor());
+ forwardInAuthor(toTake);
+ leftToTake -= toTake;
+ textLeft = textLeft.substring(toTake);
+ }
+ assert(charWithinAuthor <= curAuthorWidth(), "_authorSlicer: past end of author");
+ if (charWithinAuthor == curAuthorWidth()) {
+ nextAuthor();
+ }
+ }
+ },
+ setBuilder: function(builder) {
+ builderOut = builder;
+ }
+ };
+ }
+
+ function _makeSlicer(C, output) {
+ // C: Changeset, output: builder from _makeBuilder
+ // C is considered immutable, won't change or be changed
+
+ // OOP style: state in environment
+ var charIndex = 0; // 0 <= charIndex <= C.newLen(); maximum value iff atEnd
+ var stripIndex = 0; // 0 <= stripIndex <= C.numStrips(); maximum value iff atEnd
+ var charWithinStrip = 0; // 0 <= charWithinStrip < curStripWidth()
+ var atEnd = false;
+
+ var authorSlicer;
+ if (C.authors) {
+ authorSlicer = _makeAuthorSlicer(C.authors, output);
+ }
+
+ var ptr = 3;
+ function curStartIndex() { return C[ptr]; }
+ function curNumTaken() { return C[ptr+1]; }
+ function curNewText() { return C[ptr+2]; }
+ function curStripWidth() { return curNumTaken() + curNewText().length; }
+ function assertNotAtEnd() { assert(! atEnd, "_slicer: can't move past changeset end"); }
+ function forwardInStrip(numChars) {
+ charWithinStrip += numChars;
+ charIndex += numChars;
+ }
+ function nextStrip() {
+ assertNotAtEnd();
+ assert(charWithinStrip == curStripWidth(), "_slicer: not at strip end");
+ charWithinStrip = 0;
+ stripIndex++;
+ ptr += 3;
+ if (stripIndex == C.numStrips()) {
+ atEnd = true;
+ }
+ }
+ function curNumNewCharsInRange(start, end) {
+ // takes two indices into the current strip's combined "taken" and "new"
+ // chars, and returns how many "new" chars are included in the range
+ assert(start <= end, "_slicer: curNumNewCharsInRange given out-of-order indices");
+ var nt = curNumTaken();
+ var nn = curNewText().length;
+ var s = nt;
+ var e = nt+nn;
+ if (s < start) s = start;
+ if (e > end) e = end;
+ if (e < s) return 0;
+ return e-s;
+ }
+
+ var self;
+ return self = {
+ skipChars: function (n) {
+ assert(n >= 0, "_slicer: can't skip negative n");
+ if (n == 0) return;
+ assertNotAtEnd();
+
+ var leftToSkip = n;
+ while (leftToSkip > 0) {
+ var leftInStrip = curStripWidth() - charWithinStrip;
+ if (leftToSkip >= leftInStrip) {
+ forwardInStrip(leftInStrip);
+
+ if (authorSlicer)
+ authorSlicer.skipChars(curNumNewCharsInRange(charWithinStrip,
+ charWithinStrip + leftInStrip));
+
+ leftToSkip -= leftInStrip;
+ nextStrip();
+ }
+ else {
+ if (authorSlicer)
+ authorSlicer.skipChars(curNumNewCharsInRange(charWithinStrip,
+ charWithinStrip + leftToSkip));
+
+ forwardInStrip(leftToSkip);
+ leftToSkip = 0;
+ }
+ }
+ },
+ takeChars: function (n) {
+ assert(n >= 0, "_slicer: can't take negative n");
+ if (n == 0) return;
+ assertNotAtEnd();
+
+ var leftToTake = n;
+ while (leftToTake > 0) {
+ if (curNumTaken() > 0 && charWithinStrip < curNumTaken()) {
+ // at least one char to take from current strip's numTaken
+ var leftInTaken = (curNumTaken() - charWithinStrip);
+ assert(leftInTaken > 0, "_slicer: should have leftInTaken > 0");
+ var toTake = min(leftInTaken, leftToTake);
+ assert(toTake > 0, "_slicer: should have toTake > 0");
+ output.appendOldText(curStartIndex() + charWithinStrip, toTake);
+ forwardInStrip(toTake);
+ leftToTake -= toTake;
+ }
+ if (leftToTake > 0 && curNewText().length > 0 && charWithinStrip >= curNumTaken() &&
+ charWithinStrip < curStripWidth()) {
+ // at least one char to take from current strip's newText
+ var leftInNewText = (curStripWidth() - charWithinStrip);
+ assert(leftInNewText > 0, "_slicer: should have leftInNewText > 0");
+ var toTake = min(leftInNewText, leftToTake);
+ assert(toTake > 0, "_slicer: should have toTake > 0");
+ var newText = curNewText().substr(charWithinStrip - curNumTaken(), toTake);
+ if (authorSlicer) {
+ authorSlicer.takeChars(newText.length, newText);
+ }
+ else {
+ output.appendNewText(newText);
+ }
+ forwardInStrip(toTake);
+ leftToTake -= toTake;
+ }
+ assert(charWithinStrip <= curStripWidth(), "_slicer: past end of strip");
+ if (charWithinStrip == curStripWidth()) {
+ nextStrip();
+ }
+ }
+ },
+ skipTo: function(n) {
+ self.skipChars(n - charIndex);
+ }
+ };
+ }
+
+ array.slicer = function(outputBuilder) {
+ return _makeSlicer(this, outputBuilder);
+ }
+
+ array.compose = function(next) {
+ assert(next.oldLen() == this.newLen(), "mismatched composition");
+
+ var builder = _makeBuilder(this.oldLen(), !!(this.authors || next.authors));
+ var slicer = _makeSlicer(this, builder);
+
+ var authorSlicer;
+ if (next.authors) {
+ authorSlicer = _makeAuthorSlicer(next.authors, builder);
+ }
+
+ next.eachStrip(function(s, t, n) {
+ slicer.skipTo(s);
+ slicer.takeChars(t);
+ if (authorSlicer) {
+ authorSlicer.takeChars(n.length, n);
+ }
+ else {
+ builder.appendNewText(n);
+ }
+ }, this);
+
+ return builder.toChangeset();
+ };
+
+ array.traverser = function() {
+ return _makeTraverser(this);
+ }
+
+ function _makeTraverser(C) {
+ var s = C[3], t = C[4], n = C[5];
+ var nextIndex = 6;
+ var indexIntoNewText = 0;
+
+ var authorSlicer;
+ if (C.authors) {
+ authorSlicer = _makeAuthorSlicer(C.authors, null);
+ }
+
+ function advanceIfPossible() {
+ if (t == 0 && n == "" && nextIndex < C.length) {
+ s = C[nextIndex];
+ t = C[nextIndex+1];
+ n = C[nextIndex+2];
+ nextIndex += 3;
+ }
+ }
+
+ var self;
+ return self = {
+ numTakenChars: function() {
+ // if starts with taken characters, then how many, else 0
+ return (t > 0) ? t : 0;
+ },
+ numNewChars: function() {
+ // if starts with new characters, then how many, else 0
+ return (t == 0 && n.length > 0) ? n.length : 0;
+ },
+ takenCharsStart: function() {
+ return (self.numTakenChars() > 0) ? s : 0;
+ },
+ hasMore: function() {
+ return self.numTakenChars() > 0 || self.numNewChars() > 0;
+ },
+ curIndex: function() {
+ return indexIntoNewText;
+ },
+ consumeTakenChars: function (x) {
+ assert(self.numTakenChars() > 0, "_traverser: no taken chars");
+ assert(x >= 0 && x <= self.numTakenChars(), "_traverser: bad number of taken chars");
+ if (x == 0) return;
+ if (t == x) { s = 0; t = 0; }
+ else { s += x; t -= x; }
+ indexIntoNewText += x;
+ advanceIfPossible();
+ },
+ consumeNewChars: function(x) {
+ return self.appendNewChars(x, null);
+ },
+ appendNewChars: function(x, builder) {
+ assert(self.numNewChars() > 0, "_traverser: no new chars");
+ assert(x >= 0 && x <= self.numNewChars(), "_traverser: bad number of new chars");
+ if (x == 0) return "";
+ var str = n.substring(0, x);
+ n = n.substring(x);
+ indexIntoNewText += x;
+ advanceIfPossible();
+
+ if (builder) {
+ if (authorSlicer) {
+ authorSlicer.setBuilder(builder);
+ authorSlicer.takeChars(x, str);
+ }
+ else {
+ builder.appendNewText(str);
+ }
+ }
+ else {
+ if (authorSlicer) authorSlicer.skipChars(x);
+ return str;
+ }
+ },
+ consumeAvailableTakenChars: function() {
+ return self.consumeTakenChars(self.numTakenChars());
+ },
+ consumeAvailableNewChars: function() {
+ return self.consumeNewChars(self.numNewChars());
+ },
+ appendAvailableNewChars: function(builder) {
+ return self.appendNewChars(self.numNewChars(), builder);
+ }
+ };
+ }
+
+ array.follow = function(prev, reverseInsertOrder) {
+ // prev: Changeset, reverseInsertOrder: boolean
+
+ // A.compose(B.follow(A)) is the merging of Changesets A and B, which operate on the same old text.
+ // It is always the same as B.compose(A.follow(B, true)).
+
+ assert(prev.oldLen() == this.oldLen(), "mismatched follow: "+prev.oldLen()+"/"+this.oldLen());
+ var builder = _makeBuilder(prev.newLen(), !! this.authors);
+ var a = _makeTraverser(prev);
+ var b = _makeTraverser(this);
+ while (a.hasMore() || b.hasMore()) {
+ if (a.numNewChars() > 0 && ! reverseInsertOrder) {
+ builder.appendOldText(a.curIndex(), a.numNewChars());
+ a.consumeAvailableNewChars();
+ }
+ else if (b.numNewChars() > 0) {
+ b.appendAvailableNewChars(builder);
+ }
+ else if (a.numNewChars() > 0 && reverseInsertOrder) {
+ builder.appendOldText(a.curIndex(), a.numNewChars());
+ a.consumeAvailableNewChars();
+ }
+ else if (! b.hasMore()) a.consumeAvailableTakenChars();
+ else if (! a.hasMore()) b.consumeAvailableTakenChars();
+ else {
+ var x = a.takenCharsStart();
+ var y = b.takenCharsStart();
+ if (x < y) a.consumeTakenChars(min(a.numTakenChars(), y-x));
+ else if (y < x) b.consumeTakenChars(min(b.numTakenChars(), x-y));
+ else {
+ var takenByBoth = min(a.numTakenChars(), b.numTakenChars());
+ builder.appendOldText(a.curIndex(), takenByBoth);
+ a.consumeTakenChars(takenByBoth);
+ b.consumeTakenChars(takenByBoth);
+ }
+ }
+ }
+ return builder.toChangeset();
+ }
+
+ array.encodeToString = function(asBinary) {
+ var stringDataArray = [];
+ var numsArray = [];
+ if (! asBinary) numsArray.push(this[0]);
+ numsArray.push(this[1], this[2]);
+ this.eachStrip(function(s, t, n) {
+ numsArray.push(s, t, n.length);
+ stringDataArray.push(n);
+ }, this);
+ if (! asBinary) {
+ return numsArray.join(',')+'|'+stringDataArray.join('');
+ }
+ else {
+ return "A" + Changeset.numberArrayToString(numsArray)
+ +escapeCrazyUnicode(stringDataArray.join(''));
+ }
+ }
+
+ function escapeCrazyUnicode(str) {
+ return str.replace(/\\/g, '\\\\').replace(/[\ud800-\udfff]/g, function (c) {
+ return "\\u"+("0000"+c.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+ array.applyToAttributedText = Changeset.applyToAttributedText;
+
+ function splicesFromChanges(c) {
+ var splices = [];
+ // get a list of splices, [startChar, endChar, newText]
+ var traverser = c.traverser();
+ var oldTextLength = c.oldLen();
+ var indexIntoOldText = 0;
+ while (traverser.hasMore() || indexIntoOldText < oldTextLength) {
+ var newText = "";
+ var startChar = indexIntoOldText;
+ var endChar = indexIntoOldText;
+ if (traverser.numNewChars() > 0) {
+ newText = traverser.consumeAvailableNewChars();
+ }
+ if (traverser.hasMore()) {
+ endChar = traverser.takenCharsStart();
+ indexIntoOldText = endChar + traverser.numTakenChars();
+ traverser.consumeAvailableTakenChars();
+ }
+ else {
+ endChar = oldTextLength;
+ indexIntoOldText = endChar;
+ }
+ if (endChar != startChar || newText.length > 0) {
+ splices.push([startChar, endChar, newText]);
+ }
+ }
+ return splices;
+ }
+
+ array.toSplices = function() {
+ return splicesFromChanges(this);
+ }
+
+ array.characterRangeFollowThis = function(selStartChar, selEndChar, insertionsAfter) {
+ var changeset = this;
+ // represent the selection as a changeset that replaces the selection with some finite string.
+ // Because insertions indicate intention, it doesn't matter what this string is, and even
+ // if the selectionChangeset is made to "follow" other changes it will still be the only
+ // insertion.
+ var selectionChangeset =
+ Changeset(changeset.oldLen()).builder().appendOldText(0, selStartChar).appendNewText(
+ "X").appendOldText(selEndChar, changeset.oldLen() - selEndChar).toChangeset();
+ var newSelectionChangeset = selectionChangeset.follow(changeset, insertionsAfter);
+ var selectionSplices = newSelectionChangeset.toSplices();
+ function includeChar(i) {
+ if (! includeChar.calledYet) {
+ selStartChar = i;
+ selEndChar = i;
+ includeChar.calledYet = true;
+ }
+ else {
+ if (i < selStartChar) selStartChar = i;
+ if (i > selEndChar) selEndChar = i;
+ }
+ }
+ for(var i=0; i<selectionSplices.length; i++) {
+ var s = selectionSplices[i];
+ includeChar(s[0]);
+ includeChar(s[1]);
+ }
+ return [selStartChar, selEndChar];
+ }
+
+ return array;
+}
+
+Changeset.MAGIC = "Changeset";
+Changeset.makeSplice = function(oldLength, spliceStart, numRemoved, stringInserted) {
+ oldLength = (oldLength || 0);
+ spliceStart = (spliceStart || 0);
+ numRemoved = (numRemoved || 0);
+ stringInserted = String(stringInserted || "");
+
+ var builder = Changeset(oldLength).builder();
+ builder.appendOldText(0, spliceStart);
+ builder.appendNewText(stringInserted);
+ builder.appendOldText(spliceStart + numRemoved, oldLength - numRemoved - spliceStart);
+ return builder.toChangeset();
+};
+Changeset.identity = function(len) {
+ return Changeset(len).builder().appendOldText(0, len).toChangeset();
+};
+Changeset.decodeFromString = function(str) {
+ function error(msg) { var e = new Error(msg); e.easysync = true; throw e; }
+ function toHex(str) {
+ var a = [];
+ a.push("length["+str.length+"]:");
+ var TRUNC=20;
+ for(var i=0;i<str.substring(0,TRUNC).length;i++) {
+ a.push(("000"+str.charCodeAt(i).toString(16)).slice(-4));
+ }
+ if (str.length > TRUNC) a.push("...");
+ return a.join(' ');
+ }
+ function unescapeCrazyUnicode(str) {
+ return str.replace(/\\(u....|\\)/g, function(seq) {
+ if (seq == "\\\\") return "\\";
+ return String.fromCharCode(Number("0x"+seq.substring(2)));
+ });
+ }
+
+ var numData, stringData;
+ var binary = false;
+ var typ = str.charAt(0);
+ if (typ == "B" || typ == "A") {
+ var result = Changeset.numberArrayFromString(str, 1);
+ numData = result[0];
+ stringData = result[1];
+ if (typ == "A") {
+ stringData = unescapeCrazyUnicode(stringData);
+ }
+ binary = true;
+ }
+ else if (typ == "C") {
+ var barPosition = str.indexOf('|');
+ numData = str.substring(0, barPosition).split(',');
+ stringData = str.substring(barPosition+1);
+ }
+ else {
+ error("Not a changeset: "+toHex(str));
+ }
+ var stringDataOffset = 0;
+ var array = [];
+ var ptr;
+ if (binary) {
+ array.push("Changeset", numData[0], numData[1]);
+ var ptr = 2;
+ }
+ else {
+ array.push(numData[0], Number(numData[1]), Number(numData[2]));
+ var ptr = 3;
+ }
+ while (ptr < numData.length) {
+ array.push(Number(numData[ptr++]), Number(numData[ptr++]));
+ var newTextLength = Number(numData[ptr++]);
+ array.push(stringData.substr(stringDataOffset, newTextLength));
+ stringDataOffset += newTextLength;
+ }
+ if (stringDataOffset != stringData.length) {
+ error("Extra character data beyond end of encoded string ("+toHex(str)+")");
+ }
+ return Changeset(array);
+};
+
+Changeset.numberArrayToString = function(nums) {
+ var array = [];
+ function writeNum(n) {
+ // does not support negative numbers
+ var twentyEightBit = (n & 0xfffffff);
+ if (twentyEightBit <= 0x7fff) {
+ array.push(String.fromCharCode(twentyEightBit));
+ }
+ else {
+ array.push(String.fromCharCode(0xa000 | (twentyEightBit >> 15),
+ twentyEightBit & 0x7fff));
+ }
+ }
+ writeNum(nums.length);
+ var len = nums.length;
+ for(var i=0;i<len;i++) {
+ writeNum(nums[i]);
+ }
+ return array.join('');
+};
+
+Changeset.numberArrayFromString = function(str, startIndex) {
+ // returns [numberArray, remainingString]
+ var nums = [];
+ var strIndex = (startIndex || 0);
+ function readNum() {
+ var n = str.charCodeAt(strIndex++);
+ if (n > 0x7fff) {
+ if (n >= 0xa000) {
+ n = (((n & 0x1fff) << 15) | str.charCodeAt(strIndex++));
+ }
+ else {
+ // legacy format
+ n = (((n & 0x1fff) << 16) | str.charCodeAt(strIndex++));
+ }
+ }
+ return n;
+ }
+ var len = readNum();
+ for(var i=0;i<len;i++) {
+ nums.push(readNum());
+ }
+ return [nums, str.substring(strIndex)];
+};
+
+(function() {
+ function repeatString(str, times) {
+ if (times <= 0) return "";
+ var s = repeatString(str, times >> 1);
+ s += s;
+ if (times & 1) s += str;
+ return s;
+ }
+ function chr(n) { return String.fromCharCode(n+48); }
+ function ord(c) { return c.charCodeAt(0)-48; }
+ function runMatcher(c) {
+ // Takes "A" and returns /\u0041+/g .
+ // Avoid creating new objects unnecessarily by caching matchers
+ // as properties of this function.
+ var re = runMatcher[c];
+ if (re) return re;
+ re = runMatcher[c] = new RegExp("\\u"+("0000"+c.charCodeAt(0).toString(16)).slice(-4)+"+", 'g');
+ return re;
+ }
+ function runLength(str, idx, c) {
+ var re = runMatcher(c);
+ re.lastIndex = idx;
+ var result = re.exec(str);
+ if (result && result[0]) {
+ return result[0].length;
+ }
+ return 0;
+ }
+
+ // emptyObj may be a StorableObject
+ Changeset.initAttributedText = function(emptyObj, initialString, initialAuthor) {
+ var obj = emptyObj;
+ obj.authorMap = { 1: (initialAuthor || '') };
+ obj.text = (initialString || '');
+ obj.attribs = repeatString(chr(1), obj.text.length);
+ return obj;
+ };
+ Changeset.gcAttributedText = function(atObj) {
+ // "garbage collect" the list of authors
+ var removedAuthors = [];
+ for(var a in atObj.authorMap) {
+ if (atObj.attribs.indexOf(chr(Number(a))) < 0) {
+ removedAuthors.push(atObj.authorMap[a]);
+ delete atObj.authorMap[a];
+ }
+ }
+ return removedAuthors;
+ };
+ Changeset.cloneAttributedText = function(emptyObj, atObj) {
+ var obj = emptyObj;
+ obj.text = atObj.text; // string
+ if (atObj.attribs) obj.attribs = atObj.attribs; // string
+ if (atObj.attribs_c) obj.attribs_c = atObj.attribs_c; // string
+ obj.authorMap = {};
+ for(var a in atObj.authorMap) {
+ obj.authorMap[a] = atObj.authorMap[a];
+ }
+ return obj;
+ };
+ Changeset.applyToAttributedText = function(atObj, C) {
+ C = (C || this);
+ var oldText = atObj.text;
+ var oldAttribs = atObj.attribs;
+ Changeset._assert(C.isChangeset, "applyToAttributedText: 'this' is not a changeset");
+ Changeset._assert(oldText.length == C.oldLen(),
+ "applyToAttributedText: mismatch "+oldText.length+" / "+C.oldLen());
+ var textBuf = [];
+ var attribsBuf = [];
+ var authorMap = atObj.authorMap;
+ function authorId(author) {
+ for(var a in authorMap) {
+ if (authorMap[Number(a)] === author) {
+ return Number(a);
+ }
+ }
+ for(var i=1;i<=60000;i++) {
+ // don't use "in" because it's currently broken on StorableObjects
+ if (authorMap[i] === undefined) {
+ authorMap[i] = author;
+ return i;
+ }
+ }
+ }
+ var myBuilder = { appendNewText: function(txt, author) {
+ // object that acts as a "builder" in that it receives requests from
+ // authorSlicer to append text attributed to different authors
+ attribsBuf.push(repeatString(chr(authorId(author)), txt.length));
+ } };
+ var authorSlicer;
+ if (C.authors) {
+ authorSlicer = C.authorSlicer(myBuilder);
+ }
+ C.eachStrip(function (s, t, n) {
+ textBuf.push(oldText.substr(s, t), n);
+ attribsBuf.push(oldAttribs.substr(s, t));
+ if (authorSlicer) {
+ authorSlicer.takeChars(n.length, n);
+ }
+ else {
+ myBuilder.appendNewText(n, '');
+ }
+ });
+ atObj.text = textBuf.join('');
+ atObj.attribs = attribsBuf.join('');
+ return atObj;
+ };
+ Changeset.getAttributedTextCharAuthor = function(atObj, idx) {
+ return atObj.authorMap[ord(atObj.attribs.charAt(idx))];
+ };
+ Changeset.getAttributedTextCharRunLength = function(atObj, idx) {
+ var c = atObj.attribs.charAt(idx);
+ return runLength(atObj.attribs, idx, c);
+ };
+ Changeset.eachAuthorInAttributedText = function(atObj, func) {
+ // call func(author, authorNum)
+ for(var a in atObj.authorMap) {
+ if (func(atObj.authorMap[a], Number(a))) break;
+ }
+ };
+ Changeset.getAttributedTextAuthorByNum = function(atObj, n) {
+ return atObj.authorMap[n];
+ };
+ // Compressed attributed text can be cloned, but nothing else until uncompressed!!
+ Changeset.compressAttributedText = function(atObj) {
+ // idempotent, mutates the object, returns it
+ if (atObj.attribs) {
+ atObj.attribs_c = atObj.attribs.replace(/([\s\S])\1{0,63}/g, function(run) {
+ return run.charAt(0)+chr(run.length);;
+ });
+ delete atObj.attribs;
+ }
+ return atObj;
+ };
+ Changeset.decompressAttributedText = function(atObj) {
+ // idempotent, mutates the object, returns it
+ if (atObj.attribs_c) {
+ atObj.attribs = atObj.attribs_c.replace(/[\s\S][\s\S]/g, function(run) {
+ return repeatString(run.charAt(0), ord(run.charAt(1)));
+ });
+ delete atObj.attribs_c;
+ }
+ return atObj;
+ };
+})();
diff --git a/infrastructure/ace/www/easysync2.js b/infrastructure/ace/www/easysync2.js
new file mode 100644
index 0000000..efc5b99
--- /dev/null
+++ b/infrastructure/ace/www/easysync2.js
@@ -0,0 +1,1968 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.easysync2
+// %APPJET%: jimport("com.etherpad.Easysync2Support");
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//var _opt = (this.Easysync2Support || null);
+var _opt = null; // disable optimization for now
+
+function AttribPool() {
+ var p = {};
+ p.numToAttrib = {}; // e.g. {0: ['foo','bar']}
+ p.attribToNum = {}; // e.g. {'foo,bar': 0}
+ p.nextNum = 0;
+
+ p.putAttrib = function(attrib, dontAddIfAbsent) {
+ var str = String(attrib);
+ if (str in p.attribToNum) {
+ return p.attribToNum[str];
+ }
+ if (dontAddIfAbsent) {
+ return -1;
+ }
+ var num = p.nextNum++;
+ p.attribToNum[str] = num;
+ p.numToAttrib[num] = [String(attrib[0]||''),
+ String(attrib[1]||'')];
+ return num;
+ };
+
+ p.getAttrib = function(num) {
+ var pair = p.numToAttrib[num];
+ if (! pair) return pair;
+ return [pair[0], pair[1]]; // return a mutable copy
+ };
+
+ p.getAttribKey = function(num) {
+ var pair = p.numToAttrib[num];
+ if (! pair) return '';
+ return pair[0];
+ };
+
+ p.getAttribValue = function(num) {
+ var pair = p.numToAttrib[num];
+ if (! pair) return '';
+ return pair[1];
+ };
+
+ p.eachAttrib = function(func) {
+ for(var n in p.numToAttrib) {
+ var pair = p.numToAttrib[n];
+ func(pair[0], pair[1]);
+ }
+ };
+
+ p.toJsonable = function() {
+ return {numToAttrib: p.numToAttrib, nextNum: p.nextNum};
+ };
+
+ p.fromJsonable = function(obj) {
+ p.numToAttrib = obj.numToAttrib;
+ p.nextNum = obj.nextNum;
+ p.attribToNum = {};
+ for(var n in p.numToAttrib) {
+ p.attribToNum[String(p.numToAttrib[n])] = Number(n);
+ }
+ return p;
+ };
+
+ return p;
+}
+
+var Changeset = {};
+
+Changeset.error = function error(msg) { var e = new Error(msg); e.easysync = true; throw e; };
+Changeset.assert = function assert(b, msgParts) {
+ if (! b) {
+ var msg = Array.prototype.slice.call(arguments, 1).join('');
+ Changeset.error("Changeset: "+msg);
+ }
+};
+
+Changeset.parseNum = function(str) { return parseInt(str, 36); };
+Changeset.numToString = function(num) { return num.toString(36).toLowerCase(); };
+Changeset.toBaseTen = function(cs) {
+ var dollarIndex = cs.indexOf('$');
+ var beforeDollar = cs.substring(0, dollarIndex);
+ var fromDollar = cs.substring(dollarIndex);
+ return beforeDollar.replace(/[0-9a-z]+/g, function(s) {
+ return String(Changeset.parseNum(s)); }) + fromDollar;
+};
+
+Changeset.oldLen = function(cs) {
+ return Changeset.unpack(cs).oldLen;
+};
+Changeset.newLen = function(cs) {
+ return Changeset.unpack(cs).newLen;
+};
+
+Changeset.opIterator = function(opsStr, optStartIndex) {
+ //print(opsStr);
+ var regex = /((?:\*[0-9a-z]+)*)(?:\|([0-9a-z]+))?([-+=])([0-9a-z]+)|\?|/g;
+ var startIndex = (optStartIndex || 0);
+ var curIndex = startIndex;
+ var prevIndex = curIndex;
+ function nextRegexMatch() {
+ prevIndex = curIndex;
+ var result;
+ if (_opt) {
+ result = _opt.nextOpInString(opsStr, curIndex);
+ if (result) {
+ if (result.opcode() == '?') {
+ Changeset.error("Hit error opcode in op stream");
+ }
+ curIndex = result.lastIndex();
+ }
+ }
+ else {
+ regex.lastIndex = curIndex;
+ result = regex.exec(opsStr);
+ curIndex = regex.lastIndex;
+ if (result[0] == '?') {
+ Changeset.error("Hit error opcode in op stream");
+ }
+ }
+ return result;
+ }
+ var regexResult = nextRegexMatch();
+ var obj = Changeset.newOp();
+ function next(optObj) {
+ var op = (optObj || obj);
+ if (_opt && regexResult) {
+ op.attribs = regexResult.attribs();
+ op.lines = regexResult.lines();
+ op.chars = regexResult.chars();
+ op.opcode = regexResult.opcode();
+ regexResult = nextRegexMatch();
+ }
+ else if ((! _opt) && regexResult[0]) {
+ op.attribs = regexResult[1];
+ op.lines = Changeset.parseNum(regexResult[2] || 0);
+ op.opcode = regexResult[3];
+ op.chars = Changeset.parseNum(regexResult[4]);
+ regexResult = nextRegexMatch();
+ }
+ else {
+ Changeset.clearOp(op);
+ }
+ return op;
+ }
+ function hasNext() { return !! (_opt ? regexResult : regexResult[0]); }
+ function lastIndex() { return prevIndex; }
+ return {next: next, hasNext: hasNext, lastIndex: lastIndex};
+};
+
+Changeset.clearOp = function(op) {
+ op.opcode = '';
+ op.chars = 0;
+ op.lines = 0;
+ op.attribs = '';
+};
+Changeset.newOp = function(optOpcode) {
+ return {opcode:(optOpcode || ''), chars:0, lines:0, attribs:''};
+};
+Changeset.cloneOp = function(op) {
+ return {opcode: op.opcode, chars: op.chars, lines: op.lines, attribs: op.attribs};
+};
+Changeset.copyOp = function(op1, op2) {
+ op2.opcode = op1.opcode;
+ op2.chars = op1.chars;
+ op2.lines = op1.lines;
+ op2.attribs = op1.attribs;
+};
+Changeset.opString = function(op) {
+ // just for debugging
+ if (! op.opcode) return 'null';
+ var assem = Changeset.opAssembler();
+ assem.append(op);
+ return assem.toString();
+};
+Changeset.stringOp = function(str) {
+ // just for debugging
+ return Changeset.opIterator(str).next();
+};
+
+Changeset.checkRep = function(cs) {
+ // doesn't check things that require access to attrib pool (e.g. attribute order)
+ // or original string (e.g. newline positions)
+ var unpacked = Changeset.unpack(cs);
+ var oldLen = unpacked.oldLen;
+ var newLen = unpacked.newLen;
+ var ops = unpacked.ops;
+ var charBank = unpacked.charBank;
+
+ var assem = Changeset.smartOpAssembler();
+ var oldPos = 0;
+ var calcNewLen = 0;
+ var numInserted = 0;
+ var iter = Changeset.opIterator(ops);
+ while (iter.hasNext()) {
+ var o = iter.next();
+ switch (o.opcode) {
+ case '=': oldPos += o.chars; calcNewLen += o.chars; break;
+ case '-': oldPos += o.chars; Changeset.assert(oldPos < oldLen, oldPos," >= ",oldLen," in ",cs); break;
+ case '+': {
+ calcNewLen += o.chars; numInserted += o.chars;
+ Changeset.assert(calcNewLen < newLen, calcNewLen," >= ",newLen," in ",cs);
+ break;
+ }
+ }
+ assem.append(o);
+ }
+
+ calcNewLen += oldLen - oldPos;
+ charBank = charBank.substring(0, numInserted);
+ while (charBank.length < numInserted) {
+ charBank += "?";
+ }
+
+ assem.endDocument();
+ var normalized = Changeset.pack(oldLen, calcNewLen, assem.toString(), charBank);
+ Changeset.assert(normalized == cs, normalized,' != ',cs);
+
+ return cs;
+}
+
+Changeset.smartOpAssembler = function() {
+ // Like opAssembler but able to produce conforming changesets
+ // from slightly looser input, at the cost of speed.
+ // Specifically:
+ // - merges consecutive operations that can be merged
+ // - strips final "="
+ // - ignores 0-length changes
+ // - reorders consecutive + and - (which margingOpAssembler doesn't do)
+
+ var minusAssem = Changeset.mergingOpAssembler();
+ var plusAssem = Changeset.mergingOpAssembler();
+ var keepAssem = Changeset.mergingOpAssembler();
+ var assem = Changeset.stringAssembler();
+ var lastOpcode = '';
+ var lengthChange = 0;
+
+ function flushKeeps() {
+ assem.append(keepAssem.toString());
+ keepAssem.clear();
+ }
+
+ function flushPlusMinus() {
+ assem.append(minusAssem.toString());
+ minusAssem.clear();
+ assem.append(plusAssem.toString());
+ plusAssem.clear();
+ }
+
+ function append(op) {
+ if (! op.opcode) return;
+ if (! op.chars) return;
+
+ if (op.opcode == '-') {
+ if (lastOpcode == '=') {
+ flushKeeps();
+ }
+ minusAssem.append(op);
+ lengthChange -= op.chars;
+ }
+ else if (op.opcode == '+') {
+ if (lastOpcode == '=') {
+ flushKeeps();
+ }
+ plusAssem.append(op);
+ lengthChange += op.chars;
+ }
+ else if (op.opcode == '=') {
+ if (lastOpcode != '=') {
+ flushPlusMinus();
+ }
+ keepAssem.append(op);
+ }
+ lastOpcode = op.opcode;
+ }
+
+ function appendOpWithText(opcode, text, attribs, pool) {
+ var op = Changeset.newOp(opcode);
+ op.attribs = Changeset.makeAttribsString(opcode, attribs, pool);
+ var lastNewlinePos = text.lastIndexOf('\n');
+ if (lastNewlinePos < 0) {
+ op.chars = text.length;
+ op.lines = 0;
+ append(op);
+ }
+ else {
+ op.chars = lastNewlinePos+1;
+ op.lines = text.match(/\n/g).length;
+ append(op);
+ op.chars = text.length - (lastNewlinePos+1);
+ op.lines = 0;
+ append(op);
+ }
+ }
+
+ function toString() {
+ flushPlusMinus();
+ flushKeeps();
+ return assem.toString();
+ }
+
+ function clear() {
+ minusAssem.clear();
+ plusAssem.clear();
+ keepAssem.clear();
+ assem.clear();
+ lengthChange = 0;
+ }
+
+ function endDocument() {
+ keepAssem.endDocument();
+ }
+
+ function getLengthChange() {
+ return lengthChange;
+ }
+
+ return {append: append, toString: toString, clear: clear, endDocument: endDocument,
+ appendOpWithText: appendOpWithText, getLengthChange: getLengthChange };
+};
+
+if (_opt) {
+ Changeset.mergingOpAssembler = function() {
+ var assem = _opt.mergingOpAssembler();
+
+ function append(op) {
+ assem.append(op.opcode, op.chars, op.lines, op.attribs);
+ }
+ function toString() {
+ return assem.toString();
+ }
+ function clear() {
+ assem.clear();
+ }
+ function endDocument() {
+ assem.endDocument();
+ }
+
+ return {append: append, toString: toString, clear: clear, endDocument: endDocument};
+ };
+}
+else {
+ Changeset.mergingOpAssembler = function() {
+ // This assembler can be used in production; it efficiently
+ // merges consecutive operations that are mergeable, ignores
+ // no-ops, and drops final pure "keeps". It does not re-order
+ // operations.
+ var assem = Changeset.opAssembler();
+ var bufOp = Changeset.newOp();
+
+ // If we get, for example, insertions [xxx\n,yyy], those don't merge,
+ // but if we get [xxx\n,yyy,zzz\n], that merges to [xxx\nyyyzzz\n].
+ // This variable stores the length of yyy and any other newline-less
+ // ops immediately after it.
+ var bufOpAdditionalCharsAfterNewline = 0;
+
+ function flush(isEndDocument) {
+ if (bufOp.opcode) {
+ if (isEndDocument && bufOp.opcode == '=' && ! bufOp.attribs) {
+ // final merged keep, leave it implicit
+ }
+ else {
+ assem.append(bufOp);
+ if (bufOpAdditionalCharsAfterNewline) {
+ bufOp.chars = bufOpAdditionalCharsAfterNewline;
+ bufOp.lines = 0;
+ assem.append(bufOp);
+ bufOpAdditionalCharsAfterNewline = 0;
+ }
+ }
+ bufOp.opcode = '';
+ }
+ }
+ function append(op) {
+ if (op.chars > 0) {
+ if (bufOp.opcode == op.opcode && bufOp.attribs == op.attribs) {
+ if (op.lines > 0) {
+ // bufOp and additional chars are all mergeable into a multi-line op
+ bufOp.chars += bufOpAdditionalCharsAfterNewline + op.chars;
+ bufOp.lines += op.lines;
+ bufOpAdditionalCharsAfterNewline = 0;
+ }
+ else if (bufOp.lines == 0) {
+ // both bufOp and op are in-line
+ bufOp.chars += op.chars;
+ }
+ else {
+ // append in-line text to multi-line bufOp
+ bufOpAdditionalCharsAfterNewline += op.chars;
+ }
+ }
+ else {
+ flush();
+ Changeset.copyOp(op, bufOp);
+ }
+ }
+ }
+ function endDocument() {
+ flush(true);
+ }
+ function toString() {
+ flush();
+ return assem.toString();
+ }
+ function clear() {
+ assem.clear();
+ Changeset.clearOp(bufOp);
+ }
+ return {append: append, toString: toString, clear: clear, endDocument: endDocument};
+ };
+}
+
+if (_opt) {
+ Changeset.opAssembler = function() {
+ var assem = _opt.opAssembler();
+ // this function allows op to be mutated later (doesn't keep a ref)
+ function append(op) {
+ assem.append(op.opcode, op.chars, op.lines, op.attribs);
+ }
+ function toString() {
+ return assem.toString();
+ }
+ function clear() {
+ assem.clear();
+ }
+ return {append: append, toString: toString, clear: clear};
+ };
+}
+else {
+ Changeset.opAssembler = function() {
+ var pieces = [];
+ // this function allows op to be mutated later (doesn't keep a ref)
+ function append(op) {
+ pieces.push(op.attribs);
+ if (op.lines) {
+ pieces.push('|', Changeset.numToString(op.lines));
+ }
+ pieces.push(op.opcode);
+ pieces.push(Changeset.numToString(op.chars));
+ }
+ function toString() {
+ return pieces.join('');
+ }
+ function clear() {
+ pieces.length = 0;
+ }
+ return {append: append, toString: toString, clear: clear};
+ };
+}
+
+Changeset.stringIterator = function(str) {
+ var curIndex = 0;
+ function assertRemaining(n) {
+ Changeset.assert(n <= remaining(), "!(",n," <= ",remaining(),")");
+ }
+ function take(n) {
+ assertRemaining(n);
+ var s = str.substr(curIndex, n);
+ curIndex += n;
+ return s;
+ }
+ function peek(n) {
+ assertRemaining(n);
+ var s = str.substr(curIndex, n);
+ return s;
+ }
+ function skip(n) {
+ assertRemaining(n);
+ curIndex += n;
+ }
+ function remaining() {
+ return str.length - curIndex;
+ }
+ return {take:take, skip:skip, remaining:remaining, peek:peek};
+};
+
+Changeset.stringAssembler = function() {
+ var pieces = [];
+ function append(x) {
+ pieces.push(String(x));
+ }
+ function toString() {
+ return pieces.join('');
+ }
+ return {append: append, toString: toString};
+};
+
+// "lines" need not be an array as long as it supports certain calls (lines_foo inside).
+Changeset.textLinesMutator = function(lines) {
+ // Mutates lines, an array of strings, in place.
+ // Mutation operations have the same constraints as changeset operations
+ // with respect to newlines, but not the other additional constraints
+ // (i.e. ins/del ordering, forbidden no-ops, non-mergeability, final newline).
+ // Can be used to mutate lists of strings where the last char of each string
+ // is not actually a newline, but for the purposes of N and L values,
+ // the caller should pretend it is, and for things to work right in that case, the input
+ // to insert() should be a single line with no newlines.
+
+ var curSplice = [0,0];
+ var inSplice = false;
+ // position in document after curSplice is applied:
+ var curLine = 0, curCol = 0;
+ // invariant: if (inSplice) then (curLine is in curSplice[0] + curSplice.length - {2,3}) &&
+ // curLine >= curSplice[0]
+ // invariant: if (inSplice && (curLine >= curSplice[0] + curSplice.length - 2)) then
+ // curCol == 0
+
+ function lines_applySplice(s) {
+ lines.splice.apply(lines, s);
+ }
+ function lines_toSource() {
+ return lines.toSource();
+ }
+ function lines_get(idx) {
+ if (lines.get) {
+ return lines.get(idx);
+ }
+ else {
+ return lines[idx];
+ }
+ }
+ // can be unimplemented if removeLines's return value not needed
+ function lines_slice(start, end) {
+ if (lines.slice) {
+ return lines.slice(start, end);
+ }
+ else {
+ return [];
+ }
+ }
+ function lines_length() {
+ if ((typeof lines.length) == "number") {
+ return lines.length;
+ }
+ else {
+ return lines.length();
+ }
+ }
+
+ function enterSplice() {
+ curSplice[0] = curLine;
+ curSplice[1] = 0;
+ if (curCol > 0) {
+ putCurLineInSplice();
+ }
+ inSplice = true;
+ }
+ function leaveSplice() {
+ lines_applySplice(curSplice);
+ curSplice.length = 2;
+ curSplice[0] = curSplice[1] = 0;
+ inSplice = false;
+ }
+ function isCurLineInSplice() {
+ return (curLine - curSplice[0] < (curSplice.length - 2));
+ }
+ function debugPrint(typ) {
+ print(typ+": "+curSplice.toSource()+" / "+curLine+","+curCol+" / "+lines_toSource());
+ }
+ function putCurLineInSplice() {
+ if (! isCurLineInSplice()) {
+ curSplice.push(lines_get(curSplice[0] + curSplice[1]));
+ curSplice[1]++;
+ }
+ return 2 + curLine - curSplice[0];
+ }
+
+ function skipLines(L, includeInSplice) {
+ if (L) {
+ if (includeInSplice) {
+ if (! inSplice) {
+ enterSplice();
+ }
+ for(var i=0;i<L;i++) {
+ curCol = 0;
+ putCurLineInSplice();
+ curLine++;
+ }
+ }
+ else {
+ if (inSplice) {
+ if (L > 1) {
+ leaveSplice();
+ }
+ else {
+ putCurLineInSplice();
+ }
+ }
+ curLine += L;
+ curCol = 0;
+ }
+ //print(inSplice+" / "+isCurLineInSplice()+" / "+curSplice[0]+" / "+curSplice[1]+" / "+lines.length);
+ /*if (inSplice && (! isCurLineInSplice()) && (curSplice[0] + curSplice[1] < lines.length)) {
+ print("BLAH");
+ putCurLineInSplice();
+ }*/ // tests case foo in remove(), which isn't otherwise covered in current impl
+ }
+ //debugPrint("skip");
+ }
+
+ function skip(N, L, includeInSplice) {
+ if (N) {
+ if (L) {
+ skipLines(L, includeInSplice);
+ }
+ else {
+ if (includeInSplice && ! inSplice) {
+ enterSplice();
+ }
+ if (inSplice) {
+ putCurLineInSplice();
+ }
+ curCol += N;
+ //debugPrint("skip");
+ }
+ }
+ }
+
+ function removeLines(L) {
+ var removed = '';
+ if (L) {
+ if (! inSplice) {
+ enterSplice();
+ }
+ function nextKLinesText(k) {
+ var m = curSplice[0] + curSplice[1];
+ return lines_slice(m, m+k).join('');
+ }
+ if (isCurLineInSplice()) {
+ //print(curCol);
+ if (curCol == 0) {
+ removed = curSplice[curSplice.length-1];
+ // print("FOO"); // case foo
+ curSplice.length--;
+ removed += nextKLinesText(L-1);
+ curSplice[1] += L-1;
+ }
+ else {
+ removed = nextKLinesText(L-1);
+ curSplice[1] += L-1;
+ var sline = curSplice.length - 1;
+ removed = curSplice[sline].substring(curCol) + removed;
+ curSplice[sline] = curSplice[sline].substring(0, curCol) +
+ lines_get(curSplice[0] + curSplice[1]);
+ curSplice[1] += 1;
+ }
+ }
+ else {
+ removed = nextKLinesText(L);
+ curSplice[1] += L;
+ }
+ //debugPrint("remove");
+ }
+ return removed;
+ }
+
+ function remove(N, L) {
+ var removed = '';
+ if (N) {
+ if (L) {
+ return removeLines(L);
+ }
+ else {
+ if (! inSplice) {
+ enterSplice();
+ }
+ var sline = putCurLineInSplice();
+ removed = curSplice[sline].substring(curCol, curCol+N);
+ curSplice[sline] = curSplice[sline].substring(0, curCol) +
+ curSplice[sline].substring(curCol+N);
+ //debugPrint("remove");
+ }
+ }
+ return removed;
+ }
+
+ function insert(text, L) {
+ if (text) {
+ if (! inSplice) {
+ enterSplice();
+ }
+ if (L) {
+ var newLines = Changeset.splitTextLines(text);
+ if (isCurLineInSplice()) {
+ //if (curCol == 0) {
+ //curSplice.length--;
+ //curSplice[1]--;
+ //Array.prototype.push.apply(curSplice, newLines);
+ //curLine += newLines.length;
+ //}
+ //else {
+ var sline = curSplice.length - 1;
+ var theLine = curSplice[sline];
+ var lineCol = curCol;
+ curSplice[sline] = theLine.substring(0, lineCol) + newLines[0];
+ curLine++;
+ newLines.splice(0, 1);
+ Array.prototype.push.apply(curSplice, newLines);
+ curLine += newLines.length;
+ curSplice.push(theLine.substring(lineCol));
+ curCol = 0;
+ //}
+ }
+ else {
+ Array.prototype.push.apply(curSplice, newLines);
+ curLine += newLines.length;
+ }
+ }
+ else {
+ var sline = putCurLineInSplice();
+ curSplice[sline] = curSplice[sline].substring(0, curCol) +
+ text + curSplice[sline].substring(curCol);
+ curCol += text.length;
+ }
+ //debugPrint("insert");
+ }
+ }
+
+ function hasMore() {
+ //print(lines.length+" / "+inSplice+" / "+(curSplice.length - 2)+" / "+curSplice[1]);
+ var docLines = lines_length();
+ if (inSplice) {
+ docLines += curSplice.length - 2 - curSplice[1];
+ }
+ return curLine < docLines;
+ }
+
+ function close() {
+ if (inSplice) {
+ leaveSplice();
+ }
+ //debugPrint("close");
+ }
+
+ var self = {skip:skip, remove:remove, insert:insert, close:close, hasMore:hasMore,
+ removeLines:removeLines, skipLines: skipLines};
+ return self;
+};
+
+Changeset.applyZip = function(in1, idx1, in2, idx2, func) {
+ var iter1 = Changeset.opIterator(in1, idx1);
+ var iter2 = Changeset.opIterator(in2, idx2);
+ var assem = Changeset.smartOpAssembler();
+ var op1 = Changeset.newOp();
+ var op2 = Changeset.newOp();
+ var opOut = Changeset.newOp();
+ while (op1.opcode || iter1.hasNext() || op2.opcode || iter2.hasNext()) {
+ if ((! op1.opcode) && iter1.hasNext()) iter1.next(op1);
+ if ((! op2.opcode) && iter2.hasNext()) iter2.next(op2);
+ func(op1, op2, opOut);
+ if (opOut.opcode) {
+ //print(opOut.toSource());
+ assem.append(opOut);
+ opOut.opcode = '';
+ }
+ }
+ assem.endDocument();
+ return assem.toString();
+};
+
+Changeset.unpack = function(cs) {
+ var headerRegex = /Z:([0-9a-z]+)([><])([0-9a-z]+)|/;
+ var headerMatch = headerRegex.exec(cs);
+ if ((! headerMatch) || (! headerMatch[0])) {
+ Changeset.error("Not a changeset: "+cs);
+ }
+ var oldLen = Changeset.parseNum(headerMatch[1]);
+ var changeSign = (headerMatch[2] == '>') ? 1 : -1;
+ var changeMag = Changeset.parseNum(headerMatch[3]);
+ var newLen = oldLen + changeSign*changeMag;
+ var opsStart = headerMatch[0].length;
+ var opsEnd = cs.indexOf("$");
+ if (opsEnd < 0) opsEnd = cs.length;
+ return {oldLen: oldLen, newLen: newLen, ops: cs.substring(opsStart, opsEnd),
+ charBank: cs.substring(opsEnd+1)};
+};
+
+Changeset.pack = function(oldLen, newLen, opsStr, bank) {
+ var lenDiff = newLen - oldLen;
+ var lenDiffStr = (lenDiff >= 0 ?
+ '>'+Changeset.numToString(lenDiff) :
+ '<'+Changeset.numToString(-lenDiff));
+ var a = [];
+ a.push('Z:', Changeset.numToString(oldLen), lenDiffStr, opsStr, '$', bank);
+ return a.join('');
+};
+
+Changeset.applyToText = function(cs, str) {
+ var unpacked = Changeset.unpack(cs);
+ Changeset.assert(str.length == unpacked.oldLen,
+ "mismatched apply: ",str.length," / ",unpacked.oldLen);
+ var csIter = Changeset.opIterator(unpacked.ops);
+ var bankIter = Changeset.stringIterator(unpacked.charBank);
+ var strIter = Changeset.stringIterator(str);
+ var assem = Changeset.stringAssembler();
+ while (csIter.hasNext()) {
+ var op = csIter.next();
+ switch(op.opcode) {
+ case '+': assem.append(bankIter.take(op.chars)); break;
+ case '-': strIter.skip(op.chars); break;
+ case '=': assem.append(strIter.take(op.chars)); break;
+ }
+ }
+ assem.append(strIter.take(strIter.remaining()));
+ return assem.toString();
+};
+
+Changeset.mutateTextLines = function(cs, lines) {
+ var unpacked = Changeset.unpack(cs);
+ var csIter = Changeset.opIterator(unpacked.ops);
+ var bankIter = Changeset.stringIterator(unpacked.charBank);
+ var mut = Changeset.textLinesMutator(lines);
+ while (csIter.hasNext()) {
+ var op = csIter.next();
+ switch(op.opcode) {
+ case '+': mut.insert(bankIter.take(op.chars), op.lines); break;
+ case '-': mut.remove(op.chars, op.lines); break;
+ case '=': mut.skip(op.chars, op.lines, (!! op.attribs)); break;
+ }
+ }
+ mut.close();
+};
+
+Changeset.composeAttributes = function(att1, att2, resultIsMutation, pool) {
+ // att1 and att2 are strings like "*3*f*1c", asMutation is a boolean.
+
+ // Sometimes attribute (key,value) pairs are treated as attribute presence
+ // information, while other times they are treated as operations that
+ // mutate a set of attributes, and this affects whether an empty value
+ // is a deletion or a change.
+ // Examples, of the form (att1Items, att2Items, resultIsMutation) -> result
+ // ([], [(bold, )], true) -> [(bold, )]
+ // ([], [(bold, )], false) -> []
+ // ([], [(bold, true)], true) -> [(bold, true)]
+ // ([], [(bold, true)], false) -> [(bold, true)]
+ // ([(bold, true)], [(bold, )], true) -> [(bold, )]
+ // ([(bold, true)], [(bold, )], false) -> []
+
+ // pool can be null if att2 has no attributes.
+
+ if ((! att1) && resultIsMutation) {
+ // In the case of a mutation (i.e. composing two changesets),
+ // an att2 composed with an empy att1 is just att2. If att1
+ // is part of an attribution string, then att2 may remove
+ // attributes that are already gone, so don't do this optimization.
+ return att2;
+ }
+ if (! att2) return att1;
+ var atts = [];
+ att1.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ atts.push(pool.getAttrib(Changeset.parseNum(a)));
+ return '';
+ });
+ att2.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ var pair = pool.getAttrib(Changeset.parseNum(a));
+ var found = false;
+ for(var i=0;i<atts.length;i++) {
+ var oldPair = atts[i];
+ if (oldPair[0] == pair[0]) {
+ if (pair[1] || resultIsMutation) {
+ oldPair[1] = pair[1];
+ }
+ else {
+ atts.splice(i, 1);
+ }
+ found = true;
+ break;
+ }
+ }
+ if ((! found) && (pair[1] || resultIsMutation)) {
+ atts.push(pair);
+ }
+ return '';
+ });
+ atts.sort();
+ var buf = Changeset.stringAssembler();
+ for(var i=0;i<atts.length;i++) {
+ buf.append('*');
+ buf.append(Changeset.numToString(pool.putAttrib(atts[i])));
+ }
+ //print(att1+" / "+att2+" / "+buf.toString());
+ return buf.toString();
+};
+
+Changeset._slicerZipperFunc = function(attOp, csOp, opOut, pool) {
+ // attOp is the op from the sequence that is being operated on, either an
+ // attribution string or the earlier of two changesets being composed.
+ // pool can be null if definitely not needed.
+
+ //print(csOp.toSource()+" "+attOp.toSource()+" "+opOut.toSource());
+ if (attOp.opcode == '-') {
+ Changeset.copyOp(attOp, opOut);
+ attOp.opcode = '';
+ }
+ else if (! attOp.opcode) {
+ Changeset.copyOp(csOp, opOut);
+ csOp.opcode = '';
+ }
+ else {
+ switch (csOp.opcode) {
+ case '-': {
+ if (csOp.chars <= attOp.chars) {
+ // delete or delete part
+ if (attOp.opcode == '=') {
+ opOut.opcode = '-';
+ opOut.chars = csOp.chars;
+ opOut.lines = csOp.lines;
+ opOut.attribs = '';
+ }
+ attOp.chars -= csOp.chars;
+ attOp.lines -= csOp.lines;
+ csOp.opcode = '';
+ if (! attOp.chars) {
+ attOp.opcode = '';
+ }
+ }
+ else {
+ // delete and keep going
+ if (attOp.opcode == '=') {
+ opOut.opcode = '-';
+ opOut.chars = attOp.chars;
+ opOut.lines = attOp.lines;
+ opOut.attribs = '';
+ }
+ csOp.chars -= attOp.chars;
+ csOp.lines -= attOp.lines;
+ attOp.opcode = '';
+ }
+ break;
+ }
+ case '+': {
+ // insert
+ Changeset.copyOp(csOp, opOut);
+ csOp.opcode = '';
+ break;
+ }
+ case '=': {
+ if (csOp.chars <= attOp.chars) {
+ // keep or keep part
+ opOut.opcode = attOp.opcode;
+ opOut.chars = csOp.chars;
+ opOut.lines = csOp.lines;
+ opOut.attribs = Changeset.composeAttributes(attOp.attribs, csOp.attribs,
+ attOp.opcode == '=', pool);
+ csOp.opcode = '';
+ attOp.chars -= csOp.chars;
+ attOp.lines -= csOp.lines;
+ if (! attOp.chars) {
+ attOp.opcode = '';
+ }
+ }
+ else {
+ // keep and keep going
+ opOut.opcode = attOp.opcode;
+ opOut.chars = attOp.chars;
+ opOut.lines = attOp.lines;
+ opOut.attribs = Changeset.composeAttributes(attOp.attribs, csOp.attribs,
+ attOp.opcode == '=', pool);
+ attOp.opcode = '';
+ csOp.chars -= attOp.chars;
+ csOp.lines -= attOp.lines;
+ }
+ break;
+ }
+ case '': {
+ Changeset.copyOp(attOp, opOut);
+ attOp.opcode = '';
+ break;
+ }
+ }
+ }
+};
+
+Changeset.applyToAttribution = function(cs, astr, pool) {
+ var unpacked = Changeset.unpack(cs);
+
+ return Changeset.applyZip(astr, 0, unpacked.ops, 0, function(op1, op2, opOut) {
+ return Changeset._slicerZipperFunc(op1, op2, opOut, pool);
+ });
+};
+
+/*Changeset.oneInsertedLineAtATimeOpIterator = function(opsStr, optStartIndex, charBank) {
+ var iter = Changeset.opIterator(opsStr, optStartIndex);
+ var bankIndex = 0;
+
+};*/
+
+Changeset.mutateAttributionLines = function(cs, lines, pool) {
+ //dmesg(cs);
+ //dmesg(lines.toSource()+" ->");
+
+ var unpacked = Changeset.unpack(cs);
+ var csIter = Changeset.opIterator(unpacked.ops);
+ var csBank = unpacked.charBank;
+ var csBankIndex = 0;
+ // treat the attribution lines as text lines, mutating a line at a time
+ var mut = Changeset.textLinesMutator(lines);
+
+ var lineIter = null;
+ function isNextMutOp() {
+ return (lineIter && lineIter.hasNext()) || mut.hasMore();
+ }
+ function nextMutOp(destOp) {
+ if ((!(lineIter && lineIter.hasNext())) && mut.hasMore()) {
+ var line = mut.removeLines(1);
+ lineIter = Changeset.opIterator(line);
+ }
+ if (lineIter && lineIter.hasNext()) {
+ lineIter.next(destOp);
+ }
+ else {
+ destOp.opcode = '';
+ }
+ }
+ var lineAssem = null;
+ function outputMutOp(op) {
+ //print("outputMutOp: "+op.toSource());
+ if (! lineAssem) {
+ lineAssem = Changeset.mergingOpAssembler();
+ }
+ lineAssem.append(op);
+ if (op.lines > 0) {
+ Changeset.assert(op.lines == 1, "Can't have op.lines of ",op.lines," in attribution lines");
+ // ship it to the mut
+ mut.insert(lineAssem.toString(), 1);
+ lineAssem = null;
+ }
+ }
+
+ var csOp = Changeset.newOp();
+ var attOp = Changeset.newOp();
+ var opOut = Changeset.newOp();
+ while (csOp.opcode || csIter.hasNext() || attOp.opcode || isNextMutOp()) {
+ if ((! csOp.opcode) && csIter.hasNext()) {
+ csIter.next(csOp);
+ }
+ //print(csOp.toSource()+" "+attOp.toSource()+" "+opOut.toSource());
+ //print(csOp.opcode+"/"+csOp.lines+"/"+csOp.attribs+"/"+lineAssem+"/"+lineIter+"/"+(lineIter?lineIter.hasNext():null));
+ //print("csOp: "+csOp.toSource());
+ if ((! csOp.opcode) && (! attOp.opcode) &&
+ (! lineAssem) && (! (lineIter && lineIter.hasNext()))) {
+ break; // done
+ }
+ else if (csOp.opcode == '=' && csOp.lines > 0 && (! csOp.attribs) && (! attOp.opcode) &&
+ (! lineAssem) && (! (lineIter && lineIter.hasNext()))) {
+ // skip multiple lines; this is what makes small changes not order of the document size
+ mut.skipLines(csOp.lines);
+ //print("skipped: "+csOp.lines);
+ csOp.opcode = '';
+ }
+ else if (csOp.opcode == '+') {
+ if (csOp.lines > 1) {
+ var firstLineLen = csBank.indexOf('\n', csBankIndex) + 1 - csBankIndex;
+ Changeset.copyOp(csOp, opOut);
+ csOp.chars -= firstLineLen;
+ csOp.lines--;
+ opOut.lines = 1;
+ opOut.chars = firstLineLen;
+ }
+ else {
+ Changeset.copyOp(csOp, opOut);
+ csOp.opcode = '';
+ }
+ outputMutOp(opOut);
+ csBankIndex += opOut.chars;
+ opOut.opcode = '';
+ }
+ else {
+ if ((! attOp.opcode) && isNextMutOp()) {
+ nextMutOp(attOp);
+ }
+ //print("attOp: "+attOp.toSource());
+ Changeset._slicerZipperFunc(attOp, csOp, opOut, pool);
+ if (opOut.opcode) {
+ outputMutOp(opOut);
+ opOut.opcode = '';
+ }
+ }
+ }
+
+ Changeset.assert(! lineAssem, "line assembler not finished");
+ mut.close();
+
+ //dmesg("-> "+lines.toSource());
+};
+
+Changeset.joinAttributionLines = function(theAlines) {
+ var assem = Changeset.mergingOpAssembler();
+ for(var i=0;i<theAlines.length;i++) {
+ var aline = theAlines[i];
+ var iter = Changeset.opIterator(aline);
+ while (iter.hasNext()) {
+ assem.append(iter.next());
+ }
+ }
+ return assem.toString();
+};
+
+Changeset.splitAttributionLines = function(attrOps, text) {
+ var iter = Changeset.opIterator(attrOps);
+ var assem = Changeset.mergingOpAssembler();
+ var lines = [];
+ var pos = 0;
+
+ function appendOp(op) {
+ assem.append(op);
+ if (op.lines > 0) {
+ lines.push(assem.toString());
+ assem.clear();
+ }
+ pos += op.chars;
+ }
+
+ while (iter.hasNext()) {
+ var op = iter.next();
+ var numChars = op.chars;
+ var numLines = op.lines;
+ while (numLines > 1) {
+ var newlineEnd = text.indexOf('\n', pos)+1;
+ Changeset.assert(newlineEnd > 0, "newlineEnd <= 0 in splitAttributionLines");
+ op.chars = newlineEnd - pos;
+ op.lines = 1;
+ appendOp(op);
+ numChars -= op.chars;
+ numLines -= op.lines;
+ }
+ if (numLines == 1) {
+ op.chars = numChars;
+ op.lines = 1;
+ }
+ appendOp(op);
+ }
+
+ return lines;
+};
+
+Changeset.splitTextLines = function(text) {
+ return text.match(/[^\n]*(?:\n|[^\n]$)/g);
+};
+
+Changeset.compose = function(cs1, cs2, pool) {
+ var unpacked1 = Changeset.unpack(cs1);
+ var unpacked2 = Changeset.unpack(cs2);
+ var len1 = unpacked1.oldLen;
+ var len2 = unpacked1.newLen;
+ Changeset.assert(len2 == unpacked2.oldLen, "mismatched composition");
+ var len3 = unpacked2.newLen;
+ var bankIter1 = Changeset.stringIterator(unpacked1.charBank);
+ var bankIter2 = Changeset.stringIterator(unpacked2.charBank);
+ var bankAssem = Changeset.stringAssembler();
+
+ var newOps = Changeset.applyZip(unpacked1.ops, 0, unpacked2.ops, 0, function(op1, op2, opOut) {
+ //var debugBuilder = Changeset.stringAssembler();
+ //debugBuilder.append(Changeset.opString(op1));
+ //debugBuilder.append(',');
+ //debugBuilder.append(Changeset.opString(op2));
+ //debugBuilder.append(' / ');
+
+ var op1code = op1.opcode;
+ var op2code = op2.opcode;
+ if (op1code == '+' && op2code == '-') {
+ bankIter1.skip(Math.min(op1.chars, op2.chars));
+ }
+ Changeset._slicerZipperFunc(op1, op2, opOut, pool);
+ if (opOut.opcode == '+') {
+ if (op2code == '+') {
+ bankAssem.append(bankIter2.take(opOut.chars));
+ }
+ else {
+ bankAssem.append(bankIter1.take(opOut.chars));
+ }
+ }
+
+ //debugBuilder.append(Changeset.opString(op1));
+ //debugBuilder.append(',');
+ //debugBuilder.append(Changeset.opString(op2));
+ //debugBuilder.append(' -> ');
+ //debugBuilder.append(Changeset.opString(opOut));
+ //print(debugBuilder.toString());
+ });
+
+ return Changeset.pack(len1, len3, newOps, bankAssem.toString());
+};
+
+Changeset.attributeTester = function(attribPair, pool) {
+ // returns a function that tests if a string of attributes
+ // (e.g. *3*4) contains a given attribute key,value that
+ // is already present in the pool.
+ if (! pool) {
+ return never;
+ }
+ var attribNum = pool.putAttrib(attribPair, true);
+ if (attribNum < 0) {
+ return never;
+ }
+ else {
+ var re = new RegExp('\\*'+Changeset.numToString(attribNum)+
+ '(?!\\w)');
+ return function(attribs) {
+ return re.test(attribs);
+ };
+ }
+ function never(attribs) { return false; }
+};
+
+Changeset.identity = function(N) {
+ return Changeset.pack(N, N, "", "");
+};
+
+Changeset.makeSplice = function(oldFullText, spliceStart, numRemoved, newText, optNewTextAPairs, pool) {
+ var oldLen = oldFullText.length;
+
+ if (spliceStart >= oldLen) {
+ spliceStart = oldLen - 1;
+ }
+ if (numRemoved > oldFullText.length - spliceStart - 1) {
+ numRemoved = oldFullText.length - spliceStart - 1;
+ }
+ var oldText = oldFullText.substring(spliceStart, spliceStart+numRemoved);
+ var newLen = oldLen + newText.length - oldText.length;
+
+ var assem = Changeset.smartOpAssembler();
+ assem.appendOpWithText('=', oldFullText.substring(0, spliceStart));
+ assem.appendOpWithText('-', oldText);
+ assem.appendOpWithText('+', newText, optNewTextAPairs, pool);
+ assem.endDocument();
+ return Changeset.pack(oldLen, newLen, assem.toString(), newText);
+};
+
+Changeset.toSplices = function(cs) {
+ // get a list of splices, [startChar, endChar, newText]
+
+ var unpacked = Changeset.unpack(cs);
+ var splices = [];
+
+ var oldPos = 0;
+ var iter = Changeset.opIterator(unpacked.ops);
+ var charIter = Changeset.stringIterator(unpacked.charBank);
+ var inSplice = false;
+ while (iter.hasNext()) {
+ var op = iter.next();
+ if (op.opcode == '=') {
+ oldPos += op.chars;
+ inSplice = false;
+ }
+ else {
+ if (! inSplice) {
+ splices.push([oldPos, oldPos, ""]);
+ inSplice = true;
+ }
+ if (op.opcode == '-') {
+ oldPos += op.chars;
+ splices[splices.length-1][1] += op.chars;
+ }
+ else if (op.opcode == '+') {
+ splices[splices.length-1][2] += charIter.take(op.chars);
+ }
+ }
+ }
+
+ return splices;
+};
+
+Changeset.characterRangeFollow = function(cs, startChar, endChar, insertionsAfter) {
+ var newStartChar = startChar;
+ var newEndChar = endChar;
+ var splices = Changeset.toSplices(cs);
+ var lengthChangeSoFar = 0;
+ for(var i=0;i<splices.length;i++) {
+ var splice = splices[i];
+ var spliceStart = splice[0] + lengthChangeSoFar;
+ var spliceEnd = splice[1] + lengthChangeSoFar;
+ var newTextLength = splice[2].length;
+ var thisLengthChange = newTextLength - (spliceEnd - spliceStart);
+
+ if (spliceStart <= newStartChar && spliceEnd >= newEndChar) {
+ // splice fully replaces/deletes range
+ // (also case that handles insertion at a collapsed selection)
+ if (insertionsAfter) {
+ newStartChar = newEndChar = spliceStart;
+ }
+ else {
+ newStartChar = newEndChar = spliceStart + newTextLength;
+ }
+ }
+ else if (spliceEnd <= newStartChar) {
+ // splice is before range
+ newStartChar += thisLengthChange;
+ newEndChar += thisLengthChange;
+ }
+ else if (spliceStart >= newEndChar) {
+ // splice is after range
+ }
+ else if (spliceStart >= newStartChar && spliceEnd <= newEndChar) {
+ // splice is inside range
+ newEndChar += thisLengthChange;
+ }
+ else if (spliceEnd < newEndChar) {
+ // splice overlaps beginning of range
+ newStartChar = spliceStart + newTextLength;
+ newEndChar += thisLengthChange;
+ }
+ else {
+ // splice overlaps end of range
+ newEndChar = spliceStart;
+ }
+
+ lengthChangeSoFar += thisLengthChange;
+ }
+
+ return [newStartChar, newEndChar];
+};
+
+Changeset.moveOpsToNewPool = function(cs, oldPool, newPool) {
+ // works on changeset or attribution string
+ var dollarPos = cs.indexOf('$');
+ if (dollarPos < 0) {
+ dollarPos = cs.length;
+ }
+ var upToDollar = cs.substring(0, dollarPos);
+ var fromDollar = cs.substring(dollarPos);
+ // order of attribs stays the same
+ return upToDollar.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ var oldNum = Changeset.parseNum(a);
+ var pair = oldPool.getAttrib(oldNum);
+ var newNum = newPool.putAttrib(pair);
+ return '*'+Changeset.numToString(newNum);
+ }) + fromDollar;
+};
+
+Changeset.makeAttribution = function(text) {
+ var assem = Changeset.smartOpAssembler();
+ assem.appendOpWithText('+', text);
+ return assem.toString();
+};
+
+// callable on a changeset, attribution string, or attribs property of an op
+Changeset.eachAttribNumber = function(cs, func) {
+ var dollarPos = cs.indexOf('$');
+ if (dollarPos < 0) {
+ dollarPos = cs.length;
+ }
+ var upToDollar = cs.substring(0, dollarPos);
+
+ upToDollar.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ func(Changeset.parseNum(a));
+ return '';
+ });
+};
+
+// callable on a changeset, attribution string, or attribs property of an op,
+// though it may easily create adjacent ops that can be merged.
+Changeset.filterAttribNumbers = function(cs, filter) {
+ return Changeset.mapAttribNumbers(cs, filter);
+};
+
+Changeset.mapAttribNumbers = function(cs, func) {
+ var dollarPos = cs.indexOf('$');
+ if (dollarPos < 0) {
+ dollarPos = cs.length;
+ }
+ var upToDollar = cs.substring(0, dollarPos);
+
+ var newUpToDollar = upToDollar.replace(/\*([0-9a-z]+)/g, function(s, a) {
+ var n = func(Changeset.parseNum(a));
+ if (n === true) {
+ return s;
+ }
+ else if ((typeof n) === "number") {
+ return '*'+Changeset.numToString(n);
+ }
+ else {
+ return '';
+ }
+ });
+
+ return newUpToDollar + cs.substring(dollarPos);
+};
+
+Changeset.makeAText = function(text, attribs) {
+ return { text: text, attribs: (attribs || Changeset.makeAttribution(text)) };
+};
+
+Changeset.applyToAText = function(cs, atext, pool) {
+ return { text: Changeset.applyToText(cs, atext.text),
+ attribs: Changeset.applyToAttribution(cs, atext.attribs, pool) };
+};
+
+Changeset.cloneAText = function(atext) {
+ return { text: atext.text, attribs: atext.attribs };
+};
+
+Changeset.copyAText = function(atext1, atext2) {
+ atext2.text = atext1.text;
+ atext2.attribs = atext1.attribs;
+};
+
+Changeset.appendATextToAssembler = function(atext, assem) {
+ // intentionally skips last newline char of atext
+ var iter = Changeset.opIterator(atext.attribs);
+ var op = Changeset.newOp();
+ while (iter.hasNext()) {
+ iter.next(op);
+ if (! iter.hasNext()) {
+ // last op, exclude final newline
+ if (op.lines <= 1) {
+ op.lines = 0;
+ op.chars--;
+ if (op.chars) {
+ assem.append(op);
+ }
+ }
+ else {
+ var nextToLastNewlineEnd =
+ atext.text.lastIndexOf('\n', atext.text.length-2) + 1;
+ var lastLineLength = atext.text.length - nextToLastNewlineEnd - 1;
+ op.lines--;
+ op.chars -= (lastLineLength + 1);
+ assem.append(op);
+ op.lines = 0;
+ op.chars = lastLineLength;
+ if (op.chars) {
+ assem.append(op);
+ }
+ }
+ }
+ else {
+ assem.append(op);
+ }
+ }
+};
+
+Changeset.prepareForWire = function(cs, pool) {
+ var newPool = new AttribPool();
+ var newCs = Changeset.moveOpsToNewPool(cs, pool, newPool);
+ return {translated: newCs, pool: newPool};
+};
+
+Changeset.isIdentity = function(cs) {
+ var unpacked = Changeset.unpack(cs);
+ return unpacked.ops == "" && unpacked.oldLen == unpacked.newLen;
+};
+
+Changeset.opAttributeValue = function(op, key, pool) {
+ return Changeset.attribsAttributeValue(op.attribs, key, pool);
+};
+
+Changeset.attribsAttributeValue = function(attribs, key, pool) {
+ var value = '';
+ if (attribs) {
+ Changeset.eachAttribNumber(attribs, function(n) {
+ if (pool.getAttribKey(n) == key) {
+ value = pool.getAttribValue(n);
+ }
+ });
+ }
+ return value;
+};
+
+Changeset.builder = function(oldLen) {
+ var assem = Changeset.smartOpAssembler();
+ var o = Changeset.newOp();
+ var charBank = Changeset.stringAssembler();
+
+ var self = {
+ // attribs are [[key1,value1],[key2,value2],...] or '*0*1...' (no pool needed in latter case)
+ keep: function(N, L, attribs, pool) {
+ o.opcode = '=';
+ o.attribs = (attribs &&
+ Changeset.makeAttribsString('=', attribs, pool)) || '';
+ o.chars = N;
+ o.lines = (L || 0);
+ assem.append(o);
+ return self;
+ },
+ keepText: function(text, attribs, pool) {
+ assem.appendOpWithText('=', text, attribs, pool);
+ return self;
+ },
+ insert: function(text, attribs, pool) {
+ assem.appendOpWithText('+', text, attribs, pool);
+ charBank.append(text);
+ return self;
+ },
+ remove: function(N, L) {
+ o.opcode = '-';
+ o.attribs = '';
+ o.chars = N;
+ o.lines = (L || 0);
+ assem.append(o);
+ return self;
+ },
+ toString: function() {
+ assem.endDocument();
+ var newLen = oldLen + assem.getLengthChange();
+ return Changeset.pack(oldLen, newLen, assem.toString(),
+ charBank.toString());
+ }
+ };
+
+ return self;
+};
+
+Changeset.makeAttribsString = function(opcode, attribs, pool) {
+ // makeAttribsString(opcode, '*3') or makeAttribsString(opcode, [['foo','bar']], myPool) work
+ if (! attribs) {
+ return '';
+ }
+ else if ((typeof attribs) == "string") {
+ return attribs;
+ }
+ else if (pool && attribs && attribs.length) {
+ if (attribs.length > 1) {
+ attribs = attribs.slice();
+ attribs.sort();
+ }
+ var result = [];
+ for(var i=0;i<attribs.length;i++) {
+ var pair = attribs[i];
+ if (opcode == '=' || (opcode == '+' && pair[1])) {
+ result.push('*'+Changeset.numToString(pool.putAttrib(pair)));
+ }
+ }
+ return result.join('');
+ }
+};
+
+// like "substring" but on a single-line attribution string
+Changeset.subattribution = function(astr, start, optEnd) {
+ var iter = Changeset.opIterator(astr, 0);
+ var assem = Changeset.smartOpAssembler();
+ var attOp = Changeset.newOp();
+ var csOp = Changeset.newOp();
+ var opOut = Changeset.newOp();
+
+ function doCsOp() {
+ if (csOp.chars) {
+ while (csOp.opcode && (attOp.opcode || iter.hasNext())) {
+ if (! attOp.opcode) iter.next(attOp);
+
+ if (csOp.opcode && attOp.opcode && csOp.chars >= attOp.chars &&
+ attOp.lines > 0 && csOp.lines <= 0) {
+ csOp.lines++;
+ }
+
+ Changeset._slicerZipperFunc(attOp, csOp, opOut, null);
+ if (opOut.opcode) {
+ assem.append(opOut);
+ opOut.opcode = '';
+ }
+ }
+ }
+ }
+
+ csOp.opcode = '-';
+ csOp.chars = start;
+
+ doCsOp();
+
+ if (optEnd === undefined) {
+ if (attOp.opcode) {
+ assem.append(attOp);
+ }
+ while (iter.hasNext()) {
+ iter.next(attOp);
+ assem.append(attOp);
+ }
+ }
+ else {
+ csOp.opcode = '=';
+ csOp.chars = optEnd - start;
+ doCsOp();
+ }
+
+ return assem.toString();
+};
+
+Changeset.inverse = function(cs, lines, alines, pool) {
+ // lines and alines are what the changeset is meant to apply to.
+ // They may be arrays or objects with .get(i) and .length methods.
+ // They include final newlines on lines.
+ function lines_get(idx) {
+ if (lines.get) {
+ return lines.get(idx);
+ }
+ else {
+ return lines[idx];
+ }
+ }
+ function lines_length() {
+ if ((typeof lines.length) == "number") {
+ return lines.length;
+ }
+ else {
+ return lines.length();
+ }
+ }
+ function alines_get(idx) {
+ if (alines.get) {
+ return alines.get(idx);
+ }
+ else {
+ return alines[idx];
+ }
+ }
+ function alines_length() {
+ if ((typeof alines.length) == "number") {
+ return alines.length;
+ }
+ else {
+ return alines.length();
+ }
+ }
+
+ var curLine = 0;
+ var curChar = 0;
+ var curLineOpIter = null;
+ var curLineOpIterLine;
+ var curLineNextOp = Changeset.newOp('+');
+
+ var unpacked = Changeset.unpack(cs);
+ var csIter = Changeset.opIterator(unpacked.ops);
+ var builder = Changeset.builder(unpacked.newLen);
+
+ function consumeAttribRuns(numChars, func/*(len, attribs, endsLine)*/) {
+
+ if ((! curLineOpIter) || (curLineOpIterLine != curLine)) {
+ // create curLineOpIter and advance it to curChar
+ curLineOpIter = Changeset.opIterator(alines_get(curLine));
+ curLineOpIterLine = curLine;
+ var indexIntoLine = 0;
+ var done = false;
+ while (! done) {
+ curLineOpIter.next(curLineNextOp);
+ if (indexIntoLine + curLineNextOp.chars >= curChar) {
+ curLineNextOp.chars -= (curChar - indexIntoLine);
+ done = true;
+ }
+ else {
+ indexIntoLine += curLineNextOp.chars;
+ }
+ }
+ }
+
+ while (numChars > 0) {
+ if ((! curLineNextOp.chars) && (! curLineOpIter.hasNext())) {
+ curLine++;
+ curChar = 0;
+ curLineOpIterLine = curLine;
+ curLineNextOp.chars = 0;
+ curLineOpIter = Changeset.opIterator(alines_get(curLine));
+ }
+ if (! curLineNextOp.chars) {
+ curLineOpIter.next(curLineNextOp);
+ }
+ var charsToUse = Math.min(numChars, curLineNextOp.chars);
+ func(charsToUse, curLineNextOp.attribs,
+ charsToUse == curLineNextOp.chars && curLineNextOp.lines > 0);
+ numChars -= charsToUse;
+ curLineNextOp.chars -= charsToUse;
+ curChar += charsToUse;
+ }
+
+ if ((! curLineNextOp.chars) && (! curLineOpIter.hasNext())) {
+ curLine++;
+ curChar = 0;
+ }
+ }
+
+ function skip(N, L) {
+ if (L) {
+ curLine += L;
+ curChar = 0;
+ }
+ else {
+ if (curLineOpIter && curLineOpIterLine == curLine) {
+ consumeAttribRuns(N, function() {});
+ }
+ else {
+ curChar += N;
+ }
+ }
+ }
+
+ function nextText(numChars) {
+ var len = 0;
+ var assem = Changeset.stringAssembler();
+ var firstString = lines_get(curLine).substring(curChar);
+ len += firstString.length;
+ assem.append(firstString);
+
+ var lineNum = curLine+1;
+ while (len < numChars) {
+ var nextString = lines_get(lineNum);
+ len += nextString.length;
+ assem.append(nextString);
+ lineNum++;
+ }
+
+ return assem.toString().substring(0, numChars);
+ }
+
+ function cachedStrFunc(func) {
+ var cache = {};
+ return function(s) {
+ if (! cache[s]) {
+ cache[s] = func(s);
+ }
+ return cache[s];
+ };
+ }
+
+ var attribKeys = [];
+ var attribValues = [];
+ while (csIter.hasNext()) {
+ var csOp = csIter.next();
+ if (csOp.opcode == '=') {
+ if (csOp.attribs) {
+ attribKeys.length = 0;
+ attribValues.length = 0;
+ Changeset.eachAttribNumber(csOp.attribs, function(n) {
+ attribKeys.push(pool.getAttribKey(n));
+ attribValues.push(pool.getAttribValue(n));
+ });
+ var undoBackToAttribs = cachedStrFunc(function(attribs) {
+ var backAttribs = [];
+ for(var i=0;i<attribKeys.length;i++) {
+ var appliedKey = attribKeys[i];
+ var appliedValue = attribValues[i];
+ var oldValue = Changeset.attribsAttributeValue(attribs, appliedKey, pool);
+ if (appliedValue != oldValue) {
+ backAttribs.push([appliedKey, oldValue]);
+ }
+ }
+ return Changeset.makeAttribsString('=', backAttribs, pool);
+ });
+ consumeAttribRuns(csOp.chars, function(len, attribs, endsLine) {
+ builder.keep(len, endsLine ? 1 : 0, undoBackToAttribs(attribs));
+ });
+ }
+ else {
+ skip(csOp.chars, csOp.lines);
+ builder.keep(csOp.chars, csOp.lines);
+ }
+ }
+ else if (csOp.opcode == '+') {
+ builder.remove(csOp.chars, csOp.lines);
+ }
+ else if (csOp.opcode == '-') {
+ var textBank = nextText(csOp.chars);
+ var textBankIndex = 0;
+ consumeAttribRuns(csOp.chars, function(len, attribs, endsLine) {
+ builder.insert(textBank.substr(textBankIndex, len), attribs);
+ textBankIndex += len;
+ });
+ }
+ }
+
+ return Changeset.checkRep(builder.toString());
+};
+
+// %CLIENT FILE ENDS HERE%
+
+Changeset.follow = function(cs1, cs2, reverseInsertOrder, pool) {
+ var unpacked1 = Changeset.unpack(cs1);
+ var unpacked2 = Changeset.unpack(cs2);
+ var len1 = unpacked1.oldLen;
+ var len2 = unpacked2.oldLen;
+ Changeset.assert(len1 == len2, "mismatched follow");
+ var chars1 = Changeset.stringIterator(unpacked1.charBank);
+ var chars2 = Changeset.stringIterator(unpacked2.charBank);
+
+ var oldLen = unpacked1.newLen;
+ var oldPos = 0;
+ var newLen = 0;
+
+ var hasInsertFirst = Changeset.attributeTester(['insertorder','first'],
+ pool);
+
+ var newOps = Changeset.applyZip(unpacked1.ops, 0, unpacked2.ops, 0, function(op1, op2, opOut) {
+ if (op1.opcode == '+' || op2.opcode == '+') {
+ var whichToDo;
+ if (op2.opcode != '+') {
+ whichToDo = 1;
+ }
+ else if (op1.opcode != '+') {
+ whichToDo = 2;
+ }
+ else {
+ // both +
+ var firstChar1 = chars1.peek(1);
+ var firstChar2 = chars2.peek(1);
+ var insertFirst1 = hasInsertFirst(op1.attribs);
+ var insertFirst2 = hasInsertFirst(op2.attribs);
+ if (insertFirst1 && ! insertFirst2) {
+ whichToDo = 1;
+ }
+ else if (insertFirst2 && ! insertFirst1) {
+ whichToDo = 2;
+ }
+ // insert string that doesn't start with a newline first so as not to break up lines
+ else if (firstChar1 == '\n' && firstChar2 != '\n') {
+ whichToDo = 2;
+ }
+ else if (firstChar1 != '\n' && firstChar2 == '\n') {
+ whichToDo = 1;
+ }
+ // break symmetry:
+ else if (reverseInsertOrder) {
+ whichToDo = 2;
+ }
+ else {
+ whichToDo = 1;
+ }
+ }
+ if (whichToDo == 1) {
+ chars1.skip(op1.chars);
+ opOut.opcode = '=';
+ opOut.lines = op1.lines;
+ opOut.chars = op1.chars;
+ opOut.attribs = '';
+ op1.opcode = '';
+ }
+ else {
+ // whichToDo == 2
+ chars2.skip(op2.chars);
+ Changeset.copyOp(op2, opOut);
+ op2.opcode = '';
+ }
+ }
+ else if (op1.opcode == '-') {
+ if (! op2.opcode) {
+ op1.opcode = '';
+ }
+ else {
+ if (op1.chars <= op2.chars) {
+ op2.chars -= op1.chars;
+ op2.lines -= op1.lines;
+ op1.opcode = '';
+ if (! op2.chars) {
+ op2.opcode = '';
+ }
+ }
+ else {
+ op1.chars -= op2.chars;
+ op1.lines -= op2.lines;
+ op2.opcode = '';
+ }
+ }
+ }
+ else if (op2.opcode == '-') {
+ Changeset.copyOp(op2, opOut);
+ if (! op1.opcode) {
+ op2.opcode = '';
+ }
+ else if (op2.chars <= op1.chars) {
+ // delete part or all of a keep
+ op1.chars -= op2.chars;
+ op1.lines -= op2.lines;
+ op2.opcode = '';
+ if (! op1.chars) {
+ op1.opcode = '';
+ }
+ }
+ else {
+ // delete all of a keep, and keep going
+ opOut.lines = op1.lines;
+ opOut.chars = op1.chars;
+ op2.lines -= op1.lines;
+ op2.chars -= op1.chars;
+ op1.opcode = '';
+ }
+ }
+ else if (! op1.opcode) {
+ Changeset.copyOp(op2, opOut);
+ op2.opcode = '';
+ }
+ else if (! op2.opcode) {
+ Changeset.copyOp(op1, opOut);
+ op1.opcode = '';
+ }
+ else {
+ // both keeps
+ opOut.opcode = '=';
+ opOut.attribs = Changeset.followAttributes(op1.attribs, op2.attribs, pool);
+ if (op1.chars <= op2.chars) {
+ opOut.chars = op1.chars;
+ opOut.lines = op1.lines;
+ op2.chars -= op1.chars;
+ op2.lines -= op1.lines;
+ op1.opcode = '';
+ if (! op2.chars) {
+ op2.opcode = '';
+ }
+ }
+ else {
+ opOut.chars = op2.chars;
+ opOut.lines = op2.lines;
+ op1.chars -= op2.chars;
+ op1.lines -= op2.lines;
+ op2.opcode = '';
+ }
+ }
+ switch (opOut.opcode) {
+ case '=': oldPos += opOut.chars; newLen += opOut.chars; break;
+ case '-': oldPos += opOut.chars; break;
+ case '+': newLen += opOut.chars; break;
+ }
+ });
+ newLen += oldLen - oldPos;
+
+ return Changeset.pack(oldLen, newLen, newOps, unpacked2.charBank);
+};
+
+Changeset.followAttributes = function(att1, att2, pool) {
+ // The merge of two sets of attribute changes to the same text
+ // takes the lexically-earlier value if there are two values
+ // for the same key. Otherwise, all key/value changes from
+ // both attribute sets are taken. This operation is the "follow",
+ // so a set of changes is produced that can be applied to att1
+ // to produce the merged set.
+ if ((! att2) || (! pool)) return '';
+ if (! att1) return att2;
+ var atts = [];
+ att2.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ atts.push(pool.getAttrib(Changeset.parseNum(a)));
+ return '';
+ });
+ att1.replace(/\*([0-9a-z]+)/g, function(_, a) {
+ var pair1 = pool.getAttrib(Changeset.parseNum(a));
+ for(var i=0;i<atts.length;i++) {
+ var pair2 = atts[i];
+ if (pair1[0] == pair2[0]) {
+ if (pair1[1] <= pair2[1]) {
+ // winner of merge is pair1, delete this attribute
+ atts.splice(i, 1);
+ }
+ break;
+ }
+ }
+ return '';
+ });
+ // we've only removed attributes, so they're already sorted
+ var buf = Changeset.stringAssembler();
+ for(var i=0;i<atts.length;i++) {
+ buf.append('*');
+ buf.append(Changeset.numToString(pool.putAttrib(atts[i])));
+ }
+ return buf.toString();
+};
diff --git a/infrastructure/ace/www/easysync2_tests.js b/infrastructure/ace/www/easysync2_tests.js
new file mode 100644
index 0000000..2fcf202
--- /dev/null
+++ b/infrastructure/ace/www/easysync2_tests.js
@@ -0,0 +1,877 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.easysync2_tests
+// %APPJET%: import("etherpad.collab.ace.easysync2.*")
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function runTests() {
+
+ function print(str) {
+ java.lang.System.out.println(str);
+ }
+
+ function assert(code, optMsg) {
+ if (! eval(code)) throw new Error("FALSE: "+(optMsg || code));
+ }
+ function literal(v) {
+ if ((typeof v) == "string") {
+ return '"'+v.replace(/[\\\"]/g, '\\$1').replace(/\n/g, '\\n')+'"';
+ }
+ else return v.toSource();
+ }
+ function assertEqualArrays(a, b) {
+ assert(literal(a)+".toSource() == "+literal(b)+".toSource()");
+ }
+ function assertEqualStrings(a, b) {
+ assert(literal(a)+" == "+literal(b));
+ }
+
+ function throughIterator(opsStr) {
+ var iter = Changeset.opIterator(opsStr);
+ var assem = Changeset.opAssembler();
+ while (iter.hasNext()) {
+ assem.append(iter.next());
+ }
+ return assem.toString();
+ }
+
+ function throughSmartAssembler(opsStr) {
+ var iter = Changeset.opIterator(opsStr);
+ var assem = Changeset.smartOpAssembler();
+ while (iter.hasNext()) {
+ assem.append(iter.next());
+ }
+ assem.endDocument();
+ return assem.toString();
+ }
+
+ (function() {
+ print("> throughIterator");
+ var x = '-c*3*4+6|3=az*asdf0*1*2*3+1=1-1+1*0+1=1-1+1|c=c-1';
+ assert("throughIterator("+literal(x)+") == "+literal(x));
+ })();
+
+ (function() {
+ print("> throughSmartAssembler");
+ var x = '-c*3*4+6|3=az*asdf0*1*2*3+1=1-1+1*0+1=1-1+1|c=c-1';
+ assert("throughSmartAssembler("+literal(x)+") == "+literal(x));
+ })();
+
+ function applyMutations(mu, arrayOfArrays) {
+ arrayOfArrays.forEach(function (a) {
+ var result = mu[a[0]].apply(mu, a.slice(1));
+ if (a[0] == 'remove' && a[3]) {
+ assertEqualStrings(a[3], result);
+ }
+ });
+ }
+
+ function mutationsToChangeset(oldLen, arrayOfArrays) {
+ var assem = Changeset.smartOpAssembler();
+ var op = Changeset.newOp();
+ var bank = Changeset.stringAssembler();
+ var oldPos = 0;
+ var newLen = 0;
+ arrayOfArrays.forEach(function (a) {
+ if (a[0] == 'skip') {
+ op.opcode = '=';
+ op.chars = a[1];
+ op.lines = (a[2] || 0);
+ assem.append(op);
+ oldPos += op.chars;
+ newLen += op.chars;
+ }
+ else if (a[0] == 'remove') {
+ op.opcode = '-';
+ op.chars = a[1];
+ op.lines = (a[2] || 0);
+ assem.append(op);
+ oldPos += op.chars;
+ }
+ else if (a[0] == 'insert') {
+ op.opcode = '+';
+ bank.append(a[1]);
+ op.chars = a[1].length;
+ op.lines = (a[2] || 0);
+ assem.append(op);
+ newLen += op.chars;
+ }
+ });
+ newLen += oldLen - oldPos;
+ assem.endDocument();
+ return Changeset.pack(oldLen, newLen, assem.toString(),
+ bank.toString());
+ }
+
+ function runMutationTest(testId, origLines, muts, correct) {
+ print("> runMutationTest#"+testId);
+ var lines = origLines.slice();
+ var mu = Changeset.textLinesMutator(lines);
+ applyMutations(mu, muts);
+ mu.close();
+ assertEqualArrays(correct, lines);
+
+ var inText = origLines.join('');
+ var cs = mutationsToChangeset(inText.length, muts);
+ lines = origLines.slice();
+ Changeset.mutateTextLines(cs, lines);
+ assertEqualArrays(correct, lines);
+
+ var correctText = correct.join('');
+ //print(literal(cs));
+ var outText = Changeset.applyToText(cs, inText);
+ assertEqualStrings(correctText, outText);
+ }
+
+ runMutationTest(1, ["apple\n", "banana\n", "cabbage\n", "duffle\n", "eggplant\n"],
+ [['remove',1,0,"a"],['insert',"tu"],['remove',1,0,"p"],['skip',4,1],['skip',7,1],
+ ['insert',"cream\npie\n",2],['skip',2],['insert',"bot"],['insert',"\n",1],
+ ['insert',"bu"],['skip',3],['remove',3,1,"ge\n"],['remove',6,0,"duffle"]],
+ ["tuple\n","banana\n","cream\n","pie\n", "cabot\n","bubba\n","eggplant\n"]);
+
+ runMutationTest(2, ["apple\n", "banana\n", "cabbage\n", "duffle\n", "eggplant\n"],
+ [['remove',1,0,"a"],['remove',1,0,"p"],['insert',"tu"],['skip',11,2],
+ ['insert',"cream\npie\n",2],['skip',2],['insert',"bot"],['insert',"\n",1],
+ ['insert',"bu"],['skip',3],['remove',3,1,"ge\n"],['remove',6,0,"duffle"]],
+ ["tuple\n","banana\n","cream\n","pie\n", "cabot\n","bubba\n","eggplant\n"]);
+
+ runMutationTest(3, ["apple\n", "banana\n", "cabbage\n", "duffle\n", "eggplant\n"],
+ [['remove',6,1,"apple\n"],['skip',15,2],['skip',6],['remove',1,1,"\n"],
+ ['remove',8,0,"eggplant"],['skip',1,1]],
+ ["banana\n","cabbage\n","duffle\n"]);
+
+ runMutationTest(4, ["15\n"],
+ [['skip',1],['insert',"\n2\n3\n4\n",4],['skip',2,1]],
+ ["1\n","2\n","3\n","4\n","5\n"]);
+
+ runMutationTest(5, ["1\n","2\n","3\n","4\n","5\n"],
+ [['skip',1],['remove',7,4,"\n2\n3\n4\n"],['skip',2,1]],
+ ["15\n"]);
+
+ runMutationTest(6, ["123\n","abc\n","def\n","ghi\n","xyz\n"],
+ [['insert',"0"],['skip',4,1],['skip',4,1],['remove',8,2,"def\nghi\n"],['skip',4,1]],
+ ["0123\n", "abc\n", "xyz\n"]);
+
+ runMutationTest(7, ["apple\n", "banana\n", "cabbage\n", "duffle\n", "eggplant\n"],
+ [['remove',6,1,"apple\n"],['skip',15,2,true],['skip',6,0,true],['remove',1,1,"\n"],
+ ['remove',8,0,"eggplant"],['skip',1,1,true]],
+ ["banana\n","cabbage\n","duffle\n"]);
+
+ function poolOrArray(attribs) {
+ if (attribs.getAttrib) {
+ return attribs; // it's already an attrib pool
+ }
+ else {
+ // assume it's an array of attrib strings to be split and added
+ var p = new AttribPool();
+ attribs.forEach(function (kv) { p.putAttrib(kv.split(',')); });
+ return p;
+ }
+ }
+
+ function runApplyToAttributionTest(testId, attribs, cs, inAttr, outCorrect) {
+ print("> applyToAttribution#"+testId);
+ var p = poolOrArray(attribs);
+ var result = Changeset.applyToAttribution(
+ Changeset.checkRep(cs), inAttr, p);
+ assertEqualStrings(outCorrect, result);
+ }
+
+ // turn c<b>a</b>ctus\n into a<b>c</b>tusabcd\n
+ runApplyToAttributionTest(1, ['bold,', 'bold,true'],
+ "Z:7>3-1*0=1*1=1=3+4$abcd",
+ "+1*1+1|1+5", "+1*1+1|1+8");
+
+ // turn "david\ngreenspan\n" into "<b>david\ngreen</b>\n"
+ runApplyToAttributionTest(2, ['bold,', 'bold,true'],
+ "Z:g<4*1|1=6*1=5-4$",
+ "|2+g", "*1|1+6*1+5|1+1");
+
+ (function() {
+ print("> mutatorHasMore");
+ var lines = ["1\n", "2\n", "3\n", "4\n"];
+ var mu;
+
+ mu = Changeset.textLinesMutator(lines);
+ assert(mu.hasMore()+' == true');
+ mu.skip(8,4);
+ assert(mu.hasMore()+' == false');
+ mu.close();
+ assert(mu.hasMore()+' == false');
+
+ // still 1,2,3,4
+ mu = Changeset.textLinesMutator(lines);
+ assert(mu.hasMore()+' == true');
+ mu.remove(2,1);
+ assert(mu.hasMore()+' == true');
+ mu.skip(2,1);
+ assert(mu.hasMore()+' == true');
+ mu.skip(2,1);
+ assert(mu.hasMore()+' == true');
+ mu.skip(2,1);
+ assert(mu.hasMore()+' == false');
+ mu.insert("5\n", 1);
+ assert(mu.hasMore()+' == false');
+ mu.close();
+ assert(mu.hasMore()+' == false');
+
+ // 2,3,4,5 now
+ mu = Changeset.textLinesMutator(lines);
+ assert(mu.hasMore()+' == true');
+ mu.remove(6,3);
+ assert(mu.hasMore()+' == true');
+ mu.remove(2,1);
+ assert(mu.hasMore()+' == false');
+ mu.insert("hello\n", 1);
+ assert(mu.hasMore()+' == false');
+ mu.close();
+ assert(mu.hasMore()+' == false');
+
+ })();
+
+ function runMutateAttributionTest(testId, attribs, cs, alines, outCorrect) {
+ print("> runMutateAttributionTest#"+testId);
+ var p = poolOrArray(attribs);
+ var alines2 = Array.prototype.slice.call(alines);
+ var result = Changeset.mutateAttributionLines(
+ Changeset.checkRep(cs), alines2, p);
+ assertEqualArrays(outCorrect, alines2);
+
+ print("> runMutateAttributionTest#"+testId+".applyToAttribution");
+ function removeQuestionMarks(a) { return a.replace(/\?/g, ''); }
+ var inMerged = Changeset.joinAttributionLines(alines.map(removeQuestionMarks));
+ var correctMerged = Changeset.joinAttributionLines(outCorrect.map(removeQuestionMarks));
+ var mergedResult = Changeset.applyToAttribution(cs, inMerged, p);
+ assertEqualStrings(correctMerged, mergedResult);
+ }
+
+ // turn 123\n 456\n 789\n into 123\n 4<b>5</b>6\n 789\n
+ runMutateAttributionTest(1, ["bold,true"], "Z:c>0|1=4=1*0=1$", ["|1+4", "|1+4", "|1+4"],
+ ["|1+4", "+1*0+1|1+2", "|1+4"]);
+
+ // make a document bold
+ runMutateAttributionTest(2, ["bold,true"], "Z:c>0*0|3=c$", ["|1+4", "|1+4", "|1+4"],
+ ["*0|1+4", "*0|1+4", "*0|1+4"]);
+
+ // clear bold on document
+ runMutateAttributionTest(3, ["bold,","bold,true"], "Z:c>0*0|3=c$",
+ ["*1+1+1*1+1|1+1", "+1*1+1|1+2", "*1+1+1*1+1|1+1"],
+ ["|1+4", "|1+4", "|1+4"]);
+
+ // add a character on line 3 of a document with 5 blank lines, and make sure
+ // the optimization that skips purely-kept lines is working; if any attribution string
+ // with a '?' is parsed it will cause an error.
+ runMutateAttributionTest(4, ['foo,bar','line,1','line,2','line,3','line,4','line,5'],
+ "Z:5>1|2=2+1$x",
+ ["?*1|1+1", "?*2|1+1", "*3|1+1", "?*4|1+1", "?*5|1+1"],
+ ["?*1|1+1", "?*2|1+1", "+1*3|1+1", "?*4|1+1", "?*5|1+1"]);
+
+ var testPoolWithChars = (function() {
+ var p = new AttribPool();
+ p.putAttrib(['char','newline']);
+ for(var i=1;i<36;i++) {
+ p.putAttrib(['char',Changeset.numToString(i)]);
+ }
+ p.putAttrib(['char','']);
+ return p;
+ })();
+
+ // based on runMutationTest#1
+ runMutateAttributionTest(5, testPoolWithChars,
+ "Z:11>7-2*t+1*u+1|2=b|2+a=2*b+1*o+1*t+1*0|1+1*b+1*u+1=3|1-3-6$"+
+ "tucream\npie\nbot\nbu",
+ ["*a+1*p+2*l+1*e+1*0|1+1",
+ "*b+1*a+1*n+1*a+1*n+1*a+1*0|1+1",
+ "*c+1*a+1*b+2*a+1*g+1*e+1*0|1+1",
+ "*d+1*u+1*f+2*l+1*e+1*0|1+1",
+ "*e+1*g+2*p+1*l+1*a+1*n+1*t+1*0|1+1"],
+ ["*t+1*u+1*p+1*l+1*e+1*0|1+1",
+ "*b+1*a+1*n+1*a+1*n+1*a+1*0|1+1",
+ "|1+6",
+ "|1+4",
+ "*c+1*a+1*b+1*o+1*t+1*0|1+1",
+ "*b+1*u+1*b+2*a+1*0|1+1",
+ "*e+1*g+2*p+1*l+1*a+1*n+1*t+1*0|1+1"]);
+
+ // based on runMutationTest#3
+ runMutateAttributionTest(6, testPoolWithChars,
+ "Z:11<f|1-6|2=f=6|1-1-8$",
+ ["*a|1+6", "*b|1+7", "*c|1+8", "*d|1+7", "*e|1+9"],
+ ["*b|1+7", "*c|1+8", "*d+6*e|1+1"]);
+
+ // based on runMutationTest#4
+ runMutateAttributionTest(7, testPoolWithChars,
+ "Z:3>7=1|4+7$\n2\n3\n4\n",
+ ["*1+1*5|1+2"],
+ ["*1+1|1+1","|1+2","|1+2","|1+2","*5|1+2"]);
+
+ // based on runMutationTest#5
+ runMutateAttributionTest(8, testPoolWithChars,
+ "Z:a<7=1|4-7$",
+ ["*1|1+2","*2|1+2","*3|1+2","*4|1+2","*5|1+2"],
+ ["*1+1*5|1+2"]);
+
+ // based on runMutationTest#6
+ runMutateAttributionTest(9, testPoolWithChars,
+ "Z:k<7*0+1*10|2=8|2-8$0",
+ ["*1+1*2+1*3+1|1+1","*a+1*b+1*c+1|1+1",
+ "*d+1*e+1*f+1|1+1","*g+1*h+1*i+1|1+1","?*x+1*y+1*z+1|1+1"],
+ ["*0+1|1+4", "|1+4", "?*x+1*y+1*z+1|1+1"]);
+
+ runMutateAttributionTest(10, testPoolWithChars,
+ "Z:6>4=1+1=1+1|1=1+1=1*0+1$abcd",
+ ["|1+3", "|1+3"],
+ ["|1+5", "+2*0+1|1+2"]);
+
+
+ runMutateAttributionTest(11, testPoolWithChars,
+ "Z:s>1|1=4=6|1+1$\n",
+ ["*0|1+4", "*0|1+8", "*0+5|1+1", "*0|1+1", "*0|1+5", "*0|1+1", "*0|1+1", "*0|1+1", "|1+1"],
+ ["*0|1+4", "*0+6|1+1", "*0|1+2", "*0+5|1+1", "*0|1+1", "*0|1+5", "*0|1+1", "*0|1+1", "*0|1+1", "|1+1"]);
+
+ function randomInlineString(len, rand) {
+ var assem = Changeset.stringAssembler();
+ for(var i=0;i<len;i++) {
+ assem.append(String.fromCharCode(rand.nextInt(26) + 97));
+ }
+ return assem.toString();
+ }
+
+ function randomMultiline(approxMaxLines, approxMaxCols, rand) {
+ var numParts = rand.nextInt(approxMaxLines*2)+1;
+ var txt = Changeset.stringAssembler();
+ txt.append(rand.nextInt(2) ? '\n' : '');
+ for(var i=0;i<numParts;i++) {
+ if ((i % 2) == 0) {
+ if (rand.nextInt(10)) {
+ txt.append(randomInlineString(rand.nextInt(approxMaxCols)+1, rand));
+ }
+ else {
+ txt.append('\n');
+ }
+ }
+ else {
+ txt.append('\n');
+ }
+ }
+ return txt.toString();
+ }
+
+ function randomStringOperation(numCharsLeft, rand) {
+ var result;
+ switch(rand.nextInt(9)) {
+ case 0: {
+ // insert char
+ result = {insert: randomInlineString(1, rand)};
+ break;
+ }
+ case 1: {
+ // delete char
+ result = {remove: 1};
+ break;
+ }
+ case 2: {
+ // skip char
+ result = {skip: 1};
+ break;
+ }
+ case 3: {
+ // insert small
+ result = {insert: randomInlineString(rand.nextInt(4)+1, rand)};
+ break;
+ }
+ case 4: {
+ // delete small
+ result = {remove: rand.nextInt(4)+1};
+ break;
+ }
+ case 5: {
+ // skip small
+ result = {skip: rand.nextInt(4)+1};
+ break;
+ }
+ case 6: {
+ // insert multiline;
+ result = {insert: randomMultiline(5, 20, rand)};
+ break;
+ }
+ case 7: {
+ // delete multiline
+ result = {remove: Math.round(numCharsLeft * rand.nextDouble() * rand.nextDouble()) };
+ break;
+ }
+ case 8: {
+ // skip multiline
+ result = {skip: Math.round(numCharsLeft * rand.nextDouble() * rand.nextDouble()) };
+ break;
+ }
+ case 9: {
+ // delete to end
+ result = {remove: numCharsLeft};
+ break;
+ }
+ case 10: {
+ // skip to end
+ result = {skip: numCharsLeft};
+ break;
+ }
+ }
+ var maxOrig = numCharsLeft - 1;
+ if ('remove' in result) {
+ result.remove = Math.min(result.remove, maxOrig);
+ }
+ else if ('skip' in result) {
+ result.skip = Math.min(result.skip, maxOrig);
+ }
+ return result;
+ }
+
+ function randomTwoPropAttribs(opcode, rand) {
+ // assumes attrib pool like ['apple,','apple,true','banana,','banana,true']
+ if (opcode == '-' || rand.nextInt(3)) {
+ return '';
+ }
+ else if (rand.nextInt(3)) {
+ if (opcode == '+' || rand.nextInt(2)) {
+ return '*'+Changeset.numToString(rand.nextInt(2)*2+1);
+ }
+ else {
+ return '*'+Changeset.numToString(rand.nextInt(2)*2);
+ }
+ }
+ else {
+ if (opcode == '+' || rand.nextInt(4) == 0) {
+ return '*1*3';
+ }
+ else {
+ return ['*0*2', '*0*3', '*1*2'][rand.nextInt(3)];
+ }
+ }
+ }
+
+ function randomTestChangeset(origText, rand, withAttribs) {
+ var charBank = Changeset.stringAssembler();
+ var textLeft = origText; // always keep final newline
+ var outTextAssem = Changeset.stringAssembler();
+ var opAssem = Changeset.smartOpAssembler();
+ var oldLen = origText.length;
+
+ var nextOp = Changeset.newOp();
+ function appendMultilineOp(opcode, txt) {
+ nextOp.opcode = opcode;
+ if (withAttribs) {
+ nextOp.attribs = randomTwoPropAttribs(opcode, rand);
+ }
+ txt.replace(/\n|[^\n]+/g, function (t) {
+ if (t == '\n') {
+ nextOp.chars = 1;
+ nextOp.lines = 1;
+ opAssem.append(nextOp);
+ }
+ else {
+ nextOp.chars = t.length;
+ nextOp.lines = 0;
+ opAssem.append(nextOp);
+ }
+ return '';
+ });
+ }
+
+ function doOp() {
+ var o = randomStringOperation(textLeft.length, rand);
+ if (o.insert) {
+ var txt = o.insert;
+ charBank.append(txt);
+ outTextAssem.append(txt);
+ appendMultilineOp('+', txt);
+ }
+ else if (o.skip) {
+ var txt = textLeft.substring(0, o.skip);
+ textLeft = textLeft.substring(o.skip);
+ outTextAssem.append(txt);
+ appendMultilineOp('=', txt);
+ }
+ else if (o.remove) {
+ var txt = textLeft.substring(0, o.remove);
+ textLeft = textLeft.substring(o.remove);
+ appendMultilineOp('-', txt);
+ }
+ }
+
+ while (textLeft.length > 1) doOp();
+ for(var i=0;i<5;i++) doOp(); // do some more (only insertions will happen)
+
+ var outText = outTextAssem.toString()+'\n';
+ opAssem.endDocument();
+ var cs = Changeset.pack(oldLen, outText.length, opAssem.toString(), charBank.toString());
+ Changeset.checkRep(cs);
+ return [cs, outText];
+ }
+
+ function testCompose(randomSeed) {
+ var rand = new java.util.Random(randomSeed);
+ print("> testCompose#"+randomSeed);
+
+ var p = new AttribPool();
+
+ var startText = randomMultiline(10, 20, rand)+'\n';
+
+ var x1 = randomTestChangeset(startText, rand);
+ var change1 = x1[0];
+ var text1 = x1[1];
+
+ var x2 = randomTestChangeset(text1, rand);
+ var change2 = x2[0];
+ var text2 = x2[1];
+
+ var x3 = randomTestChangeset(text2, rand);
+ var change3 = x3[0];
+ var text3 = x3[1];
+
+ //print(literal(Changeset.toBaseTen(startText)));
+ //print(literal(Changeset.toBaseTen(change1)));
+ //print(literal(Changeset.toBaseTen(change2)));
+ var change12 = Changeset.checkRep(Changeset.compose(change1, change2, p));
+ var change23 = Changeset.checkRep(Changeset.compose(change2, change3, p));
+ var change123 = Changeset.checkRep(Changeset.compose(change12, change3, p));
+ var change123a = Changeset.checkRep(Changeset.compose(change1, change23, p));
+ assertEqualStrings(change123, change123a);
+
+ assertEqualStrings(text2, Changeset.applyToText(change12, startText));
+ assertEqualStrings(text3, Changeset.applyToText(change23, text1));
+ assertEqualStrings(text3, Changeset.applyToText(change123, startText));
+ }
+
+ for(var i=0;i<30;i++) testCompose(i);
+
+ (function simpleComposeAttributesTest() {
+ print("> simpleComposeAttributesTest");
+ var p = new AttribPool();
+ p.putAttrib(['bold','']);
+ p.putAttrib(['bold','true']);
+ var cs1 = Changeset.checkRep("Z:2>1*1+1*1=1$x");
+ var cs2 = Changeset.checkRep("Z:3>0*0|1=3$");
+ var cs12 = Changeset.checkRep(Changeset.compose(cs1, cs2, p));
+ assertEqualStrings("Z:2>1+1*0|1=2$x", cs12);
+ })();
+
+ (function followAttributesTest() {
+ var p = new AttribPool();
+ p.putAttrib(['x','']);
+ p.putAttrib(['x','abc']);
+ p.putAttrib(['x','def']);
+ p.putAttrib(['y','']);
+ p.putAttrib(['y','abc']);
+ p.putAttrib(['y','def']);
+
+ function testFollow(a, b, afb, bfa, merge) {
+ assertEqualStrings(afb, Changeset.followAttributes(a, b, p));
+ assertEqualStrings(bfa, Changeset.followAttributes(b, a, p));
+ assertEqualStrings(merge, Changeset.composeAttributes(a, afb, true, p));
+ assertEqualStrings(merge, Changeset.composeAttributes(b, bfa, true, p));
+ }
+
+ testFollow('', '', '', '', '');
+ testFollow('*0', '', '', '*0', '*0');
+ testFollow('*0', '*0', '', '', '*0');
+ testFollow('*0', '*1', '', '*0', '*0');
+ testFollow('*1', '*2', '', '*1', '*1');
+ testFollow('*0*1', '', '', '*0*1', '*0*1');
+ testFollow('*0*4', '*2*3', '*3', '*0', '*0*3');
+ testFollow('*0*4', '*2', '', '*0*4', '*0*4');
+ })();
+
+ function testFollow(randomSeed) {
+ var rand = new java.util.Random(randomSeed + 1000);
+ print("> testFollow#"+randomSeed);
+
+ var p = new AttribPool();
+
+ var startText = randomMultiline(10, 20, rand)+'\n';
+
+ var cs1 = randomTestChangeset(startText, rand)[0];
+ var cs2 = randomTestChangeset(startText, rand)[0];
+
+ var afb = Changeset.checkRep(Changeset.follow(cs1, cs2, false, p));
+ var bfa = Changeset.checkRep(Changeset.follow(cs2, cs1, true, p));
+
+ var merge1 = Changeset.checkRep(Changeset.compose(cs1, afb));
+ var merge2 = Changeset.checkRep(Changeset.compose(cs2, bfa));
+
+ assertEqualStrings(merge1, merge2);
+ }
+
+ for(var i=0;i<30;i++) testFollow(i);
+
+ function testSplitJoinAttributionLines(randomSeed) {
+ var rand = new java.util.Random(randomSeed + 2000);
+ print("> testSplitJoinAttributionLines#"+randomSeed);
+
+ var doc = randomMultiline(10, 20, rand)+'\n';
+
+ function stringToOps(str) {
+ var assem = Changeset.mergingOpAssembler();
+ var o = Changeset.newOp('+');
+ o.chars = 1;
+ for(var i=0;i<str.length;i++) {
+ var c = str.charAt(i);
+ o.lines = (c == '\n' ? 1 : 0);
+ o.attribs = (c == 'a' || c == 'b' ? '*'+c : '');
+ assem.append(o);
+ }
+ return assem.toString();
+ }
+
+ var theJoined = stringToOps(doc);
+ var theSplit = doc.match(/[^\n]*\n/g).map(stringToOps);
+
+ assertEqualArrays(theSplit, Changeset.splitAttributionLines(theJoined, doc));
+ assertEqualStrings(theJoined, Changeset.joinAttributionLines(theSplit));
+ }
+
+ for(var i=0;i<10;i++) testSplitJoinAttributionLines(i);
+
+ (function testMoveOpsToNewPool() {
+ print("> testMoveOpsToNewPool");
+
+ var pool1 = new AttribPool();
+ var pool2 = new AttribPool();
+
+ pool1.putAttrib(['baz','qux']);
+ pool1.putAttrib(['foo','bar']);
+
+ pool2.putAttrib(['foo','bar']);
+
+ assertEqualStrings(Changeset.moveOpsToNewPool('Z:1>2*1+1*0+1$ab', pool1, pool2), 'Z:1>2*0+1*1+1$ab');
+ assertEqualStrings(Changeset.moveOpsToNewPool('*1+1*0+1', pool1, pool2), '*0+1*1+1');
+ })();
+
+
+ (function testMakeSplice() {
+ print("> testMakeSplice");
+
+ var t = "a\nb\nc\n";
+ var t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, "def"), t);
+ assertEqualStrings("a\nb\ncdef\n", t2);
+
+ })();
+
+ (function testToSplices() {
+ print("> testToSplices");
+
+ var cs = Changeset.checkRep('Z:z>9*0=1=4-3+9=1|1-4-4+1*0+a$123456789abcdefghijk');
+ var correctSplices = [[5, 8, "123456789"], [9, 17, "abcdefghijk"]];
+ assertEqualArrays(correctSplices, Changeset.toSplices(cs));
+ })();
+
+ function testCharacterRangeFollow(testId, cs, oldRange, insertionsAfter, correctNewRange) {
+ print("> testCharacterRangeFollow#"+testId);
+
+ var cs = Changeset.checkRep(cs);
+ assertEqualArrays(correctNewRange, Changeset.characterRangeFollow(cs, oldRange[0], oldRange[1],
+ insertionsAfter));
+
+ }
+
+ testCharacterRangeFollow(1, 'Z:z>9*0=1=4-3+9=1|1-4-4+1*0+a$123456789abcdefghijk',
+ [7, 10], false, [14, 15]);
+ testCharacterRangeFollow(2, "Z:bc<6|x=b4|2-6$", [400, 407], false, [400, 401]);
+ testCharacterRangeFollow(3, "Z:4>0-3+3$abc", [0,3], false, [3,3]);
+ testCharacterRangeFollow(4, "Z:4>0-3+3$abc", [0,3], true, [0,0]);
+ testCharacterRangeFollow(5, "Z:5>1+1=1-3+3$abcd", [1,4], false, [5,5]);
+ testCharacterRangeFollow(6, "Z:5>1+1=1-3+3$abcd", [1,4], true, [2,2]);
+ testCharacterRangeFollow(7, "Z:5>1+1=1-3+3$abcd", [0,6], false, [1,7]);
+ testCharacterRangeFollow(8, "Z:5>1+1=1-3+3$abcd", [0,3], false, [1,2]);
+ testCharacterRangeFollow(9, "Z:5>1+1=1-3+3$abcd", [2,5], false, [5,6]);
+ testCharacterRangeFollow(10, "Z:2>1+1$a", [0,0], false, [1,1]);
+ testCharacterRangeFollow(11, "Z:2>1+1$a", [0,0], true, [0,0]);
+
+ (function testOpAttributeValue() {
+ print("> testOpAttributeValue");
+
+ var p = new AttribPool();
+ p.putAttrib(['name','david']);
+ p.putAttrib(['color','green']);
+
+ assertEqualStrings("david", Changeset.opAttributeValue(Changeset.stringOp('*0*1+1'), 'name', p));
+ assertEqualStrings("david", Changeset.opAttributeValue(Changeset.stringOp('*0+1'), 'name', p));
+ assertEqualStrings("", Changeset.opAttributeValue(Changeset.stringOp('*1+1'), 'name', p));
+ assertEqualStrings("", Changeset.opAttributeValue(Changeset.stringOp('+1'), 'name', p));
+ assertEqualStrings("green", Changeset.opAttributeValue(Changeset.stringOp('*0*1+1'), 'color', p));
+ assertEqualStrings("green", Changeset.opAttributeValue(Changeset.stringOp('*1+1'), 'color', p));
+ assertEqualStrings("", Changeset.opAttributeValue(Changeset.stringOp('*0+1'), 'color', p));
+ assertEqualStrings("", Changeset.opAttributeValue(Changeset.stringOp('+1'), 'color', p));
+ })();
+
+ function testAppendATextToAssembler(testId, atext, correctOps) {
+ print("> testAppendATextToAssembler#"+testId);
+
+ var assem = Changeset.smartOpAssembler();
+ Changeset.appendATextToAssembler(atext, assem);
+ assertEqualStrings(correctOps, assem.toString());
+ }
+
+ testAppendATextToAssembler(1, {text:"\n", attribs:"|1+1"}, "");
+ testAppendATextToAssembler(2, {text:"\n\n", attribs:"|2+2"}, "|1+1");
+ testAppendATextToAssembler(3, {text:"\n\n", attribs:"*x|2+2"}, "*x|1+1");
+ testAppendATextToAssembler(4, {text:"\n\n", attribs:"*x|1+1|1+1"}, "*x|1+1");
+ testAppendATextToAssembler(5, {text:"foo\n", attribs:"|1+4"}, "+3");
+ testAppendATextToAssembler(6, {text:"\nfoo\n", attribs:"|2+5"}, "|1+1+3");
+ testAppendATextToAssembler(7, {text:"\nfoo\n", attribs:"*x|2+5"}, "*x|1+1*x+3");
+ testAppendATextToAssembler(8, {text:"\n\n\nfoo\n", attribs:"|2+2*x|2+5"}, "|2+2*x|1+1*x+3");
+
+ function testMakeAttribsString(testId, pool, opcode, attribs, correctString) {
+ print("> testMakeAttribsString#"+testId);
+
+ var p = poolOrArray(pool);
+ var str = Changeset.makeAttribsString(opcode, attribs, p);
+ assertEqualStrings(correctString, str);
+ }
+
+ testMakeAttribsString(1, ['bold,'], '+', [['bold','']], '');
+ testMakeAttribsString(2, ['abc,def','bold,'], '=', [['bold','']], '*1');
+ testMakeAttribsString(3, ['abc,def','bold,true'], '+', [['abc','def'],['bold','true']], '*0*1');
+ testMakeAttribsString(4, ['abc,def','bold,true'], '+', [['bold','true'],['abc','def']], '*0*1');
+
+ function testSubattribution(testId, astr, start, end, correctOutput) {
+ print("> testSubattribution#"+testId);
+
+ var str = Changeset.subattribution(astr, start, end);
+ assertEqualStrings(correctOutput, str);
+ }
+
+ testSubattribution(1, "+1", 0, 0, "");
+ testSubattribution(2, "+1", 0, 1, "+1");
+ testSubattribution(3, "+1", 0, undefined, "+1");
+ testSubattribution(4, "|1+1", 0, 0, "");
+ testSubattribution(5, "|1+1", 0, 1, "|1+1");
+ testSubattribution(6, "|1+1", 0, undefined, "|1+1");
+ testSubattribution(7, "*0+1", 0, 0, "");
+ testSubattribution(8, "*0+1", 0, 1, "*0+1");
+ testSubattribution(9, "*0+1", 0, undefined, "*0+1");
+ testSubattribution(10, "*0|1+1", 0, 0, "");
+ testSubattribution(11, "*0|1+1", 0, 1, "*0|1+1");
+ testSubattribution(12, "*0|1+1", 0, undefined, "*0|1+1");
+ testSubattribution(13, "*0+2+1*1+3", 0, 1, "*0+1");
+ testSubattribution(14, "*0+2+1*1+3", 0, 2, "*0+2");
+ testSubattribution(15, "*0+2+1*1+3", 0, 3, "*0+2+1");
+ testSubattribution(16, "*0+2+1*1+3", 0, 4, "*0+2+1*1+1");
+ testSubattribution(17, "*0+2+1*1+3", 0, 5, "*0+2+1*1+2");
+ testSubattribution(18, "*0+2+1*1+3", 0, 6, "*0+2+1*1+3");
+ testSubattribution(19, "*0+2+1*1+3", 0, 7, "*0+2+1*1+3");
+ testSubattribution(20, "*0+2+1*1+3", 0, undefined, "*0+2+1*1+3");
+ testSubattribution(21, "*0+2+1*1+3", 1, undefined, "*0+1+1*1+3");
+ testSubattribution(22, "*0+2+1*1+3", 2, undefined, "+1*1+3");
+ testSubattribution(23, "*0+2+1*1+3", 3, undefined, "*1+3");
+ testSubattribution(24, "*0+2+1*1+3", 4, undefined, "*1+2");
+ testSubattribution(25, "*0+2+1*1+3", 5, undefined, "*1+1");
+ testSubattribution(26, "*0+2+1*1+3", 6, undefined, "");
+ testSubattribution(27, "*0+2+1*1|1+3", 0, 1, "*0+1");
+ testSubattribution(28, "*0+2+1*1|1+3", 0, 2, "*0+2");
+ testSubattribution(29, "*0+2+1*1|1+3", 0, 3, "*0+2+1");
+ testSubattribution(30, "*0+2+1*1|1+3", 0, 4, "*0+2+1*1+1");
+ testSubattribution(31, "*0+2+1*1|1+3", 0, 5, "*0+2+1*1+2");
+ testSubattribution(32, "*0+2+1*1|1+3", 0, 6, "*0+2+1*1|1+3");
+ testSubattribution(33, "*0+2+1*1|1+3", 0, 7, "*0+2+1*1|1+3");
+ testSubattribution(34, "*0+2+1*1|1+3", 0, undefined, "*0+2+1*1|1+3");
+ testSubattribution(35, "*0+2+1*1|1+3", 1, undefined, "*0+1+1*1|1+3");
+ testSubattribution(36, "*0+2+1*1|1+3", 2, undefined, "+1*1|1+3");
+ testSubattribution(37, "*0+2+1*1|1+3", 3, undefined, "*1|1+3");
+ testSubattribution(38, "*0+2+1*1|1+3", 4, undefined, "*1|1+2");
+ testSubattribution(39, "*0+2+1*1|1+3", 5, undefined, "*1|1+1");
+ testSubattribution(40, "*0+2+1*1|1+3", 1, 5, "*0+1+1*1+2");
+ testSubattribution(41, "*0+2+1*1|1+3", 2, 6, "+1*1|1+3");
+ testSubattribution(42, "*0+2+1*1+3", 2, 6, "+1*1+3");
+
+ function testFilterAttribNumbers(testId, cs, filter, correctOutput) {
+ print("> testFilterAttribNumbers#"+testId);
+
+ var str = Changeset.filterAttribNumbers(cs, filter);
+ assertEqualStrings(correctOutput, str);
+ }
+
+ testFilterAttribNumbers(1, "*0*1+1+2+3*1+4*2+5*0*2*1*b*c+6",
+ function(n) { return (n%2) == 0; },
+ "*0+1+2+3+4*2+5*0*2*c+6");
+ testFilterAttribNumbers(2, "*0*1+1+2+3*1+4*2+5*0*2*1*b*c+6",
+ function(n) { return (n%2) == 1; },
+ "*1+1+2+3*1+4+5*1*b+6");
+
+ function testInverse(testId, cs, lines, alines, pool, correctOutput) {
+ print("> testInverse#"+testId);
+
+ pool = poolOrArray(pool);
+ var str = Changeset.inverse(Changeset.checkRep(cs), lines, alines, pool);
+ assertEqualStrings(correctOutput, str);
+ }
+
+ // take "FFFFTTTTT" and apply "-FT--FFTT", the inverse of which is "--F--TT--"
+ testInverse(1, "Z:9>0=1*0=1*1=1=2*0=2*1|1=2$", null, ["+4*1+5"], ['bold,','bold,true'],
+ "Z:9>0=2*0=1=2*1=2$");
+
+ function testMutateTextLines(testId, cs, lines, correctLines) {
+ print("> testMutateTextLines#"+testId);
+
+ var a = lines.slice();
+ Changeset.mutateTextLines(cs, a);
+ assertEqualArrays(correctLines, a);
+ }
+
+ testMutateTextLines(1, "Z:4<1|1-2-1|1+1+1$\nc", ["a\n", "b\n"], ["\n", "c\n"]);
+ testMutateTextLines(2, "Z:4>0|1-2-1|2+3$\nc\n", ["a\n", "b\n"], ["\n", "c\n", "\n"]);
+
+ function testInverseRandom(randomSeed) {
+ var rand = new java.util.Random(randomSeed + 3000);
+ print("> testInverseRandom#"+randomSeed);
+
+ var p = poolOrArray(['apple,','apple,true','banana,','banana,true']);
+
+ var startText = randomMultiline(10, 20, rand)+'\n';
+ var alines = Changeset.splitAttributionLines(Changeset.makeAttribution(startText), startText);
+ var lines = startText.slice(0,-1).split('\n').map(function(s) { return s+'\n'; });
+
+ var stylifier = randomTestChangeset(startText, rand, true)[0];
+
+ //print(alines.join('\n'));
+ Changeset.mutateAttributionLines(stylifier, alines, p);
+ //print(stylifier);
+ //print(alines.join('\n'));
+ Changeset.mutateTextLines(stylifier, lines);
+
+ var changeset = randomTestChangeset(lines.join(''), rand, true)[0];
+ var inverseChangeset = Changeset.inverse(changeset, lines, alines, p);
+
+ var origLines = lines.slice();
+ var origALines = alines.slice();
+
+ Changeset.mutateTextLines(changeset, lines);
+ Changeset.mutateAttributionLines(changeset, alines, p);
+ //print(origALines.join('\n'));
+ //print(changeset);
+ //print(inverseChangeset);
+ //print(origLines.map(function(s) { return '1: '+s.slice(0,-1); }).join('\n'));
+ //print(lines.map(function(s) { return '2: '+s.slice(0,-1); }).join('\n'));
+ //print(alines.join('\n'));
+ Changeset.mutateTextLines(inverseChangeset, lines);
+ Changeset.mutateAttributionLines(inverseChangeset, alines, p);
+ //print(lines.map(function(s) { return '3: '+s.slice(0,-1); }).join('\n'));
+
+ assertEqualArrays(origLines, lines);
+ assertEqualArrays(origALines, alines);
+ }
+
+ for(var i=0;i<30;i++) testInverseRandom(i);
+} \ No newline at end of file
diff --git a/infrastructure/ace/www/editor.css b/infrastructure/ace/www/editor.css
new file mode 100644
index 0000000..0a43478
--- /dev/null
+++ b/infrastructure/ace/www/editor.css
@@ -0,0 +1,109 @@
+
+/* These CSS rules are included in both the outer and inner ACE iframe.
+ Also see inner.css, included only in the inner one.
+*/
+
+body {
+ margin: 0;
+ white-space: nowrap;
+}
+
+#outerdocbody {
+ background-color: #fff;
+}
+body.grayedout { background-color: #eee !important }
+
+#innerdocbody {
+ font-size: 12px; /* overridden by body.style */
+ font-family: monospace; /* overridden by body.style */
+ line-height: 16px; /* overridden by body.style */
+}
+
+body.doesWrap {
+ white-space: normal;
+}
+
+#innerdocbody {
+ padding-top: 1px; /* important for some reason? */
+ padding-right: 10px;
+ padding-bottom: 8px;
+ padding-left: 1px /* prevents characters from looking chopped off in FF3 */;
+ overflow: hidden;
+ /* blank 1x1 gif, so that IE8 doesn't consider the body transparent */
+ background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==);
+}
+
+#sidediv {
+ font-size: 11px;
+ font-family: monospace;
+ line-height: 16px; /* overridden by sideDiv.style */
+ padding-top: 8px; /* EDIT_BODY_PADDING_TOP */
+ padding-right: 3px; /* LINE_NUMBER_PADDING_RIGHT - 1 */
+ position: absolute;
+ width: 20px; /* MIN_LINEDIV_WIDTH */
+ top: 0;
+ left: 0;
+ cursor: default;
+ color: white;
+}
+
+#sidedivinner {
+ text-align: right;
+}
+
+.sidedivdelayed { /* class set after sizes are set */
+ background-color: #eee;
+ color: #888 !important;
+ border-right: 1px solid #999;
+}
+.sidedivhidden {
+ display: none;
+}
+
+#outerdocbody iframe {
+ display: block; /* codemirror says it suppresses bugs */
+ position: relative;
+ left: 32px; /* MIN_LINEDIV_WIDTH + LINE_NUMBER_PADDING_RIGHT + EDIT_BODY_PADDING_LEFT */
+ top: 7px; /* EDIT_BODY_PADDING_TOP - 1*/
+ border: 0;
+ width: 1px; /* changed programmatically */
+ height: 1px; /* changed programmatically */
+}
+
+#outerdocbody .hotrect {
+ border: 1px solid #999;
+ position: absolute;
+}
+
+/* cause "body" area (e.g. where clicks are heard) to grow horizontally with text */
+body.mozilla, body.safari {
+ display: table-cell;
+}
+
+body.doesWrap {
+ display: block !important;
+}
+
+.safari div {
+ /* prevents the caret from disappearing on the longest line of the doc */
+ padding-right: 1px;
+}
+
+p {
+ margin: 0;
+}
+
+/*b, strong, .Apple-style-span { font-weight: normal !important; font-style: normal !important;
+ color: red !important; }*/
+
+#linemetricsdiv {
+ position: absolute;
+ left: -1000px;
+ top: -1000px;
+ color: white;
+ z-index: -1;
+ font-size: 12px; /* overridden by lineMetricsDiv.style */
+ font-family: monospace; /* overridden by lineMetricsDiv.style */
+}
+
+#overlaysdiv { position: absolute; left: -1000px; top: -1000px; } \ No newline at end of file
diff --git a/infrastructure/ace/www/firebug/errorIcon.png b/infrastructure/ace/www/firebug/errorIcon.png
new file mode 100644
index 0000000..2d75261
--- /dev/null
+++ b/infrastructure/ace/www/firebug/errorIcon.png
Binary files differ
diff --git a/infrastructure/ace/www/firebug/firebug.css b/infrastructure/ace/www/firebug/firebug.css
new file mode 100644
index 0000000..1f041c4
--- /dev/null
+++ b/infrastructure/ace/www/firebug/firebug.css
@@ -0,0 +1,209 @@
+
+html, body {
+ margin: 0;
+ background: #FFFFFF;
+ font-family: Lucida Grande, Tahoma, sans-serif;
+ font-size: 11px;
+ overflow: hidden;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.toolbar {
+ height: 14px;
+ border-top: 1px solid ThreeDHighlight;
+ border-bottom: 1px solid ThreeDShadow;
+ padding: 2px 6px;
+ background: ThreeDFace;
+}
+
+.toolbarRight {
+ position: absolute;
+ top: 4px;
+ right: 6px;
+}
+
+#log {
+ overflow: auto;
+ position: absolute;
+ left: 0;
+ width: 100%;
+}
+
+#commandLine {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 18px;
+ border: none;
+ border-top: 1px solid ThreeDShadow;
+}
+
+/************************************************************************************************/
+
+.logRow {
+ position: relative;
+ border-bottom: 1px solid #D7D7D7;
+ padding: 2px 4px 1px 6px;
+ background-color: #FFFFFF;
+}
+
+.logRow-command {
+ font-family: Monaco, monospace;
+ color: blue;
+}
+
+.objectBox-null {
+ padding: 0 2px;
+ border: 1px solid #666666;
+ background-color: #888888;
+ color: #FFFFFF;
+}
+
+.objectBox-string {
+ font-family: Monaco, monospace;
+ color: red;
+ white-space: pre;
+}
+
+.objectBox-number {
+ color: #000088;
+}
+
+.objectBox-function {
+ font-family: Monaco, monospace;
+ color: DarkGreen;
+}
+
+.objectBox-object {
+ color: DarkGreen;
+ font-weight: bold;
+}
+
+/************************************************************************************************/
+
+.logRow-info,
+.logRow-error,
+.logRow-warning {
+ background: #FFFFFF no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+
+.logRow-info {
+ background-image: url(infoIcon.png);
+}
+
+.logRow-warning {
+ background-color: cyan;
+ background-image: url(warningIcon.png);
+}
+
+.logRow-error {
+ background-color: LightYellow;
+ background-image: url(errorIcon.png);
+}
+
+.errorMessage {
+ vertical-align: top;
+ color: #FF0000;
+}
+
+.objectBox-sourceLink {
+ position: absolute;
+ right: 4px;
+ top: 2px;
+ padding-left: 8px;
+ font-family: Lucida Grande, sans-serif;
+ font-weight: bold;
+ color: #0000FF;
+}
+
+/************************************************************************************************/
+
+.logRow-group {
+ background: #EEEEEE;
+ border-bottom: none;
+}
+
+.logGroup {
+ background: #EEEEEE;
+}
+
+.logGroupBox {
+ margin-left: 24px;
+ border-top: 1px solid #D7D7D7;
+ border-left: 1px solid #D7D7D7;
+}
+
+/************************************************************************************************/
+
+.selectorTag,
+.selectorId,
+.selectorClass {
+ font-family: Monaco, monospace;
+ font-weight: normal;
+}
+
+.selectorTag {
+ color: #0000FF;
+}
+
+.selectorId {
+ color: DarkBlue;
+}
+
+.selectorClass {
+ color: red;
+}
+
+/************************************************************************************************/
+
+.objectBox-element {
+ font-family: Monaco, monospace;
+ color: #000088;
+}
+
+.nodeChildren {
+ margin-left: 16px;
+}
+
+.nodeTag {
+ color: blue;
+}
+
+.nodeValue {
+ color: #FF0000;
+ font-weight: normal;
+}
+
+.nodeText,
+.nodeComment {
+ margin: 0 2px;
+ vertical-align: top;
+}
+
+.nodeText {
+ color: #333333;
+}
+
+.nodeComment {
+ color: DarkGreen;
+}
+
+/************************************************************************************************/
+
+.propertyNameCell {
+ vertical-align: top;
+}
+
+.propertyName {
+ font-weight: bold;
+}
diff --git a/infrastructure/ace/www/firebug/firebug.html b/infrastructure/ace/www/firebug/firebug.html
new file mode 100644
index 0000000..861e639
--- /dev/null
+++ b/infrastructure/ace/www/firebug/firebug.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <title>Firebug</title>
+ <link rel="stylesheet" type="text/css" href="firebug.css">
+</head>
+
+<body>
+ <div id="toolbar" class="toolbar">
+ <a href="#" onclick="parent.console.clear()">Clear</a>
+ <span class="toolbarRight">
+ <a href="#" onclick="parent.console.close()">Close</a>
+ </span>
+ </div>
+ <div id="log"></div>
+ <input type="text" id="commandLine">
+
+ <script>parent.onFirebugReady(document);</script>
+</body>
+</html>
diff --git a/infrastructure/ace/www/firebug/firebug.js b/infrastructure/ace/www/firebug/firebug.js
new file mode 100644
index 0000000..d3c1978
--- /dev/null
+++ b/infrastructure/ace/www/firebug/firebug.js
@@ -0,0 +1,688 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+if (!("console" in window) || !("firebug" in console)) {
+(function()
+{
+ window.console =
+ {
+ log: function()
+ {
+ logFormatted(arguments, "");
+ },
+
+ debug: function()
+ {
+ logFormatted(arguments, "debug");
+ },
+
+ info: function()
+ {
+ logFormatted(arguments, "info");
+ },
+
+ warn: function()
+ {
+ logFormatted(arguments, "warning");
+ },
+
+ error: function()
+ {
+ logFormatted(arguments, "error");
+ },
+
+ assert: function(truth, message)
+ {
+ if (!truth)
+ {
+ var args = [];
+ for (var i = 1; i < arguments.length; ++i)
+ args.push(arguments[i]);
+
+ logFormatted(args.length ? args : ["Assertion Failure"], "error");
+ throw message ? message : "Assertion Failure";
+ }
+ },
+
+ dir: function(object)
+ {
+ var html = [];
+
+ var pairs = [];
+ for (var name in object)
+ {
+ try
+ {
+ pairs.push([name, object[name]]);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
+
+ html.push('<table>');
+ for (var i = 0; i < pairs.length; ++i)
+ {
+ var name = pairs[i][0], value = pairs[i][1];
+
+ html.push('<tr>',
+ '<td class="propertyNameCell"><span class="propertyName">',
+ escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
+ appendObject(value, html);
+ html.push('</span></td></tr>');
+ }
+ html.push('</table>');
+
+ logRow(html, "dir");
+ },
+
+ dirxml: function(node)
+ {
+ var html = [];
+
+ appendNode(node, html);
+ logRow(html, "dirxml");
+ },
+
+ group: function()
+ {
+ logRow(arguments, "group", pushGroup);
+ },
+
+ groupEnd: function()
+ {
+ logRow(arguments, "", popGroup);
+ },
+
+ time: function(name)
+ {
+ timeMap[name] = (new Date()).getTime();
+ },
+
+ timeEnd: function(name)
+ {
+ if (name in timeMap)
+ {
+ var delta = (new Date()).getTime() - timeMap[name];
+ logFormatted([name+ ":", delta+"ms"]);
+ delete timeMap[name];
+ }
+ },
+
+ count: function()
+ {
+ this.warn(["count() not supported."]);
+ },
+
+ trace: function()
+ {
+ this.warn(["trace() not supported."]);
+ },
+
+ profile: function()
+ {
+ this.warn(["profile() not supported."]);
+ },
+
+ profileEnd: function()
+ {
+ },
+
+ clear: function()
+ {
+ consoleBody.innerHTML = "";
+ },
+
+ open: function()
+ {
+ toggleConsole(true);
+ },
+
+ close: function()
+ {
+ if (frameVisible)
+ toggleConsole();
+ }
+ };
+
+ // ********************************************************************************************
+
+ var consoleFrame = null;
+ var consoleBody = null;
+ var commandLine = null;
+
+ var frameVisible = false;
+ var messageQueue = [];
+ var groupStack = [];
+ var timeMap = {};
+
+ var clPrefix = ">>> ";
+
+ var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
+ var isIE = navigator.userAgent.indexOf("MSIE") != -1;
+ var isOpera = navigator.userAgent.indexOf("Opera") != -1;
+ var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
+
+ // ********************************************************************************************
+
+ function toggleConsole(forceOpen)
+ {
+ frameVisible = forceOpen || !frameVisible;
+ if (consoleFrame)
+ consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
+ else
+ waitForBody();
+ }
+
+ function focusCommandLine()
+ {
+ toggleConsole(true);
+ if (commandLine)
+ commandLine.focus();
+ }
+
+ function waitForBody()
+ {
+ if (document.body)
+ createFrame();
+ else
+ setTimeout(waitForBody, 200);
+ }
+
+ function createFrame()
+ {
+ if (consoleFrame)
+ return;
+
+ window.onFirebugReady = function(doc)
+ {
+ window.onFirebugReady = null;
+
+ var toolbar = doc.getElementById("toolbar");
+ toolbar.onmousedown = onSplitterMouseDown;
+
+ commandLine = doc.getElementById("commandLine");
+ addEvent(commandLine, "keydown", onCommandLineKeyDown);
+
+ addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ consoleBody = doc.getElementById("log");
+ layout();
+ flush();
+ }
+
+ var baseURL = getFirebugURL();
+
+ consoleFrame = document.createElement("iframe");
+ consoleFrame.setAttribute("src", baseURL+"/firebug.html");
+ consoleFrame.setAttribute("frameBorder", "0");
+ consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
+ consoleFrame.style.zIndex = "2147483647";
+ consoleFrame.style.position = "fixed";
+ consoleFrame.style.width = "100%";
+ consoleFrame.style.left = "0";
+ consoleFrame.style.bottom = "0";
+ consoleFrame.style.height = "200px";
+ document.body.appendChild(consoleFrame);
+ }
+
+ function getFirebugURL()
+ {
+ var scripts = document.getElementsByTagName("script");
+ for (var i = 0; i < scripts.length; ++i)
+ {
+ if (scripts[i].src.indexOf("firebug.js") != -1)
+ {
+ var lastSlash = scripts[i].src.lastIndexOf("/");
+ return scripts[i].src.substr(0, lastSlash);
+ }
+ }
+ }
+
+ function evalCommandLine()
+ {
+ var text = commandLine.value;
+ commandLine.value = "";
+
+ logRow([clPrefix, text], "command");
+
+ var value;
+ try
+ {
+ value = eval(text);
+ }
+ catch (exc)
+ {
+ }
+
+ console.log(value);
+ }
+
+ function layout()
+ {
+ var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
+ var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
+ consoleBody.style.top = toolbar.offsetHeight + "px";
+ consoleBody.style.height = height + "px";
+
+ commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
+ }
+
+ function logRow(message, className, handler)
+ {
+ if (consoleBody)
+ writeMessage(message, className, handler);
+ else
+ {
+ messageQueue.push([message, className, handler]);
+ waitForBody();
+ }
+ }
+
+ function flush()
+ {
+ var queue = messageQueue;
+ messageQueue = [];
+
+ for (var i = 0; i < queue.length; ++i)
+ writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+ }
+
+ function writeMessage(message, className, handler)
+ {
+ var isScrolledToBottom =
+ consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
+
+ if (!handler)
+ handler = writeRow;
+
+ handler(message, className);
+
+ if (isScrolledToBottom)
+ consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
+ }
+
+ function appendRow(row)
+ {
+ var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
+ container.appendChild(row);
+ }
+
+ function writeRow(message, className)
+ {
+ var row = consoleBody.ownerDocument.createElement("div");
+ row.className = "logRow" + (className ? " logRow-"+className : "");
+ row.innerHTML = message.join("");
+ appendRow(row);
+ }
+
+ function pushGroup(message, className)
+ {
+ logFormatted(message, className);
+
+ var groupRow = consoleBody.ownerDocument.createElement("div");
+ groupRow.className = "logGroup";
+ var groupRowBox = consoleBody.ownerDocument.createElement("div");
+ groupRowBox.className = "logGroupBox";
+ groupRow.appendChild(groupRowBox);
+ appendRow(groupRowBox);
+ groupStack.push(groupRowBox);
+ }
+
+ function popGroup()
+ {
+ groupStack.pop();
+ }
+
+ // ********************************************************************************************
+
+ function logFormatted(objects, className)
+ {
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if (typeof(format) != "string")
+ {
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+ for (var i = 0; i < parts.length; ++i)
+ {
+ var part = parts[i];
+ if (part && typeof(part) == "object")
+ {
+ var object = objects[++objIndex];
+ part.appender(object, html);
+ }
+ else
+ appendText(part, html);
+ }
+
+ for (var i = objIndex+1; i < objects.length; ++i)
+ {
+ appendText(" ", html);
+
+ var object = objects[i];
+ if (typeof(object) == "string")
+ appendText(object, html);
+ else
+ appendObject(object, html);
+ }
+
+ logRow(html, className);
+ }
+
+ function parseFormat(format)
+ {
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for (var m = reg.exec(format); m; m = reg.exec(format))
+ {
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+ }
+
+ function escapeHTML(value)
+ {
+ function replaceChars(ch)
+ {
+ switch (ch)
+ {
+ case "<":
+ return "&lt;";
+ case ">":
+ return "&gt;";
+ case "&":
+ return "&amp;";
+ case "'":
+ return "&#39;";
+ case '"':
+ return "&quot;";
+ }
+ return "?";
+ };
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function objectToString(object)
+ {
+ try
+ {
+ return object+"";
+ }
+ catch (exc)
+ {
+ return null;
+ }
+ }
+
+ // ********************************************************************************************
+
+ function appendText(object, html)
+ {
+ html.push(escapeHTML(objectToString(object)));
+ }
+
+ function appendNull(object, html)
+ {
+ html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendString(object, html)
+ {
+ html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
+ '&quot;</span>');
+ }
+
+ function appendInteger(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFloat(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFunction(object, html)
+ {
+ var reName = /function ?(.*?)\(/;
+ var m = reName.exec(objectToString(object));
+ var name = m ? m[1] : "function";
+ html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
+ }
+
+ function appendObject(object, html)
+ {
+ try
+ {
+ if (object == undefined)
+ appendNull("undefined", html);
+ else if (object == null)
+ appendNull("null", html);
+ else if (typeof object == "string")
+ appendString(object, html);
+ else if (typeof object == "number")
+ appendInteger(object, html);
+ else if (typeof object == "function")
+ appendFunction(object, html);
+ else if (object.nodeType == 1)
+ appendSelector(object, html);
+ else if (typeof object == "object")
+ appendObjectFormatted(object, html);
+ else
+ appendText(object, html);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ function appendObjectFormatted(object, html)
+ {
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
+ }
+
+ function appendSelector(object, html)
+ {
+ html.push('<span class="objectBox-selector">');
+
+ html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+ if (object.id)
+ html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+ if (object.className)
+ html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+
+ html.push('</span>');
+ }
+
+ function appendNode(node, html)
+ {
+ if (node.nodeType == 1)
+ {
+ html.push(
+ '<div class="objectBox-element">',
+ '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+ for (var i = 0; i < node.attributes.length; ++i)
+ {
+ var attr = node.attributes[i];
+ if (!attr.specified)
+ continue;
+
+ html.push('&nbsp;<span class="nodeName">', attr.nodeName.toLowerCase(),
+ '</span>=&quot;<span class="nodeValue">', escapeHTML(attr.nodeValue),
+ '</span>&quot;')
+ }
+
+ if (node.firstChild)
+ {
+ html.push('&gt;</div><div class="nodeChildren">');
+
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ appendNode(child, html);
+
+ html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
+ node.nodeName.toLowerCase(), '&gt;</span></div>');
+ }
+ else
+ html.push('/&gt;</div>');
+ }
+ else if (node.nodeType == 3)
+ {
+ html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
+ '</div>');
+ }
+ }
+
+ // ********************************************************************************************
+
+ function addEvent(object, name, handler)
+ {
+ if (document.all)
+ object.attachEvent("on"+name, handler);
+ else
+ object.addEventListener(name, handler, false);
+ }
+
+ function removeEvent(object, name, handler)
+ {
+ if (document.all)
+ object.detachEvent("on"+name, handler);
+ else
+ object.removeEventListener(name, handler, false);
+ }
+
+ function cancelEvent(event)
+ {
+ if (document.all)
+ event.cancelBubble = true;
+ else
+ event.stopPropagation();
+ }
+
+ function onError(msg, href, lineNo)
+ {
+ var html = [];
+
+ var lastSlash = href.lastIndexOf("/");
+ var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+
+ html.push(
+ '<span class="errorMessage">', msg, '</span>',
+ '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+ );
+
+ logRow(html, "error");
+ };
+
+ function onKeyDown(event)
+ {
+ if (event.keyCode == 123)
+ toggleConsole();
+ else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
+ && (event.metaKey || event.ctrlKey))
+ focusCommandLine();
+ else
+ return;
+
+ cancelEvent(event);
+ }
+
+ function onSplitterMouseDown(event)
+ {
+ if (isSafari || isOpera)
+ return;
+
+ addEvent(document, "mousemove", onSplitterMouseMove);
+ addEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onSplitterMouseMove(event)
+ {
+ var win = document.all
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument.defaultView;
+
+ var clientY = event.clientY;
+ if (win != win.parent)
+ clientY += win.frameElement ? win.frameElement.offsetTop : 0;
+
+ var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
+ var y = height - clientY;
+
+ consoleFrame.style.height = y + "px";
+ layout();
+ }
+
+ function onSplitterMouseUp(event)
+ {
+ removeEvent(document, "mousemove", onSplitterMouseMove);
+ removeEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onCommandLineKeyDown(event)
+ {
+ if (event.keyCode == 13)
+ evalCommandLine();
+ else if (event.keyCode == 27)
+ commandLine.value = "";
+ }
+
+ window.onerror = onError;
+ addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ if (document.documentElement.getAttribute("debug") == "true")
+ toggleConsole(true);
+})();
+}
diff --git a/infrastructure/ace/www/firebug/firebugx.js b/infrastructure/ace/www/firebug/firebugx.js
new file mode 100644
index 0000000..b2cc49c
--- /dev/null
+++ b/infrastructure/ace/www/firebug/firebugx.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+if (!("console" in window) || !("firebug" in console))
+{
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {}
+} \ No newline at end of file
diff --git a/infrastructure/ace/www/firebug/infoIcon.png b/infrastructure/ace/www/firebug/infoIcon.png
new file mode 100644
index 0000000..da1e533
--- /dev/null
+++ b/infrastructure/ace/www/firebug/infoIcon.png
Binary files differ
diff --git a/infrastructure/ace/www/firebug/warningIcon.png b/infrastructure/ace/www/firebug/warningIcon.png
new file mode 100644
index 0000000..de51084
--- /dev/null
+++ b/infrastructure/ace/www/firebug/warningIcon.png
Binary files differ
diff --git a/infrastructure/ace/www/index.html b/infrastructure/ace/www/index.html
new file mode 100644
index 0000000..a1e6e96
--- /dev/null
+++ b/infrastructure/ace/www/index.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head>
+ <title>A Code Editor</title>
+ <script src="jquery-1.2.1.js"></script>
+ <!-- DEBUG -->
+ <script src="ace2_outer.js"></script>
+ <script src="firebug/firebugx.js"></script>
+ <!-- /DEBUG -->
+ <script src="testcode.js"></script>
+ <!-- PROD: <script src="ace2.js"></script> -->
+ <script>
+ $(document).ready(function() {
+ var editor = new Ace2Editor();
+ editor.init("editorcontainer", getTestCode(), editorReady);
+
+ editor.setOnKeyPress(function (evt) {
+ if (evt.ctrlKey && evt.which == "s".charCodeAt(0)) {
+ alert("You tried to save.");
+ return false;
+ }
+ return true;
+ });
+
+ function editorReady() {
+ resizeEditor();
+ $(window).bind("resize", resizeEditor);
+ setTimeout(function() {editor.focus();}, 0);
+ }
+
+ function resizeEditor() {
+ $("#editorcontainer").get(0).style.height = "100%";
+ editor.getFrame().style.height = ((document.documentElement.clientHeight)-1)+"px";
+ editor.adjustSize();
+ }
+ });
+ </script>
+ <style>
+ html { overflow: hidden } /* for Win IE 6 */
+ body { margin:0; padding:0; border:0; overflow: hidden; }
+ #editorcontainer { height: 1000px; /* changed programmatically */ }
+ #editorcontainer iframe { width: 100%; height: 100%; border:0; padding:0; margin:0; }
+ </style>
+ </head>
+ <body>
+ <div id="editorcontainer"><!-- --></div>
+ </body>
+</html>
diff --git a/infrastructure/ace/www/inner.css b/infrastructure/ace/www/inner.css
new file mode 100644
index 0000000..7479cfe
--- /dev/null
+++ b/infrastructure/ace/www/inner.css
@@ -0,0 +1,48 @@
+
+/* Firefox (3) is bad about keeping the text cursor in design mode;
+ various actions (clicking, dragging, scroll-wheel) lose it and it
+ doesn't come back easily, presumably because of optimizations.
+ These rules try to maximize the chance Firefox will think the cursor
+ needs changing again.
+*/
+html { cursor: text; } /* in Safari, produces text cursor for whole doc (inc. below body) */
+span { cursor: auto; }
+
+a { cursor: pointer !important; }
+
+/*span { padding-bottom: 1px; }/* padding-top: 1px; }*/
+
+/*.inspoint_atstart_generic { background: transparent url(/genimg/solid/2x10/000000.gif) repeat-y left top }
+.inspoint_atend_generic { background: transparent url(/genimg/solid/2x10/000000.gif) repeat-y right top }*/
+
+/*div { background: transparent url(/static/img/acecarets/default.gif) repeat-y left top }*/
+
+/*tt { padding-left: 3px; padding-right: 3px; margin-right: -3px; margin-left: -3px; }*/
+
+/*div { display: list-item; list-style: disc outside; margin-left: 20px; }*/
+/*div:before { content:"foo" }*/
+
+ul, ol, li {
+ padding: 0;
+ margin: 0;
+}
+ul { margin-left: 1.5em; }
+ul ul { margin-left: 0 !important; }
+ul.list-bullet1 { margin-left: 1.5em; }
+ul.list-bullet2 { margin-left: 3em; }
+ul.list-bullet3 { margin-left: 4.5em; }
+ul.list-bullet4 { margin-left: 6em; }
+ul.list-bullet5 { margin-left: 7.5em; }
+ul.list-bullet6 { margin-left: 9em; }
+ul.list-bullet7 { margin-left: 10.5em; }
+ul.list-bullet8 { margin-left: 12em; }
+
+ul { list-style-type: disc; }
+ul.list-bullet1 { list-style-type: disc; }
+ul.list-bullet2 { list-style-type: circle; }
+ul.list-bullet3 { list-style-type: square; }
+ul.list-bullet4 { list-style-type: disc; }
+ul.list-bullet5 { list-style-type: circle; }
+ul.list-bullet6 { list-style-type: square; }
+ul.list-bullet7 { list-style-type: disc; }
+ul.list-bullet8 { list-style-type: circle; }
diff --git a/infrastructure/ace/www/jquery-1.2.1.js b/infrastructure/ace/www/jquery-1.2.1.js
new file mode 100644
index 0000000..b4eb132
--- /dev/null
+++ b/infrastructure/ace/www/jquery-1.2.1.js
@@ -0,0 +1,2992 @@
+(function(){
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+ var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(selector, context) {
+ // If the context is a namespace object, return a new object
+ return this instanceof jQuery ?
+ this.init(selector, context) :
+ new jQuery(selector, context);
+};
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+ var _$ = $;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function(selector, context) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle HTML strings
+ if ( typeof selector == "string" ) {
+ var m = quickExpr.exec(selector);
+ if ( m && (m[1] || !context) ) {
+ // HANDLE: $(html) -> $(array)
+ if ( m[1] )
+ selector = jQuery.clean( [ m[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var tmp = document.getElementById( m[3] );
+ if ( tmp )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( tmp.id != m[3] )
+ return jQuery().find( selector );
+ else {
+ this[0] = tmp;
+ this.length = 1;
+ return this;
+ }
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction(selector) )
+ return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object is passed as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ jquery: "1.2.1",
+
+ size: function() {
+ return this.length;
+ },
+
+ length: 0,
+
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[num];
+ },
+
+ pushStack: function( a ) {
+ var ret = jQuery(a);
+ ret.prevObject = this;
+ return ret;
+ },
+
+ setArray: function( a ) {
+ this.length = 0;
+ Array.prototype.push.apply( this, a );
+ return this;
+ },
+
+ each: function( fn, args ) {
+ return jQuery.each( this, fn, args );
+ },
+
+ index: function( obj ) {
+ var pos = -1;
+ this.each(function(i){
+ if ( this == obj ) pos = i;
+ });
+ return pos;
+ },
+
+ attr: function( key, value, type ) {
+ var obj = key;
+
+ // Look for the case where we're accessing a style value
+ if ( key.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+ else {
+ obj = {};
+ obj[ key ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(index){
+ // Set all the styles
+ for ( var prop in obj )
+ jQuery.attr(
+ type ? this.style : this,
+ prop, jQuery.prop(this, obj[prop], type, index, prop)
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function(e) {
+ if ( typeof e != "object" && e != null )
+ return this.empty().append( document.createTextNode( e ) );
+
+ var t = "";
+ jQuery.each( e || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ t += this.nodeType != 1 ?
+ this.nodeValue : jQuery.fn.text([ this ]);
+ });
+ });
+ return t;
+ },
+
+ wrapAll: function(html) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery(html, this[0].ownerDocument)
+ .clone()
+ .insertBefore(this[0])
+ .map(function(){
+ var elem = this;
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function(html) {
+ return this.each(function(){
+ jQuery(this).contents().wrapAll(html);
+ });
+ },
+
+ wrap: function(html) {
+ return this.each(function(){
+ jQuery(this).wrapAll(html);
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, 1, function(a){
+ this.appendChild( a );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, -1, function(a){
+ this.insertBefore( a, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, 1, function(a){
+ this.parentNode.insertBefore( a, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, -1, function(a){
+ this.parentNode.insertBefore( a, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery([]);
+ },
+
+ find: function(t) {
+ var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
+ return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
+ jQuery.unique( data ) : data );
+ },
+
+ clone: function(events) {
+ // Do the clone
+ var ret = this.map(function(){
+ return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if (events === true)
+ this.find("*").andSelf().each(function(i) {
+ var events = jQuery.data(this, "events");
+ for ( var type in events )
+ for ( var handler in events[type] )
+ jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function(t) {
+ return this.pushStack(
+ jQuery.isFunction( t ) &&
+ jQuery.grep(this, function(el, index){
+ return t.apply(el, [index]);
+ }) ||
+
+ jQuery.multiFilter(t,this) );
+ },
+
+ not: function(t) {
+ return this.pushStack(
+ t.constructor == String &&
+ jQuery.multiFilter(t, this, true) ||
+
+ jQuery.grep(this, function(a) {
+ return ( t.constructor == Array || t.jquery )
+ ? jQuery.inArray( a, t ) < 0
+ : a != t;
+ })
+ );
+ },
+
+ add: function(t) {
+ return this.pushStack( jQuery.merge(
+ this.get(),
+ t.constructor == String ?
+ jQuery(t).get() :
+ t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
+ t : [t] )
+ );
+ },
+
+ is: function(expr) {
+ return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+ },
+
+ hasClass: function(expr) {
+ return this.is("." + expr);
+ },
+
+ val: function( val ) {
+ if ( val == undefined ) {
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName(elem, "select") ) {
+ var index = elem.selectedIndex,
+ a = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[i];
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return val;
+
+ // Multi-Selects return an array
+ a.push(val);
+ }
+ }
+
+ return a;
+
+ // Everything else, we just grab the value
+ } else
+ return this[0].value.replace(/\r/g, "");
+ }
+ } else
+ return this.each(function(){
+ if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
+ this.checked = (jQuery.inArray(this.value, val) >= 0 ||
+ jQuery.inArray(this.name, val) >= 0);
+ else if ( jQuery.nodeName(this, "select") ) {
+ var tmp = val.constructor == Array ? val : [val];
+
+ jQuery("option", this).each(function(){
+ this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
+ jQuery.inArray(this.text, tmp) >= 0);
+ });
+
+ if ( !tmp.length )
+ this.selectedIndex = -1;
+ } else
+ this.value = val;
+ });
+ },
+
+ html: function( val ) {
+ return val == undefined ?
+ ( this.length ? this[0].innerHTML : null ) :
+ this.empty().append( val );
+ },
+
+ replaceWith: function( val ) {
+ return this.after( val ).remove();
+ },
+
+ eq: function(i){
+ return this.slice(i, i+1);
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function(fn) {
+ return this.pushStack(jQuery.map( this, function(elem,i){
+ return fn.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function(args, table, dir, fn) {
+ var clone = this.length > 1, a;
+
+ return this.each(function(){
+ if ( !a ) {
+ a = jQuery.clean(args, this.ownerDocument);
+ if ( dir < 0 )
+ a.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+
+ jQuery.each( a, function(){
+ var elem = clone ? this.cloneNode(true) : this;
+ if ( !evalScript(0, elem) )
+ fn.call( obj, elem );
+ });
+ });
+ }
+};
+
+function evalScript(i, elem){
+ var script = jQuery.nodeName(elem, "script");
+
+ if ( script ) {
+ if ( elem.src )
+ jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild(elem);
+
+ } else if ( elem.nodeType == 1 )
+ jQuery("script", elem).each(evalScript);
+
+ return script;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( al == 1 ) {
+ target = this;
+ a = 0;
+ }
+
+ var prop;
+
+ for ( ; a < al; a++ )
+ // Only deal with non-null/undefined values
+ if ( (prop = arguments[a]) != null )
+ // Extend the base object
+ for ( var i in prop ) {
+ // Prevent never-ending loop
+ if ( target == prop[i] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && typeof prop[i] == 'object' && target[i] )
+ jQuery.extend( target[i], prop[i] );
+
+ // Don't bring in undefined values
+ else if ( prop[i] != undefined )
+ target[i] = prop[i];
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+
+jQuery.extend({
+ noConflict: function(deep) {
+ window.$ = _$;
+ if ( deep )
+ window.jQuery = _jQuery;
+ return jQuery;
+ },
+
+ // This may seem like some crazy code, but trust me when I say that this
+ // is the only cross-browser way to do this. --John
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a XML document
+ isXMLDoc: function(elem) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ // Evaluates Async. in Safari 2 :-(
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+ if ( data ) {
+ if ( window.execScript )
+ window.execScript( data );
+ else if ( jQuery.browser.safari )
+ // safari doesn't provide a synchronous global eval
+ window.setTimeout( data, 0 );
+ else
+ eval.call( window, data );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ? jQuery.cache[ id ][ name ] : id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+ for ( name in jQuery.cache[ id ] ) break;
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( obj, fn, args ) {
+ if ( args ) {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.apply( obj[i], args );
+ else
+ for ( var i = 0, ol = obj.length; i < ol; i++ )
+ if ( fn.apply( obj[i], args ) === false ) break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.call( obj[i], i, obj[i] );
+ else
+ for ( var i = 0, ol = obj.length, val = obj[0];
+ i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ }
+
+ return obj;
+ },
+
+ prop: function(elem, value, type, index, prop){
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, [index] );
+
+ // exclude the following css properties to add px
+ var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, c ){
+ jQuery.each( (c || "").split(/\s+/), function(i, cur){
+ if ( !jQuery.className.has( elem.className, cur ) )
+ elem.className += ( elem.className ? " " : "" ) + cur;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, c ){
+ elem.className = c != undefined ?
+ jQuery.grep( elem.className.split(/\s+/), function(cur){
+ return !jQuery.className.has( c, cur );
+ }).join(" ") : "";
+ },
+
+ // internal only, use is(".class")
+ has: function( t, c ) {
+ return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ swap: function(e,o,f) {
+ for ( var i in o ) {
+ e.style["old"+i] = e.style[i];
+ e.style[i] = o[i];
+ }
+ f.apply( e, [] );
+ for ( var i in o )
+ e.style[i] = e.style["old"+i];
+ },
+
+ css: function(e,p) {
+ if ( p == "height" || p == "width" ) {
+ var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+
+ jQuery.each( d, function(){
+ old["padding" + this] = 0;
+ old["border" + this + "Width"] = 0;
+ });
+
+ jQuery.swap( e, old, function() {
+ if ( jQuery(e).is(':visible') ) {
+ oHeight = e.offsetHeight;
+ oWidth = e.offsetWidth;
+ } else {
+ e = jQuery(e.cloneNode(true))
+ .find(":radio").removeAttr("checked").end()
+ .css({
+ visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
+ }).appendTo(e.parentNode)[0];
+
+ var parPos = jQuery.css(e.parentNode,"position") || "static";
+ if ( parPos == "static" )
+ e.parentNode.style.position = "relative";
+
+ oHeight = e.clientHeight;
+ oWidth = e.clientWidth;
+
+ if ( parPos == "static" )
+ e.parentNode.style.position = "static";
+
+ e.parentNode.removeChild(e);
+ }
+ });
+
+ return p == "height" ? oHeight : oWidth;
+ }
+
+ return jQuery.curCSS( e, p );
+ },
+
+ curCSS: function(elem, prop, force) {
+ var ret, stack = [], swap = [];
+
+ // A helper method for determining if an element's values are broken
+ function color(a){
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle(a,null);
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ if (prop == "opacity" && jQuery.browser.msie) {
+ ret = jQuery.attr(elem.style, "opacity");
+ return ret == "" ? "1" : ret;
+ }
+
+ if (prop.match(/float/i))
+ prop = styleFloat;
+
+ if (!force && elem.style[prop])
+ ret = elem.style[prop];
+
+ else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+ if (prop.match(/float/i))
+ prop = "float";
+
+ prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+ var cur = document.defaultView.getComputedStyle(elem, null);
+
+ if ( cur && !color(elem) )
+ ret = cur.getPropertyValue(prop);
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( a = 0; a < stack.length; a++ )
+ if ( color(stack[a]) ) {
+ swap[a] = stack[a].style.display;
+ stack[a].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = prop == "display" && swap[stack.length-1] != null ?
+ "none" :
+ document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+ // Finally, revert the display styles back
+ for ( a = 0; a < swap.length; a++ )
+ if ( swap[a] != null )
+ stack[a].style.display = swap[a];
+ }
+
+ if ( prop == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if (elem.currentStyle) {
+ var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
+ ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
+ var style = elem.style.left;
+ var runtimeStyle = elem.runtimeStyle.left;
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function(a, doc) {
+ var r = [];
+ doc = doc || document;
+
+ jQuery.each( a, function(i,arg){
+ if ( !arg ) return;
+
+ if ( arg.constructor == Number )
+ arg = arg.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof arg == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+
+ var wrap =
+ // option or optgroup
+ !s.indexOf("<opt") &&
+ [1, "<select>", "</select>"] ||
+
+ !s.indexOf("<leg") &&
+ [1, "<fieldset>", "</fieldset>"] ||
+
+ s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [1, "<table>", "</table>"] ||
+
+ !s.indexOf("<tr") &&
+ [2, "<table><tbody>", "</tbody></table>"] ||
+
+ // <thead> matched above
+ (!s.indexOf("<td") || !s.indexOf("<th")) &&
+ [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+
+ !s.indexOf("<col") &&
+ [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [1, "div<div>", "</div>"] ||
+
+ [0,"",""];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + arg + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
+ tb = div.firstChild && div.firstChild.childNodes;
+
+ // String was a bare <thead> or <tfoot>
+ else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
+ tb = div.childNodes;
+
+ for ( var n = tb.length-1; n >= 0 ; --n )
+ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
+ tb[n].parentNode.removeChild(tb[n]);
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test(arg) )
+ div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ arg = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
+ return;
+
+ if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
+ r.push( arg );
+ else
+ r = jQuery.merge( r, arg );
+
+ });
+
+ return r;
+ },
+
+ attr: function(elem, name, value){
+ var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[name] ) {
+ if ( value != undefined ) elem[fix[name]] = value;
+ return elem[fix[name]];
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
+ return elem.getAttributeNode(name).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode )
+ throw "type property can't be changed";
+ elem.setAttribute( name, value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
+ (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
+ }
+ name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
+ if ( value != undefined ) elem[name] = value;
+ return elem[name];
+ }
+ },
+
+ trim: function(t){
+ return (t||"").replace(/^\s+|\s+$/g, "");
+ },
+
+ makeArray: function( a ) {
+ var r = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof a != "array" )
+ for ( var i = 0, al = a.length; i < al; i++ )
+ r.push( a[i] );
+ else
+ r = a.slice( 0 );
+
+ return r;
+ },
+
+ inArray: function( b, a ) {
+ for ( var i = 0, al = a.length; i < al; i++ )
+ if ( a[i] == b )
+ return i;
+ return -1;
+ },
+
+ merge: function(first, second) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[i]; i++ )
+ if ( second[i].nodeType != 8 )
+ first.push(second[i]);
+ } else
+ for ( var i = 0; second[i]; i++ )
+ first.push(second[i]);
+
+ return first;
+ },
+
+ unique: function(first) {
+ var r = [], done = {};
+
+ try {
+ for ( var i = 0, fl = first.length; i < fl; i++ ) {
+ var id = jQuery.data(first[i]);
+ if ( !done[id] ) {
+ done[id] = true;
+ r.push(first[i]);
+ }
+ }
+ } catch(e) {
+ r = first;
+ }
+
+ return r;
+ },
+
+ grep: function(elems, fn, inv) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, el = elems.length; i < el; i++ )
+ if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
+ result.push( elems[i] );
+
+ return result;
+ },
+
+ map: function(elems, fn) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, el = elems.length; i < el; i++ ) {
+ var val = fn(elems[i],i);
+
+ if ( val !== null && val != undefined ) {
+ if ( val.constructor != Array ) val = [val];
+ result = result.concat( val );
+ }
+ }
+
+ return result;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(userAgent),
+ opera: /opera/.test(userAgent),
+ msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+ mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+};
+
+var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength"
+ }
+});
+
+jQuery.each({
+ parent: "a.parentNode",
+ parents: "jQuery.dir(a,'parentNode')",
+ next: "jQuery.nth(a,2,'nextSibling')",
+ prev: "jQuery.nth(a,2,'previousSibling')",
+ nextAll: "jQuery.dir(a,'nextSibling')",
+ prevAll: "jQuery.dir(a,'previousSibling')",
+ siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
+ children: "jQuery.sibling(a.firstChild)",
+ contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
+}, function(i,n){
+ jQuery.fn[ i ] = function(a) {
+ var ret = jQuery.map(this,n);
+ if ( a && typeof a == "string" )
+ ret = jQuery.multiFilter(a,ret);
+ return this.pushStack( jQuery.unique(ret) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(i,n){
+ jQuery.fn[ i ] = function(){
+ var a = arguments;
+ return this.each(function(){
+ for ( var j = 0, al = a.length; j < al; j++ )
+ jQuery(a[j])[n]( this );
+ });
+ };
+});
+
+jQuery.each( {
+ removeAttr: function( key ) {
+ jQuery.attr( this, key, "" );
+ this.removeAttribute( key );
+ },
+ addClass: function(c){
+ jQuery.className.add(this,c);
+ },
+ removeClass: function(c){
+ jQuery.className.remove(this,c);
+ },
+ toggleClass: function( c ){
+ jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
+ },
+ remove: function(a){
+ if ( !a || jQuery.filter( a, [this] ).r.length ) {
+ jQuery.removeData( this );
+ this.parentNode.removeChild( this );
+ }
+ },
+ empty: function() {
+ // Clean up the cache
+ jQuery("*", this).each(function(){ jQuery.removeData(this); });
+
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(i,n){
+ jQuery.fn[ i ] = function() {
+ return this.each( n, arguments );
+ };
+});
+
+jQuery.each( [ "Height", "Width" ], function(i,name){
+ var n = name.toLowerCase();
+
+ jQuery.fn[ n ] = function(h) {
+ return this[0] == window ?
+ jQuery.browser.safari && self["inner" + name] ||
+ jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
+ document.body["client" + name] :
+
+ this[0] == document ?
+ Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
+
+ h == undefined ?
+ ( this.length ? jQuery.css( this[0], n ) : null ) :
+ this.css( n, h.constructor == String ? h : h + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
+ "#": "a.getAttribute('id')==m[2]",
+ ":": {
+ // Position Checks
+ lt: "i<m[3]-0",
+ gt: "i>m[3]-0",
+ nth: "m[3]-0==i",
+ eq: "m[3]-0==i",
+ first: "i==0",
+ last: "i==r.length-1",
+ even: "i%2==0",
+ odd: "i%2",
+
+ // Child Checks
+ "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
+ "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
+ "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+
+ // Parent Checks
+ parent: "a.firstChild",
+ empty: "!a.firstChild",
+
+ // Text Check
+ contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",
+
+ // Visibility
+ visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
+ hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+
+ // Form attributes
+ enabled: "!a.disabled",
+ disabled: "a.disabled",
+ checked: "a.checked",
+ selected: "a.selected||jQuery.attr(a,'selected')",
+
+ // Form elements
+ text: "'text'==a.type",
+ radio: "'radio'==a.type",
+ checkbox: "'checkbox'==a.type",
+ file: "'file'==a.type",
+ password: "'password'==a.type",
+ submit: "'submit'==a.type",
+ image: "'image'==a.type",
+ reset: "'reset'==a.type",
+ button: '"button"==a.type||jQuery.nodeName(a,"button")',
+ input: "/input|select|textarea|button/i.test(a.nodeName)",
+
+ // :has()
+ has: "jQuery.find(m[3],a).length",
+
+ // :header
+ header: "/h\\d/i.test(a.nodeName)",
+
+ // :animated
+ animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // Make sure that the context is a DOM Element
+ if ( context && !context.nodeType )
+ context = null;
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ var nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var nodeName = m[2], merge = {};
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ r = jQuery.filter(m[3], r, true).r;
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ test = /(\d*)n\+?(\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
+ first = (test[1] || 1) - 0, last = test[2] - 0;
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 1 ) {
+ if ( last == 0 || node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex + last) % first == 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var f = jQuery.expr[m[1]];
+ if ( typeof f != "string" )
+ f = jQuery.expr[m[1]][m[2]];
+
+ // Build a custom macro to enclose it
+ f = eval("false||function(a,i){return " + f + "}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, f, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(element, type, handler, data) {
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && element.setInterval != undefined )
+ element = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Init the element's event structure
+ var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
+
+ var handle = jQuery.data(element, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(element, arguments);
+
+ return val;
+ });
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // And bind the global event handler to the element
+ if (element.addEventListener)
+ element.addEventListener(type, handle, false);
+ else
+ element.attachEvent("on" + type, handle);
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ this.global[type] = true;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(element, type, handler) {
+ var events = jQuery.data(element, "events"), ret, index;
+
+ // Namespaced event handlers
+ if ( typeof type == "string" ) {
+ var parts = type.split(".");
+ type = parts[0];
+ }
+
+ if ( events ) {
+ // type is actually an event object here
+ if ( type && type.type ) {
+ handler = type.handler;
+ type = type.type;
+ }
+
+ if ( !type ) {
+ for ( type in events )
+ this.remove( element, type );
+
+ } else if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if (element.removeEventListener)
+ element.removeEventListener(type, jQuery.data(element, "handle"), false);
+ else
+ element.detachEvent("on" + type, jQuery.data(element, "handle"));
+ ret = null;
+ delete events[type];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ jQuery.removeData( element, "events" );
+ jQuery.removeData( element, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, element, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ // Handle a global trigger
+ if ( !element ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ evt = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( evt )
+ data.unshift( this.fix({ type: type, target: element }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
+ val = jQuery.data(element, "handle").apply( element, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( evt )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && extra.apply( element, data ) === false )
+ val = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
+ this.triggered = true;
+ element[ type ]();
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in c ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = c[j];
+ args[0].data = c[j].data;
+
+ // Filter the functions by class
+ if ( !parts[1] || c[j].type == parts[1] ) {
+ var tmp = c[j].apply( this, args );
+
+ if ( val !== false )
+ val = tmp;
+
+ if ( tmp === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target && event.srcElement )
+ event.target = event.srcElement;
+
+ // check if target is a textnode (safari)
+ if (jQuery.browser.safari && event.target.nodeType == 3)
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var e = document.documentElement, b = document.body;
+ event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
+ event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && (event.charCode || event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var a = arguments;
+
+ return this.click(function(e) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ e.preventDefault();
+
+ // and execute the function
+ return a[this.lastToggle].apply( this, [e] ) || false;
+ });
+ },
+
+ hover: function(f,g) {
+
+ // A private function for handling mouse 'hovering'
+ function handleHover(e) {
+ // Check if mouse(over|out) are still within the same parent element
+ var p = e.relatedTarget;
+
+ // Traverse up the tree
+ while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
+
+ // If we actually just moused on to a sub-element, ignore it
+ if ( p == this ) return false;
+
+ // Execute the right function
+ return (e.type == "mouseover" ? f : g).apply(this, [e]);
+ }
+
+ // Bind the function to the two event listeners
+ return this.mouseover(handleHover).mouseout(handleHover);
+ },
+
+ ready: function(f) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ f.apply( document, [jQuery] );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ /*
+ * All the code that makes DOM Ready work nicely.
+ */
+ isReady: false,
+ readyList: [],
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+ // Remove event listener to avoid memory leak
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // Remove script element used by IE hack
+ if( !window.frames.length ) // don't remove if frames are present (#1187)
+ jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+ }
+ }
+});
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i,o){
+
+ // Handle event binding
+ jQuery.fn[o] = function(f){
+ return f ? this.bind(o, f) : this.trigger(o);
+ };
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // If Mozilla is used
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used, use the excellent hack by Matthias Miller
+ // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
+ else if ( jQuery.browser.msie ) {
+
+ // Only works if you document.write() it
+ document.write("<scr" + "ipt id=__ie_init defer=true " +
+ "src=//:><\/script>");
+
+ // Use the defer script hack
+ var script = document.getElementById("__ie_init");
+
+ // script does not exist if jQuery is loaded dynamically
+ if ( script )
+ script.onreadystatechange = function() {
+ if ( this.readyState != "complete" ) return;
+ jQuery.ready();
+ };
+
+ // Clear from memory
+ script = null;
+
+ // If Safari is used
+ } else if ( jQuery.browser.safari )
+ // Continually check to see if the document.readyState is valid
+ jQuery.safariTimer = setInterval(function(){
+ // loaded and complete are both valid states
+ if ( document.readyState == "loaded" ||
+ document.readyState == "complete" ) {
+
+ // If either one are found, remove the timer
+ clearInterval( jQuery.safariTimer );
+ jQuery.safariTimer = null;
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ }, 10);
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ // Add delay to account for Safari's delay in globalEval
+ setTimeout(function(){
+ self.each( callback, [res.responseText, status, res] );
+ }, 13);
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=(\?|%3F)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = s.data.replace(jsre, "=" + jsonp);
+ s.url = s.url.replace(jsre, "=" + jsonp);
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime();
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script
+ if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+
+ // Handle Script loading
+ if ( !jsonp && (s.success || s.complete) ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async);
+
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock ? this.oldblock : "";
+ if ( jQuery.css(this,"display") == "none" )
+ this.style.display = "block";
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ if ( this.oldblock == "none" )
+ this.oldblock = "block";
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var opt = jQuery.speed(speed, easing, callback);
+
+ return this[ opt.queue === false ? "each" : "queue" ](function(){
+ opt = jQuery.extend({}, opt);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) ) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(){
+ var timers = jQuery.timers;
+
+ return this.each(function(){
+ for ( var i = 0; i < timers.length; i++ )
+ if ( timers[i].elem == this )
+ timers.splice(i--, 1);
+ }).dequeue();
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return;
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(){
+ return self.step();
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timers.length == 1 ) {
+ var timer = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length )
+ clearInterval( timer );
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(){
+ var t = (new Date()).getTime();
+
+ if ( t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var absolute = jQuery.css(elem, "position") == "absolute",
+ parent = elem.parentNode,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522;
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(
+ box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)
+ );
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ if ( msie ) {
+ var border = jQuery("html").css("borderWidth");
+ border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border;
+ add( -border, -border );
+ }
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table cells
+ if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
+ border( offsetParent );
+
+ // Safari <= 2 doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" )
+ absolute = true;
+
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Work around opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && absolute )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ return results;
+
+ function border(elem) {
+ add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+};
+})();
diff --git a/infrastructure/ace/www/lang_html.js b/infrastructure/ace/www/lang_html.js
new file mode 100644
index 0000000..f9eff8e
--- /dev/null
+++ b/infrastructure/ace/www/lang_html.js
@@ -0,0 +1,1685 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+grammars=(window.grammars||{});grammars["text.html.basic"]=(function(){var G=function(M,K,L){K.lastIndex=L;
+var J=K.exec(M);return !!(J&&J[0]);};var C=function(V,L,O,R,K,U,N,b,S){S=(S&&" "+S);var W=new Array(R.length+1);
+var P=L;var T=O[0].length;for(var X=0;X<N.length;X++){var a=N[X];var Z=K[a];if(Z<0){continue;}var Q=(W[a]===undefined);
+var J=L+T;var M=U[a];for(var Y=0;Y<M.length;Y++){J-=(O[M[Y]]||"").length;}if(Q){J-=(O[Z]||"").length;
+}if(J>P){b(V.substring(P,J),(S+W.join("")).substring(1));}P=J;if(Q){W[a]=" "+R[a];}else{delete W[a];}}if(P<L+T){b(V.substring(P,L+T),(S+W.join("")).substring(1));
+}};var F=function(R,U,L,Q,S,N,K,J,P,M,O){L.lastIndex=U;var T=L.exec(R);if(!T){return false;}if(T[Q]){return false;
+}O&&O();C(R,U,T,S,N,K,J,P,M);return[T[0].length];};var E=function(O,N,M,J,Q,L,K,P){return(M?F(O,N,M[0],M[1],J,M[2],M[3],Q,L,K,P):false);
+};var A=[/\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient)(\b)|([\s\S])/g,/(>)|([\s\S])/g,/(?=\n)|(\/)([igm]*)|([\s\S])/g,/\\.|([\s\S])/g,/(?=^\s*#\s*endif\b.*(?=\n))|([\s\S])/g,/(<\?)(\s*([\-_a-zA-Z0-9]+))|([\s\S])/g,/(<!)(DOCTYPE)|([\s\S])/g,/<[!%]\-\-|([\s\S])/g,/(<)(((?:([\-_a-zA-Z0-9]+)((:)))?([\-_a-zA-Z0-9:]+))((?=(\s[^>]*)?><\/\3>)))|([\s\S])/g,/(<\/?)((?:([\-_a-zA-Z0-9]+)((:)))?([\-_a-zA-Z0-9:]+))|([\s\S])/g,/(&)(([a-zA-Z0-9_\-]+|#[0-9]+|#x[0-9a-fA-F]+)(;))|([\s\S])/g,/&|([\s\S])/g,/<%@|([\s\S])/g,/<%[!=]?(?!\-\-)|([\s\S])/g,/<!\[CDATA\[|([\s\S])/g,/<|([\s\S])/g,/"|([\s\S])/g,/#(\\"|[^"])*(?="|(?=\n)\n?)|([\s\S])/g,/\-\-(\\"|[^"])*(?="|(?=\n)\n?)|([\s\S])/g,/'(?=[^']*?")|([\s\S])/g,/`(?=[^`]*?")|([\s\S])/g,/\\"(?!([^\\"]|\\[^"])*\\")(?=(\\[^"]|.)*?")|([\s\S])/g,/\\"|([\s\S])/g,/`|([\s\S])/g,/'|([\s\S])/g,/^\t*(TEXTILE)((?=\n))|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*)|([\s\S])/g,/^\s*(#\s*(endif)(\b))|([\s\S])/g,/^\s*(#\s*(else)(\b))|([\s\S])/g,/|([\s\S])/g,/"""|/g,/\1|([\s\S])/g,/^\s*(end tell)|([\s\S])/g,/(?:^\s*([cC][rR][eE][aA][tT][eE])(\s+([aA][gG][gG][rR][eE][gG][aA][tT][eE]|[cC][oO][nN][vV][eE][rR][sS][iI][oO][nN]|[dD][aA][tT][aA][bB][aA][sS][eE]|[dD][oO][mM][aA][iI][nN]|[fF][uU][nN][cC][tT][iI][oO][nN]|[gG][rR][oO][uU][pP]|([uU][nN][iI][qQ][uU][eE]\s+)?[iI][nN][dD][eE][xX]|[lL][aA][nN][gG][uU][aA][gG][eE]|[oO][pP][eE][rR][aA][tT][oO][rR] [cC][lL][aA][sS][sS]|[oO][pP][eE][rR][aA][tT][oO][rR]|[rR][uU][lL][eE]|[sS][cC][hH][eE][mM][aA]|[sS][eE][qQ][uU][eE][nN][cC][eE]|[tT][aA][bB][lL][eE]|[tT][aA][bB][lL][eE][sS][pP][aA][cC][eE]|[tT][rR][iI][gG][gG][eE][rR]|[tT][yY][pP][eE]|[uU][sS][eE][rR]|[vV][iI][eE][wW])(\s+)))((['"`]?)(\w+)(\7))|([\s\S])/g,/(?:^\s*([dD][rR][oO][pP])(\s+([aA][gG][gG][rR][eE][gG][aA][tT][eE]|[cC][oO][nN][vV][eE][rR][sS][iI][oO][nN]|[dD][aA][tT][aA][bB][aA][sS][eE]|[dD][oO][mM][aA][iI][nN]|[fF][uU][nN][cC][tT][iI][oO][nN]|[gG][rR][oO][uU][pP]|[iI][nN][dD][eE][xX]|[lL][aA][nN][gG][uU][aA][gG][eE]|[oO][pP][eE][rR][aA][tT][oO][rR] [cC][lL][aA][sS][sS]|[oO][pP][eE][rR][aA][tT][oO][rR]|[rR][uU][lL][eE]|[sS][cC][hH][eE][mM][aA]|[sS][eE][qQ][uU][eE][nN][cC][eE]|[tT][aA][bB][lL][eE]|[tT][aA][bB][lL][eE][sS][pP][aA][cC][eE]|[tT][rR][iI][gG][gG][eE][rR]|[tT][yY][pP][eE]|[uU][sS][eE][rR]|[vV][iI][eE][wW])))|([\s\S])/g,/(?:\s*([dD][rR][oO][pP])(\s+([tT][aA][bB][lL][eE])(\s+(\w+)((\s+[cC][aA][sS][cC][aA][dD][eE])?(\b)))))|([\s\S])/g,/(?:^\s*([aA][lL][tT][eE][rR])(\s+([aA][gG][gG][rR][eE][gG][aA][tT][eE]|[cC][oO][nN][vV][eE][rR][sS][iI][oO][nN]|[dD][aA][tT][aA][bB][aA][sS][eE]|[dD][oO][mM][aA][iI][nN]|[fF][uU][nN][cC][tT][iI][oO][nN]|[gG][rR][oO][uU][pP]|[iI][nN][dD][eE][xX]|[lL][aA][nN][gG][uU][aA][gG][eE]|[oO][pP][eE][rR][aA][tT][oO][rR] [cC][lL][aA][sS][sS]|[oO][pP][eE][rR][aA][tT][oO][rR]|[rR][uU][lL][eE]|[sS][cC][hH][eE][mM][aA]|[sS][eE][qQ][uU][eE][nN][cC][eE]|[tT][aA][bB][lL][eE]|[tT][aA][bB][lL][eE][sS][pP][aA][cC][eE]|[tT][rR][iI][gG][gG][eE][rR]|[tT][yY][pP][eE]|[uU][sS][eE][rR]|[vV][iI][eE][wW])(\s+)))|([\s\S])/g,/(?:\n\n\t\t\t\t# [nN][oO][rR][mM][aA][lL] [sS][tT][uU][fF][fF], [cC][aA][pP][tT][uU][rR][eE] 1\n\t\t\t\t \b([bB][iI][gG][iI][nN][tT]|[bB][iI][gG][sS][eE][rR][iI][aA][lL]|[bB][iI][tT]|[bB][oO][oO][lL][eE][aA][nN]|[bB][oO][xX]|[bB][yY][tT][eE][aA]|[cC][iI][dD][rR]|[cC][iI][rR][cC][lL][eE]|[dD][aA][tT][eE]|[dD][oO][uU][bB][lL][eE]\s[pP][rR][eE][cC][iI][sS][iI][oO][nN]|[iI][nN][eE][tT]|[iI][nN][tT]|[iI][nN][tT][eE][gG][eE][rR]|[lL][iI][nN][eE]|[lL][sS][eE][gG]|[mM][aA][cC][aA][dD][dD][rR]|[mM][oO][nN][eE][yY]|[oO][iI][dD]|[pP][aA][tT][hH]|[pP][oO][iI][nN][tT]|[pP][oO][lL][yY][gG][oO][nN]|[rR][eE][aA][lL]|[sS][eE][rR][iI][aA][lL]|[sS][mM][aA][lL][lL][iI][nN][tT]|[sS][yY][sS][dD][aA][tT][eE]|[tT][eE][xX][tT])(\b\n\n\t\t\t\t# [nN][uU][mM][eE][rR][iI][cC] [sS][uU][fF][fF][iI][xX], [cC][aA][pP][tT][uU][rR][eE] 2 + 3[iI]\n\t\t\t\t)|\b([bB][iI][tT]\s[vV][aA][rR][yY][iI][nN][gG]|[cC][hH][aA][rR][aA][cC][tT][eE][rR]\s(?:[vV][aA][rR][yY][iI][nN][gG])?|[tT][iI][nN][yY][iI][nN][tT]|[vV][aA][rR]\s[cC][hH][aA][rR]|[fF][lL][oO][aA][tT]|[iI][nN][tT][eE][rR][vV][aA][lL])(\((\d+)(\)\n\n\t\t\t\t# [oO][pP][tT][iI][oO][nN][aA][lL] [nN][uU][mM][eE][rR][iI][cC] [sS][uU][fF][fF][iI][xX], [cC][aA][pP][tT][uU][rR][eE] 4 + 5[iI]\n\t\t\t\t))|\b([cC][hH][aA][rR]|[nN][uU][mM][bB][eE][rR]|[vV][aA][rR][cC][hH][aA][rR]\d?)(\b(?:\((\d+)(\)))?(\n\n\t\t\t\t# [sS][pP][eE][cC][iI][aA][lL] [cC][aA][sS][eE], [cC][aA][pP][tT][uU][rR][eE] 6 + 7[iI] + 8[iI]\n\t\t\t\t))|\b([nN][uU][mM][eE][rR][iI][cC])(\b(?:\((\d+)(,(\d+)(\))))?(\n\n\t\t\t\t# [sS][pP][eE][cC][iI][aA][lL] [cC][aA][sS][eE], [cC][aA][pP][tT][uU][rR][eE][sS] 9, 10[iI], 11\n\t\t\t\t))|\b([tT][iI][mM][eE][sS])((?:\((\d+)(\)))((\s[wW][iI][tT][hH][oO][uU][tT][sS][tT][iI][mM][eE][sS][zZ][oO][nN][eE]\b)?(\n\n\t\t\t\t# [sS][pP][eE][cC][iI][aA][lL] [cC][aA][sS][eE], [cC][aA][pP][tT][uU][rR][eE][sS] 12, 13, 14[iI], 15\n\t\t\t\t)))|\b([tT][iI][mM][eE][sS][tT][aA][mM][pP])((?:([sS])(\((\d+)(\)(\s[wW][iI][tT][hH][oO][uU][tT][sS][tT][iI][mM][eE][sS][zZ][oO][nN][eE]\b)?)))?(\n\n\t\t\t)))|([\s\S])/g,/(?:\b((?:[pP][rR][iI][mM][aA][rR][yY]|[fF][oO][rR][eE][iI][gG][nN])\s+[kK][eE][yY]|[rR][eE][fF][eE][rR][eE][nN][cC][eE][sS]|[oO][nN]\s[dD][eE][lL][eE][tT][eE](\s+[cC][aA][sS][cC][aA][dD][eE])?|[cC][hH][eE][cC][kK]|[cC][oO][nN][sS][tT][rR][aA][iI][nN][tT])\b)|([\s\S])/g,/\b\d+\b|([\s\S])/g,/(?:\b([sS][eE][lL][eE][cC][tT](\s+[dD][iI][sS][tT][iI][nN][cC][tT])?|[iI][nN][sS][eE][rR][tT]\s+([iI][gG][nN][oO][rR][eE]\s+)?[iI][nN][tT][oO]|[uU][pP][dD][aA][tT][eE]|[dD][eE][lL][eE][tT][eE]|[fF][rR][oO][mM]|[sS][eE][tT]|[wW][hH][eE][rR][eE]|[gG][rR][oO][uU][pP]\s[bB][yY]|[oO][rR]|[lL][iI][kK][eE]|[aA][nN][dD]|[uU][nN][iI][oO][nN](\s+[aA][lL][lL])?|[hH][aA][vV][iI][nN][gG]|[oO][rR][dD][eE][rR]\s[bB][yY]|[lL][iI][mM][iI][tT]|([iI][nN][nN][eE][rR]|[cC][rR][oO][sS][sS])\s+[jJ][oO][iI][nN]|[jJ][oO][iI][nN]|[sS][tT][rR][aA][iI][gG][hH][tT]_[jJ][oO][iI][nN]|([lL][eE][fF][tT]|[rR][iI][gG][hH][tT])(\s+[oO][uU][tT][eE][rR])?\s+[jJ][oO][iI][nN]|[nN][aA][tT][uU][rR][aA][lL](\s+([lL][eE][fF][tT]|[rR][iI][gG][hH][tT])(\s+[oO][uU][tT][eE][rR])?)?\s+[jJ][oO][iI][nN])\b)|([\s\S])/g,/(?:\b([oO][nN]|(([iI][sS]\s+)?[nN][oO][tT]\s+)?[nN][uU][lL][lL])\b)|([\s\S])/g,/(?:\b[vV][aA][lL][uU][eE][sS]\b)|([\s\S])/g,/(?:\b([bB][eE][gG][iI][nN](\s+[wW][oO][rR][kK])?|[sS][tT][aA][rR][tT]\s+[tT][rR][aA][nN][sS][aA][cC][tT][iI][oO][nN]|[cC][oO][mM][mM][iI][tT](\s+[wW][oO][rR][kK])?|[rR][oO][lL][lL][bB][aA][cC][kK](\s+[wW][oO][rR][kK])?)\b)|([\s\S])/g,/(?:\b([gG][rR][aA][nN][tT](\s[wW][iI][tT][hH]\s[gG][rR][aA][nN][tT]\s[oO][pP][tT][iI][oO][nN])?|[rR][eE][vV][oO][kK][eE])\b)|([\s\S])/g,/(?:\b[iI][nN]\b)|([\s\S])/g,/(?:^\s*([cC][oO][mM][mM][eE][nN][tT]\s+[oO][nN]\s+([tT][aA][bB][lL][eE]|[cC][oO][lL][uU][mM][nN]|[aA][gG][gG][rR][eE][gG][aA][tT][eE]|[cC][oO][nN][sS][tT][rR][aA][iI][nN][tT]|[dD][aA][tT][aA][bB][aA][sS][eE]|[dD][oO][mM][aA][iI][nN]|[fF][uU][nN][cC][tT][iI][oO][nN]|[iI][nN][dD][eE][xX]|[oO][pP][eE][rR][aA][tT][oO][rR]|[rR][uU][lL][eE]|[sS][cC][hH][eE][mM][aA]|[sS][eE][qQ][uU][eE][nN][cC][eE]|[tT][rR][iI][gG][gG][eE][rR]|[tT][yY][pP][eE]|[vV][iI][eE][wW]))\s+.*?\s+([iI][sS])\s+)|([\s\S])/g,/(?:\b[aA][sS]\b)|([\s\S])/g,/(?:\b([dD][eE][sS][cC]|[aA][sS][cC])\b)|([\s\S])/g,/\*|([\s\S])/g,/[!<>]?=|<>|<|>|([\s\S])/g,/\-|\+|\/|([\s\S])/g,/\|\||([\s\S])/g,/(?:\b([cC][uU][rR][rR][eE][nN][tT]_([dD][aA][tT][eE]|[tT][iI][mM][eE]([sS][tT][aA][mM][pP])?|[uU][sS][eE][rR])|([sS][eE][sS][sS][iI][oO][nN]|[sS][yY][sS][tT][eE][mM])_[uU][sS][eE][rR])\b)|([\s\S])/g,/(?:\b([aA][vV][gG]|[cC][oO][uU][nN][tT]|[mM][iI][nN]|[mM][aA][xX]|[sS][uU][mM])(?=\s*\())|([\s\S])/g,/(?:\b([cC][oO][nN][cC][aA][tT][eE][nN][aA][tT][eE]|[cC][oO][nN][vV][eE][rR][tT]|[lL][oO][wW][eE][rR]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][aA][nN][sS][lL][aA][tT][eE]|[tT][rR][iI][mM]|[uU][pP][pP][eE][rR])\b)|([\s\S])/g,/(\w+?)(\.(\w+))|([\s\S])/g,/\b(for)(\s+(?=\({2}))|([\s\S])/g,/\b(for)(\s+((?:[^\s\\]|\\.)+)(\b))|([\s\S])/g,/\b(while|until)(\b)|([\s\S])/g,/\b(select)(\s+((?:[^\s\\]|\\.)+)(\b))|([\s\S])/g,/\b(case)(\b)|([\s\S])/g,/\b(if)(\b)|([\s\S])/g,/\-?\?>|([\s\S])/g,/(#)(.*?(?=\-?\?>))|([\s\S])/g,/\)|([\s\S])/g,/\(|([\s\S])/g,/(?![A-Za-z0-9_])|([\s\S])/g,/(&)(([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;))|([\s\S])/g,/(?=")|([\s\S])/g,/\\[\\']|([\s\S])/g,/(?:^\s*)((?!while|for|do|if|else|switch|catch|enumerate|r?iterate)[A-Za-z_][A-Za-z0-9_:]*)(\s*(\())|([\s\S])/g,/(:)((?=\s*[A-Za-z_][A-Za-z0-9_:]*\s*(\()))|([\s\S])/g,/^\s*(?=[uU]?[rR]?""")|([\s\S])/g,/^\s*(?=[uU]?[rR]?''')|([\s\S])/g,/\]|([\s\S])/g,/(\\)((.*)((?=\n)\n?))|([\s\S])/g,/>|([\s\S])/g,/\\>|\\\\|([\s\S])/g,/^\s*(#\s*(endif)(\b))(.*(?=\n))|([\s\S])/g,/((")("")|""")|([\s\S])/g,/(""")|([\s\S])/g,/\}|([\s\S])/g,/((?!while|for|do|if|else|switch|catch|enumerate|return|r?iterate)(?=((?:\b[A-Za-z_](?=([A-Za-z0-9_]*))\3\b|::)*))\2)(\s*(\())|([\s\S])/g,/\*\/|([\s\S])/g,/(?=')|([\s\S])/g,/(?=\s*\()|([\s\S])/g,/^\t*(MARKDOWN)((?=\n))|([\s\S])/g,/\b((Arithmetic|Assertion|Attribute|EOF|Environment|FloatingPoint|IO|Import|Indentation|Index|Key|Lookup|Memory|Name|OS|Overflow|NotImplemented|Reference|Runtime|Standard|Syntax|System|Tab|Type|UnboundLocal|Unicode(Translate|Encode|Decode)?|Value|ZeroDivision)Error|(Deprecation|Future|Overflow|PendingDeprecation|Runtime|Syntax|User)?Warning|KeyboardInterrupt|NotImplemented|StopIteration|SystemExit|(Base)?Exception)\b|([\s\S])/g,/(?=\n)\n?|([\s\S])/g,/(?=(\\\s*\n))\1|([\s\S])/g,/\s*(?:(?=\})|(,))|([\s\S])/g,/^\s*(#\s*(else)(\b))(.*)|([\s\S])/g,/=[=~]?|!=?|<|>|&&|\|\||([\s\S])/g,/\-(nt|ot|ef|eq|ne|l[te]|g[te]|[a-hknoprstuwxzOGLSN])|([\s\S])/g,/(?=\n)|([\s\S])/g,/[a-zA-Z0-9_]+|([\s\S])/g,/(')|(\n)|([\s\S])/g,/\b(done)(\b)|([\s\S])/g,/\1[eimnosux]*|([\s\S])/g,/(?=\s|(?=\n)\n?|#)|([\s\S])/g,/(?=(@)(\s*[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*))|([\s\S])/g,/\b(item|container|(computer|disk|trash)\-object|disk|folder|((alias|application|document|internet location) )?file|clipping|package)s?\b|([\s\S])/g,/\b((Finder|desktop|information|preferences|clipping) )windows?\b|([\s\S])/g,/\b(preferences|(icon|column|list) view options|(label|column|alias list)s?)\b|([\s\S])/g,/\b(copy|find|sort|clean up|eject|empty( trash)|erase|reveal|update)\b|([\s\S])/g,/\b(insertion location|product version|startup disk|desktop|trash|home|computer container|finder preferences)\b|([\s\S])/g,/\b(visible)\b|([\s\S])/g,/^(?!\s*\*).*(?=\n)\n?|([\s\S])/g,/^\s*\*\s*(@access)(\s+((public|private|protected)|(.+))(\s*(?=\n)))|([\s\S])/g,/((https?|s?ftp|ftps|file|smb|afp|nfs|(x\-)?man|gopher|txmt):\/\/|mailto:)[\-:@a-zA-Z0-9_\.~%\+\/\?=&#]*[\-@a-zA-Z0-9_~%\+\/=&#]|([\s\S])/g,/(@xlink)(\s+(.+)(\s*(?=\n)))|([\s\S])/g,/@(a(bstract|uthor)|c(ategory|opyright)|example|global|internal|li(cense|nk)|pa(ckage|ram)|return|s(ee|ince|tatic|ubpackage)|t(hrows|odo)|v(ar|ersion)|uses|deprecated|final)\b|([\s\S])/g,/\{(@(link))(.+?\})|([\s\S])/g,/(\})|([\s\S])/g,/([A-Za-z]+|((\|)([^\|\n]*(\|))))(\s*(:))|([\s\S])/g,/:|([\s\S])/g,/,|([\s\S])/g,/^\t*(HTML)((?=\n))|([\s\S])/g,/(@[^ \(]+)(\()|([\s\S])/g,/@\w*|([\s\S])/g,/final|([\s\S])/g,/\w+|([\s\S])/g,/(?=(^\s*)?<\?)|([\s\S])/g,/\b([a-zA-Z_][a-zA-Z_0-9]*)(\s*(=)((?!=)))|([\s\S])/g,/\}|/g,/|(?=#)|(;)|([\s\S])/g,/(?=#)|(;)|([\s\S])/g,/\bconst\b|([\s\S])/g,/(?=(?:\/\/|\/\*))|(?=\n)|([\s\S])/g,/(\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*?\b)|([\s\S])/g,/^=end|([\s\S])/g,/\b(esac)(\b)|([\s\S])/g,/\b(?:in)\b|([\s\S])/g,/^\s*(script)(\s+(\w+))|([\s\S])/g,/^\s*(to|on)(\s+([A-Za-z][A-Za-z0-9_]*)((\()((?:(\w+(?:\s*,\s*\w+)*))?(\)))))|([\s\S])/g,/^\s*(on)(\s+(\w+)((?=\s+(above|against|apart from|around|aside from|at|below|beneath|beside|between|by|for|from|instead of|into|on|onto|out of|over|thru|under)\s+)))|([\s\S])/g,/(?:([eE][xX][tT][eE][nN][dD][sS]))(\s+([a-zA-Z0-9_]+)(\s*))|([\s\S])/g,/(?:([iI][mM][pP][lL][eE][mM][eE][nN][tT][sS]))(\s+([a-zA-Z0-9_]+)(\s*))|([\s\S])/g,/\*\)|([\s\S])/g,/(>(<)(\/))((\2)(>))|([\s\S])/g,/(?=\})|([\s\S])/g,/(')([^'\\]*('))|([\s\S])/g,/(`)([^`\\]*(`))|([\s\S])/g,/(")([^"#]*("))|([\s\S])/g,/%\{|([\s\S])/g,/(\))|([\s\S])/g,/^\s*(end script)|([\s\S])/g,/"|/g,/((")|")|(\n)|([\s\S])/g,/(")|(\n)|([\s\S])/g,/(?!<?<<\s*(HTML|XML|SQL|JAVASCRIPT)\s*(?=\n))|([\s\S])/g,/(<<<)(\s*(HTML)(\s*(?=\n)\n?))|([\s\S])/g,/(<<<)(\s*(XML)(\s*(?=\n)\n?))|([\s\S])/g,/(<<<)(\s*(SQL)(\s*(?=\n)\n?))|([\s\S])/g,/(<<<)(\s*(JAVASCRIPT)(\s*(?=\n)\n?))|([\s\S])/g,/\\[\$`"\\\n]|([\s\S])/g,/\s*SQL(?=\n)|([\s\S])/g,/(\/?>)|([\s\S])/g,/^(XML)((;?)((?=\n)\n?))|([\s\S])/g,/;;|([\s\S])/g,/(\(|(?=\S))|([\s\S])/g,/\)|/g,/\]\](?=>)|([\s\S])/g,/\}[eimnosux]*|([\s\S])/g,/\\[0-7]{1,3}|([\s\S])/g,/\\x[0-9A-Fa-f]{1,2}|([\s\S])/g,/\\[nrt\\\$"]|([\s\S])/g,/((\$\{)(([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)(\})))|([\s\S])/g,/((\$)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))((?:(\->)((?:(([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))|(\$([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))))|(\[)((?:(\d+)|((\$)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))|(\w+)|(.*?))(\])))?)|([\s\S])/g,/(?=(\$([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)(?:\[([a-zA-Z0-9_\u007f-\u00ff]+|\$([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))\]|\->([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)(\(.*?\))?)?|\$\{(?:([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)(\[(?:([a-zA-Z0-9_\u007f-\u00ff]+|\$([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))|'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*")\])?)\}))\{|([\s\S])/g,/\||([\s\S])/g,/\-\-\s*>|([\s\S])/g,/\-\-|([\s\S])/g,/\)[eimnosux]*|([\s\S])/g,/((\$)(GLOBALS|_(ENV|SERVER|SESSION)))|\b(global)\b|([\s\S])/g,/\b__(all|bases|class|debug|dict|doc|file|members|metaclass|methods|name|slots|weakref)__\b|([\s\S])/g,/\*\/|(?=<\/script)|([\s\S])/g,/(?=\)|:)|([\s\S])/g,/\(|,|/g,/\s*|([\s\S])/g,/(?=(@)(\s*[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\())|([\s\S])/g,/(\()|([\s\S])/g,/\b((?:[a-z]\w*\.)*[A-Z]+\w*)<|([\s\S])/g,/\b((?:[a-z]\w*\.)*[A-Z]+\w*)(?=\[)|([\s\S])/g,/\b(?:[a-z]\w*(\.))*([A-Z]+\w*\b)|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\s+"(?:[tT][eE][xX][tT][mM][aA][tT][eE])")(?!.*\bto\b))|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\s+"(?:[fF][iI][nN][dD][eE][rR])")(?!.*\bto\b))|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\s+"(?:[sS][yY][sS][tT][eE][mM] [eE][vV][eE][nN][tT][sS])")(?!.*\bto\b))|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\s+"(?:[iI][tT][uU][nN][eE][sS])")(?!.*\bto\b))|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\b)(?!.*\bto\b))|([\s\S])/g,/^\s*(tell)(\s+(?=app(lication)?\b)(?=.*?to tell\s*(?!.*\bto\b)))|([\s\S])/g,/^\s*(tell)(\s+.*?(to tell)(\s*(?!.*\bto\b)))|([\s\S])/g,/^\s*(tell)(\s+(?!.*\bto\b))|([\s\S])/g,/(?=\n)|(?=#)|([\s\S])/g,/(\){2})|([\s\S])/g,/^\t*(\3)((?=\n))|([\s\S])/g,/\b(namespace)(\b\s*(?=(([_A-Za-z][_A-Za-z0-9]*\b)?))\3)|([\s\S])/g,/\b(class|struct)(\b\s*(?=(([_A-Za-z][_A-Za-z0-9]*\b)?))\3)|([\s\S])/g,/\b(extern)((?=\s*"))|([\s\S])/g,/(\()|\s*((?=\n)\n?|#.*(?=\n)\n?)|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*)|([\s\S])/g,/(\]{2})|([\s\S])/g,/^\1(?=\n)|([\s\S])/g,/(^\s*)?((((?:<)\?(?:[pP][hH][pP]|=)?)((\s*)((\?)(>))))(\1|(\s*(?=\n)\n)?))|([\s\S])/g,/^\s*(?=<\?)|([\s\S])/g,/\?>|/g,/((<)|<)(\?(?:[pP][hH][pP]|=)?)|([\s\S])/g,/(<)(\?(?:[pP][hH][pP]|=)?)|([\s\S])/g,/^(?=\s*[A-Z0-9_]+\s*(\{|\(|,))|([\s\S])/g,/(:)|([\s\S])/g,/\s+|([\s\S])/g,/\s*(array)(\s*(&)?(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))(\s*(=)(\s*(array)(\s*(\())))))|([\s\S])/g,/\s*(array)(\s*(&)?(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))((?:\s*(=)(\s*(?:([nN][uU][lL][lL])|(\S.*?))?))?(\s*(?=,|\))))))|([\s\S])/g,/\s*([A-Za-z_][A-Za-z_0-9]*)(\s*(&)?(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))((?:\s*(=)(\s*(?:([nN][uU][lL][lL])|(\S.*?))?))?(\s*(?=,|\))))))|([\s\S])/g,/(\s*&)?(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))(\s*(?=,|\))))|([\s\S])/g,/(\s*&)?(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))((?:\s*(=)(\s*))(\s*)))|([\s\S])/g,/\/\*|([\s\S])/g,/^<<\-?\w+|([\s\S])/g,/(?=\n)|"|([\s\S])/g,/\\(x[0-9a-fA-F]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.)|([\s\S])/g,/\s*(?:(,)|(?=\)))|([\s\S])/g,/(\))(\s*(?:(:)|(.*(?=\n)\n?)))|([\s\S])/g,/(class|(?:@)?interface|enum)(\s+(\w+))|([\s\S])/g,/extends|([\s\S])/g,/(implements)(\s)|([\s\S])/g,/\{|([\s\S])/g,/\/(?=\S.*\/)|([\s\S])/g,/%r\{|([\s\S])/g,/(\})((\s*\n)?)|([\s\S])/g,/(\s*(?=\n)\n)?|([\s\S])/g,/<\?(?:[pP][hH][pP]|=)?|([\s\S])/g,/>|[^\w\s,<]|([\s\S])/g,/'|"|/g,/(\$)([\-\*@#\?\$!0_])|([\s\S])/g,/(\$)([1-9])|([\s\S])/g,/(\$)([a-zA-Z_][a-zA-Z0-9_]*)|([\s\S])/g,/\$\{|([\s\S])/g,/^[\s\S]|/g,/\s|/g,/(?::|\.)(?=\s|;|&|(?=\n))|([\s\S])/g,/\b(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)\b|([\s\S])/g,/(?=\n)|(?![\-a-z])|([\s\S])/g,/\b(azimuth|background\-attachment|background\-color|background\-image|background\-position|background\-repeat|background|border\-bottom\-color|border\-bottom\-style|border\-bottom\-width|border\-bottom|border\-collapse|border\-color|border\-left\-color|border\-left\-style|border\-left\-width|border\-left|border\-right\-color|border\-right\-style|border\-right\-width|border\-right|border\-spacing|border\-style|border\-top\-color|border\-top\-style|border\-top\-width|border\-top|border\-width|border|bottom|caption\-side|clear|clip|color|content|counter\-increment|counter\-reset|cue\-after|cue\-before|cue|cursor|direction|display|elevation|empty\-cells|float|font\-family|font\-size\-adjust|font\-size|font\-stretch|font\-style|font\-variant|font\-weight|font|height|left|letter\-spacing|line\-height|list\-style\-image|list\-style\-position|list\-style\-type|list\-style|margin\-bottom|margin\-left|margin\-right|margin\-top|marker\-offset|margin|marks|max\-height|max\-width|min\-height|min\-width|\-moz\-border\-radius|opacity|orphans|outline\-color|outline\-style|outline\-width|outline|overflow(\-[xy])?|padding\-bottom|padding\-left|padding\-right|padding\-top|padding|page\-break\-after|page\-break\-before|page\-break\-inside|page|pause\-after|pause\-before|pause|pitch\-range|pitch|play\-during|position|quotes|richness|right|size|speak\-header|speak\-numeral|speak\-punctuation|speech\-rate|speak|stress|table\-layout|text\-align|text\-decoration|text\-indent|text\-shadow|text\-transform|top|unicode\-bidi|vertical\-align|visibility|voice\-family|volume|white\-space|widows|width|word\-spacing|z\-index)\b|([\s\S])/g,/\b(?:void|boolean|byte|char|short|int|float|long|double)(\[\])*\b|([\s\S])/g,/(?=not)impossible|([\s\S])/g,/^(PYTHON)((?=\n))|([\s\S])/g,/(?=,|;|\})|([\s\S])/g,/(?=<<<\s*(HTML|XML|SQL|JAVASCRIPT)\s*(?=\n))|([\s\S])/g,/\/\*\*(?:#@\+)?\s*(?=\n)|([\s\S])/g,/(\/\/)(.*?((?=\n)\n?|(?=\?>)))|([\s\S])/g,/(#)(.*?((?=\n)\n?|(?=\?>)))|([\s\S])/g,/^(?:\s*([iI][nN][tT][eE][rR][fF][aA][cC][eE])(\s+([a-zA-Z0-9_]+)(\s*([eE][xX][tT][eE][nN][dD][sS])?(\s*))))|([\s\S])/g,/(?:^\s*([aA][bB][sS][tT][rR][aA][cC][tT]|[fF][iI][nN][aA][lL])?(\s*([cC][lL][aA][sS][sS])(\s+([a-zA-Z0-9_]+)(\s*))))|([\s\S])/g,/\b(break|c(ase|ontinue)|d(e(clare|fault)|ie|o)|e(lse(if)?|nd(declare|for(each)?|if|switch|while)|xit)|for(each)?|if|return|switch|use|while)\b|([\s\S])/g,/(?:\b((?:[rR][eE][qQ][uU][iI][rR][eE]|[iI][nN][cC][lL][uU][dD][eE])(?:_[oO][nN][cC][eE])?)(\b\s*))|([\s\S])/g,/\b(catch)(\b\s*\(\s*([A-Za-z_][A-Za-z_0-9]*)(\s*((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))(\s*\))))|([\s\S])/g,/\b(catch|try|throw|exception)\b|([\s\S])/g,/(?:^\s*)((?:(?:final|abstract|public|private|protected|static)\s+)*)((function)((?:\s+|(\s*&\s*))((?:(__(?:call|(?:con|de)struct|get|(?:is|un)?set|tostring|clone|set_state|sleep|wakeup|autoload))|([a-zA-Z0-9_]+))(\s*(\()))))|([\s\S])/g,/(?:\b([rR][eE][aA][lL]|[dD][oO][uU][bB][lL][eE]|[fF][lL][oO][aA][tT]|[iI][nN][tT]([eE][gG][eE][rR])?|[bB][oO][oO][lL]([eE][aA][nN])?|[sS][tT][rR][iI][nN][gG]|[cC][lL][aA][sS][sS]|[cC][lL][oO][nN][eE]|[vV][aA][rR]|[fF][uU][nN][cC][tT][iI][oO][nN]|[iI][nN][tT][eE][rR][fF][aA][cC][eE]|[pP][aA][rR][eE][nN][tT]|[sS][eE][lL][fF]|[oO][bB][jJ][eE][cC][tT])\b)|([\s\S])/g,/(?:\b([gG][lL][oO][bB][aA][lL]|[aA][bB][sS][tT][rR][aA][cC][tT]|[cC][oO][nN][sS][tT]|[eE][xX][tT][eE][nN][dD][sS]|[iI][mM][pP][lL][eE][mM][eE][nN][tT][sS]|[fF][iI][nN][aA][lL]|[pP]([rR]([iI][vV][aA][tT][eE]|[oO][tT][eE][cC][tT][eE][dD])|[uU][bB][lL][iI][cC])|[sS][tT][aA][tT][iI][cC])\b)|([\s\S])/g,/(::)((?:([A-Za-z_][A-Za-z_0-9]*)(\s*\()|((\$+)([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))|([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*))?)|([\s\S])/g,/(<<<)(\s*([a-zA-Z_]+[a-zA-Z0-9_]*))|([\s\S])/g,/=>|([\s\S])/g,/&(?=\s*(\$|new|[A-Za-z_][A-Za-z_0-9]+(?=\s*\()))|([\s\S])/g,/;|([\s\S])/g,/(@)|([\s\S])/g,/(\-\-|\+\+)|([\s\S])/g,/(\-|\+|\*|\/|%)|([\s\S])/g,/(?:(!|&&|\|\|)|\b([aA][nN][dD]|[oO][rR]|[xX][oO][rR]|[aA][sS])\b)|([\s\S])/g,/<<|>>|~|\^|&|\||([\s\S])/g,/(===|==|!==|!=|<=|>=|<>|<|>)|([\s\S])/g,/(\.=|\.)|([\s\S])/g,/=|([\s\S])/g,/(?:\b([iI][nN][sS][tT][aA][nN][cC][eE][oO][fF])(\b(?:\s+(\w+))?))|([\s\S])/g,/[a-zA-Z0-9_\u007f-\u00ff]|/g,/(\->)(([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*?)(\b))|([\s\S])/g,/^(RUBY)((?=\n))|([\s\S])/g,/\b(audio (data|file))\b|([\s\S])/g,/\b(alias(es)?|(Classic|local|network|system|user) domain objects?|disk( item)?s?|domains?|file( package)?s?|folders?|items?)\b|([\s\S])/g,/\b(delete|open|move)\b|([\s\S])/g,/\b(folder actions?|scripts?)\b|([\s\S])/g,/\b(attach action to|attached scripts|edit action of|remove action from)\b|([\s\S])/g,/\b(movie data|movie file)\b|([\s\S])/g,/\b(log out|restart|shut down|sleep)\b|([\s\S])/g,/\b(((application |desk accessory )?process|(check|combo )?box)(es)?|(action|attribute|browser|(busy|progress|relevance) indicator|color well|column|drawer|group|grow area|image|incrementor|list|menu( bar)?( item)?|(menu |pop up |radio )?button|outline|(radio|tab|splitter) group|row|scroll (area|bar)|sheet|slider|splitter|static text|table|text (area|field)|tool bar|UI element|window)s?)\b|([\s\S])/g,/\b(click|key code|keystroke|perform|select)\b|([\s\S])/g,/\b(property list (file|item))\b|([\s\S])/g,/\b(annotation|QuickTime (data|file)|track)s?\b|([\s\S])/g,/\b((abort|begin|end) transaction)\b|([\s\S])/g,/\b(XML (attribute|data|element|file)s?)\b|([\s\S])/g,/\b(print settings|users?|login items?)\b|([\s\S])/g,/\[|([\s\S])/g,/\b(colors?|documents?|items?|windows?)\b|([\s\S])/g,/\b(close|count|delete|duplicate|exists|make|move|open|print|quit|save|activate|select|data size)\b|([\s\S])/g,/\b(name|frontmost|version)\b|([\s\S])/g,/\b(selection)\b|([\s\S])/g,/\b(attachments?|attribute runs?|characters?|paragraphs?|texts?|words?)\b|([\s\S])/g,/\s*(?:(,)|(?=(?=\n)\n?|[\):]))|([\s\S])/g,/<%+#|([\s\S])/g,/<%+(?!>)=?|([\s\S])/g,/<\?r(?!>)=?|([\s\S])/g,/\b(function)(\s+((?:[^\s\\]|\\.)+)((?:\s*(\(\)))?))|([\s\S])/g,/\b((?:[^\s\\]|\\.)+)(\s*(\(\)))|([\s\S])/g,/'''|/g,/((')('')|''')|([\s\S])/g,/(''')|([\s\S])/g,/<\/(?:script|SCRIPT)|/g,/(>)((?:\s*\n)?)|([\s\S])/g,/(?!\-\-)%>|([\s\S])/g,/"\/(?=(?=((\\.|[^"\/])+))\1\/[imsxeADSUXu]*")|([\s\S])/g,/^(APPLESCRIPT)((?=\n))|([\s\S])/g,/\b(true|false|null)\b|([\s\S])/g,/\b(this|super)\b|([\s\S])/g,/\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|\-)?[0-9]+)?)([LlFfUuDd]|UL|ul)?\b|([\s\S])/g,/(\.)?(\b([A-Z][A-Z0-9_]+)(?!<|\.class|\s*\w+\s*=)\b)|([\s\S])/g,/([uU]r)(""")|([\s\S])/g,/([uU]R)(""")|([\s\S])/g,/(r)(""")|([\s\S])/g,/(R)(""")|([\s\S])/g,/([uU])(""")|([\s\S])/g,/([uU]r)(")|([\s\S])/g,/([uU]R)(")|([\s\S])/g,/(r)(")|([\s\S])/g,/(R)(")|([\s\S])/g,/([uU])(")|([\s\S])/g,/(""")((?=\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)))|([\s\S])/g,/(")((?=\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)))|([\s\S])/g,/(")|([\s\S])/g,/\\['\\]|([\s\S])/g,/;|/g,/\s*(\})|([\s\S])/g,/(?=\{|implements)|([\s\S])/g,/(?=\{)|([\s\S])/g,/\b(a|abbr|acronym|address|area|b|base|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|dt|em|fieldset|form|frame|frameset|(h[1-6])|head|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|meta|noframes|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var)\b|([\s\S])/g,/(\.)([a-zA-Z0-9_\-]+)|([\s\S])/g,/(#)([a-zA-Z][a-zA-Z0-9_\-]*)|([\s\S])/g,/(:+)(\b(after|before|first\-child|first\-letter|first\-line|selection)\b)|([\s\S])/g,/(:)(\b(active|hover|link|visited|focus)\b)|([\s\S])/g,/(\[)(\s*(\-?[_a-zA-Z\\\u0080-\uffff][_a-zA-Z0-9\-\\\u0080-\uffff]*)((?:\s*([~\|\^\$\*]?=)(\s*(?:(\-?[_a-zA-Z\\\u0080-\uffff][_a-zA-Z0-9\-\\\u0080-\uffff]*)|((?=((['"])((?:[^\\]|\\.)*?(\10))))\9))))?(\s*(\]))))|([\s\S])/g,/^\s*#\s*endif\b.*(?=\n)|([\s\S])/g,/(?=\s*\[)|([\s\S])/g,/[A-Za-z_][A-Za-z0-9_]*|([\s\S])/g,/#\{(\})|([\s\S])/g,/#\{|([\s\S])/g,/(#@)([a-zA-Z_]\w*)|([\s\S])/g,/(#@@)([a-zA-Z_]\w*)|([\s\S])/g,/(#\$)([a-zA-Z_]\w*)|([\s\S])/g,/\s*(;|(?=\}))|([\s\S])/g,/\b(absolute|all\-scroll|always|armenian|auto|baseline|below|bidi\-override|block|bold|bolder|both|bottom|break\-all|break\-word|capitalize|center|char|circle|cjk\-ideographic|col\-resize|collapse|crosshair|dashed|decimal\-leading\-zero|decimal|default|disabled|disc|distribute\-all\-lines|distribute\-letter|distribute\-space|distribute|dotted|double|e\-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana\-iroha|hiragana|horizontal|ideograph\-alpha|ideograph\-numeric|ideograph\-parenthesis|ideograph\-space|inactive|inherit|inline\-block|inline|inset|inside|inter\-ideograph|inter\-word|italic|justify|katakana\-iroha|katakana|keep\-all|left|lighter|line\-edge|line\-through|line|list\-item|loose|lower\-alpha|lower\-greek|lower\-latin|lower\-roman|lowercase|lr\-tb|ltr|medium|middle|move|n\-resize|ne\-resize|newspaper|no\-drop|no\-repeat|nw\-resize|none|normal|not\-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat\-x|repeat\-y|repeat|right|ridge|row\-resize|rtl|s\-resize|scroll|se\-resize|separate|small\-caps|solid|square|static|strict|super|sw\-resize|table\-footer\-group|table\-header\-group|tb\-rl|text\-bottom|text\-top|text|thick|thin|top|transparent|underline|upper\-alpha|upper\-latin|upper\-roman|uppercase|vertical\-ideographic|vertical\-text|visible|w\-resize|wait|whitespace|zero)\b|([\s\S])/g,/(\b(?:[aA][rR][iI][aA][lL]|[cC][eE][nN][tT][uU][rR][yY]|[cC][oO][mM][iI][cC]|[cC][oO][uU][rR][iI][eE][rR]|[gG][aA][rR][aA][mM][oO][nN][dD]|[gG][eE][oO][rR][gG][iI][aA]|[hH][eE][lL][vV][eE][tT][iI][cC][aA]|[iI][mM][pP][aA][cC][tT]|[lL][uU][cC][iI][dD][aA]|[sS][yY][mM][bB][oO][lL]|[sS][yY][sS][tT][eE][mM]|[tT][aA][hH][oO][mM][aA]|[tT][iI][mM][eE][sS]|[tT][rR][eE][bB][uU][cC][hH][eE][tT]|[uU][tT][oO][pP][iI][aA]|[vV][eE][rR][dD][aA][nN][aA]|[wW][eE][bB][dD][iI][nN][gG][sS]|[sS][aA][nN][sS]\-[sS][eE][rR][iI][fF]|[sS][eE][rR][iI][fF]|[mM][oO][nN][oO][sS][pP][aA][cC][eE])\b)|([\s\S])/g,/\b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b|([\s\S])/g,/\b(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen)\b|([\s\S])/g,/(\-|\+)?\s*[0-9]+(\.[0-9]+)?|([\s\S])/g,/\d|/g,/(px|pt|cm|mm|in|em|ex|pc)\b|%|([\s\S])/g,/%|([\s\S])/g,/(#)(([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b)|([\s\S])/g,/(rgb|url|attr|counter|counters)(\s*(\())|([\s\S])/g,/!\s*important|([\s\S])/g,/%>|([\s\S])/g,/(\])|([\s\S])/g,/\[|,|/g,/\s*(?![\],])|([\s\S])/g,/\b(sizeof)\b|([\s\S])/g,/(<<)(\-("|'|)(RUBY)(\3))|([\s\S])/g,/(<<)(("|'|)(RUBY)(\3))|([\s\S])/g,/(<<)(\-("|'|)(PYTHON)(\3))|([\s\S])/g,/(<<)(("|'|)(PYTHON)(\3))|([\s\S])/g,/(<<)(\-("|'|)(APPLESCRIPT)(\3))|([\s\S])/g,/(<<)(("|'|)(APPLESCRIPT)(\3))|([\s\S])/g,/(<<)(\-("|'|)(HTML)(\3))|([\s\S])/g,/(<<)(("|'|)(HTML)(\3))|([\s\S])/g,/(<<)(\-("|'|)(MARKDOWN)(\3))|([\s\S])/g,/(<<)(("|'|)(MARKDOWN)(\3))|([\s\S])/g,/(<<)(\-("|'|)(TEXTILE)(\3))|([\s\S])/g,/(<<)(("|'|)(TEXTILE)(\3))|([\s\S])/g,/(<<)(\-("|'|)\\?(\w+)(\3))|([\s\S])/g,/(<<)(("|'|)\\?(\w+)(\3))|([\s\S])/g,/;|&|(?=\n)|([\s\S])/g,/\s*((?=;|\}))|([\s\S])/g,/(url)(\s*(\()(\s*))|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\[)|([\s\S])/g,/(\[)|([\s\S])/g,/\s*\2(?=\n)|([\s\S])/g,/%(\d+\$)?[#0\- \+']*[,;:_]?((\-?\d+)|\*(\-?\d+\$)?)?(\.((\-?\d+)|\*(\-?\d+\$)?)?)?(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)?[diouxXDOUeEfFgGaACcSspn%]|([\s\S])/g,/(\\U[0-9A-Fa-f]{8})|(\\u[0-9A-Fa-f]{4})|(\\N\{[a-zA-Z ]+\})|([\s\S])/g,/(<\/)(((?:[sS][tT][yY][lL][eE]))((>)((?:\s*\n)?)))|([\s\S])/g,/(\/)([imsxeADSUXu]*)(')|([\s\S])/g,/(\{)(\d+(,\d+)?(\}))|([\s\S])/g,/(\\){1,2}[\.\$\^\[\]\{\}]|([\s\S])/g,/\\{1,2}[\\']|([\s\S])/g,/\[(?:\^?\])?|([\s\S])/g,/[\$\^\+\*]|([\s\S])/g,/\b(?:if|then|else|elif|fi|for|in|do|done|select|case|continue|esac|while|until|return)\b|([\s\S])/g,/\b(?:export|declare|typeset|local|readonly)\b|([\s\S])/g,/(?=\w+\s*\()|([\s\S])/g,/(?:\b([nN][eE][wW])(\s+(?:(\$[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)|(\w+)))|(\w+)((?=::)))|([\s\S])/g,/\b(basestring|bool|buffer|classmethod|complex|dict|enumerate|file|float|frozenset|int|list|long|object|open|property|reversed|set|slice|staticmethod|str|super|tuple|type|unicode|xrange)\b|([\s\S])/g,/\-\-%?>|([\s\S])/g,/\){2}|([\s\S])/g,/^\s*(#\s*(pragma\s+mark)(\s+(.*)))|([\s\S])/g,/\\(?:[0-7]{1,3}|x[\da-fA-F]{1,2}|.)|([\s\S])/g,/\}|(?=;)|([\s\S])/g,/(\w+)(\s*\()|([\s\S])/g,/(?=\w.*\s+\w+\s*\()|([\s\S])/g,/#(\\'|[^'])*(?='|(?=\n)\n?)|([\s\S])/g,/\-\-(\\'|[^'])*(?='|(?=\n)\n?)|([\s\S])/g,/\\'(?!([^\\']|\\[^'])*\\')(?=(\\[^']|.)*?')|([\s\S])/g,/`(?=[^`]*?')|([\s\S])/g,/"(?=[^"]*?')|([\s\S])/g,/\\'|([\s\S])/g,/(?:\b([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[nN][uU][lL][lL]|__([fF][iI][lL][eE]|[fF][uU][nN][cC][tT][iI][oO][nN]|[cC][lL][aA][sS][sS]|[mM][eE][tT][hH][oO][dD]|[lL][iI][nN][eE])__|[oO][nN]|[oO][fF][fF]|[yY][eE][sS]|[nN][oO]|[nN][lL]|[bB][rR]|[tT][aA][bB])\b)|([\s\S])/g,/\b(DEFAULT_INCLUDE_PATH|E_(ALL|COMPILE_(ERROR|WARNING)|CORE_(ERROR|WARNING)|(RECOVERABLE_)?ERROR|NOTICE|PARSE|STRICT|USER_(ERROR|NOTICE|WARNING)|WARNING)|PEAR_(EXTENSION_DIR|INSTALL_DIR)|PHP_(BINDIR|CONFIG_FILE_PATH|DATADIR|E(OL|XTENSION_DIR)|L(IBDIR|OCALSTATEDIR)|O(S|UTPUT_HANDLER_CONT|UTPUT_HANDLER_END|UTPUT_HANDLER_START)|SYSCONFDIR|VERSION))\b|([\s\S])/g,/\b(A(B(DAY_([1-7])|MON_([0-9]{1,2}))|LT_DIGITS|M_STR|SSERT_(ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(ASE_(LOWER|UPPER)|HAR_MAX|O(DESET|NNECTION_(ABORTED|NORMAL|TIMEOUT)|UNT_(NORMAL|RECURSIVE))|REDITS_(ALL|DOCS|FULLPAGE|GENERAL|GROUP|MODULES|QA|SAPI)|RNCYSTR|RYPT_(BLOWFISH|EXT_DES|MD5|SALT_LENGTH|STD_DES)|URRENCY_SYMBOL)|D(AY_([1-7])|ECIMAL_POINT|IRECTORY_SEPARATOR|_(FMT|T_FMT))|E(NT_(COMPAT|NOQUOTES|QUOTES)|RA(|_D_FMT|_D_T_FMT|_T_FMT|_YEAR)|XTR_(IF_EXISTS|OVERWRITE|PREFIX_(ALL|IF_EXISTS|INVALID|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(ENTITIES|SPECIALCHARS)|IN(FO_(ALL|CONFIGURATION|CREDITS|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(ALL|PERDIR|SYSTEM|USER)|T_(CURR_SYMBOL|FRAC_DIGITS))|L(C_(ALL|COLLATE|CTYPE|MESSAGES|MONETARY|NUMERIC|TIME)|O(CK_(EX|NB|SH|UN)|G_(ALERT|AUTH(|PRIV)|CONS|CRIT|CRON|DAEMON|DEBUG|EMERG|ERR|INFO|KERN|LOCAL([0-7])|LPR|MAIL|NDELAY|NEWS|NOTICE|NOWAIT|ODELAY|PERROR|PID|SYSLOG|USER|UUCP|WARNING)))|M(ON_([0-9]{1,2}|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|YSQL_(ASSOC|BOTH|NUM)|_(1_PI|2_(PI|SQRTPI)|E|L(N10|N2|OG(10E|2E))|PI(|_2|_4)|SQRT1_2|SQRT2))|N(EGATIVE_SIGN|O(EXPR|STR)|_(CS_PRECEDES|SEP_BY_SPACE|SIGN_POSN))|P(ATH(INFO_(BASENAME|DIRNAME|EXTENSION|FILENAME)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(CS_PRECEDES|SEP_BY_SPACE|SIGN_POSN))|RADIXCHAR|S(EEK_(CUR|END|SET)|ORT_(ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(BOTH|LEFT|RIGHT))|T(HOUS(ANDS_SEP|EP)|_(FMT(|_AMPM)))|YES(EXPR|STR))\b|([\s\S])/g,/[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*|([\s\S])/g,/^\s*(#(if)(\s+(0*1)(\b)))|([\s\S])/g,/\b(__import__|all|abs|any|apply|callable|chr|cmp|coerce|compile|delattr|dir|divmod|eval|execfile|filter|getattr|globals|hasattr|hash|hex|id|input|intern|isinstance|issubclass|iter|len|locals|map|max|min|oct|ord|pow|range|raw_input|reduce|reload|repr|round|setattr|sorted|sum|unichr|vars|zip)\b|([\s\S])/g,/(?:%(\([a-zA-Z_]+\))?#?0?\-? ?\+?([0-9]*|\*)(\.([0-9]*|\*))?[hHlL]?[a-zA-Z%])|([\s\S])/g,/\)|\]|/g,/(?!\s*\{)||(?=;)|([\s\S])/g,/(?!\s*\{)|(?=;)|([\s\S])/g,/|(?=;)|([\s\S])/g,/(?=;)|([\s\S])/g,/(\w+)(\s*(?=\[))|([\s\S])/g,/(?=\w.*\()|([\s\S])/g,/\b(print settings)\b|([\s\S])/g,/\b(get url|insert|reload bundles)\b|([\s\S])/g,/(#)(\s[a-zA-Z0-9,\. \t\?!-\u0080\-\uffff]*(?=\n))|([\s\S])/g,/\+{1,2}|\-{1,2}|!|~|\*{1,2}|\/|%|<[<=]?|>[>=]?|==|!=|^|\|{1,2}|&{1,2}|\?|:|,|=|[\*\/%\+\-&\^\|]=|<<=|>>=|([\s\S])/g,/0[xX][0-9a-fA-F]+|([\s\S])/g,/0\d+|([\s\S])/g,/\d{1,2}#[0-9a-zA-Z@_]+|([\s\S])/g,/\d+|([\s\S])/g,/\-?%>|([\s\S])/g,/(#)(.*?(?=\-?%>))|([\s\S])/g,/(\?>)|([\s\S])/g,/ ([a-zA-Z\-]+)|([\s\S])/g,/(DOCTYPE)|([\s\S])/g,/\[CDATA\[|([\s\S])/g,/(\s*)(?!\-\-|>)\S(\s*)|([\s\S])/g,/^\s*(#(if)(\s+(0)(\b)))(.*)|([\s\S])/g,/\{|,|/g,/\s*(?![\},])|([\s\S])/g,/:|/g,/(?!(^\s*)?<\?)|([\s\S])/g,/(?=^\s*#\s*(else|endif)\b.*(?=\n))|([\s\S])/g,/^(?=\s*[:\.\*#a-zA-Z])|([\s\S])/g,/^\s*((@)(import\b))|([\s\S])/g,/^\s*((@)(media))(\s+(((all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)\s*,?\s*)+)(\s*\{))|([\s\S])/g,/^\s*(package)(\b(?:\s*([^ ;\$]+)(\s*(;)?))?)|([\s\S])/g,/^\s*(import)(\b(?:\s*([^ ;\$]+)(\s*(;)?))?)|([\s\S])/g,/(?![A-Za-z0-9_\.])|([\s\S])/g,/(\.)(?=[A-Za-z_][A-Za-z0-9_]*)|([\s\S])/g,/\.|/g,/(?=\s|;|(?=\n))|([\s\S])/g,/"\s*(?=(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)\b)|([\s\S])/g,/(?=\))|([\s\S])/g,/^(HTML)((?=\n))|([\s\S])/g,/\b(fi)(\b)|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\s*(=)(\s*)))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*(function)?(\s*(\()((.*?)(\))))))))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*))))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*(function)(\s*(\()((.*?)(\)))))))|([\s\S])/g,/([a-zA-Z_\?\$][\w\?\$]*)(\s*(=)(\s*(function)(\s*(\()((.*?)(\))))))|([\s\S])/g,/\b(function)(\s+([a-zA-Z_\$]\w*)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/\b([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*:\s*\b(function)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/(?:((')((.*?)(')))|((")((.*?)("))))(\s*:\s*\b(function)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/(new)(\s+(\w+(?:\.\w*)?))|([\s\S])/g,/\b(console)\b|([\s\S])/g,/\.(warn|info|log|error|time|timeEnd|assert)\b|([\s\S])/g,/\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?))\b|([\s\S])/g,/\/\*\*(?!\/)|([\s\S])/g,/(\/\/)(.*(?=\n)\n?)|([\s\S])/g,/(<!\-\-|\-\->)|([\s\S])/g,/\b(boolean|byte|char|class|double|enum|float|function|int|interface|long|short|var|void)\b|([\s\S])/g,/\b(const|export|extends|final|implements|native|private|protected|public|static|synchronized|throws|transient|volatile)\b|([\s\S])/g,/\b(break|case|catch|continue|default|do|else|finally|for|goto|if|import|package|return|switch|throw|try|while)\b|([\s\S])/g,/\b(delete|in|instanceof|new|typeof|with)\b|([\s\S])/g,/\btrue\b|([\s\S])/g,/\bfalse\b|([\s\S])/g,/\bnull\b|([\s\S])/g,/\b(super|this)\b|([\s\S])/g,/\b(debugger)\b|([\s\S])/g,/\b(Anchor|Applet|Area|Array|Boolean|Button|Checkbox|Date|document|event|FileUpload|Form|Frame|Function|Hidden|History|Image|JavaArray|JavaClass|JavaObject|JavaPackage|java|Layer|Link|Location|Math|MimeType|Number|navigator|netscape|Object|Option|Packages|Password|Plugin|Radio|RegExp|Reset|Select|String|Style|Submit|screen|sun|Text|Textarea|window|XMLHttpRequest)\b|([\s\S])/g,/\b(s(h(ift|ow(Mod(elessDialog|alDialog)|Help))|croll(X|By(Pages|Lines)?|Y|To)?|t(op|rike)|i(n|zeToContent|debar|gnText)|ort|u(p|b(str(ing)?)?)|pli(ce|t)|e(nd|t(Re(sizable|questHeader)|M(i(nutes|lliseconds)|onth)|Seconds|Ho(tKeys|urs)|Year|Cursor|Time(out)?|Interval|ZOptions|Date|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(ome|andleEvent)|navigate|c(har(CodeAt|At)|o(s|n(cat|textual|firm)|mpile)|eil|lear(Timeout|Interval)?|a(ptureEvents|ll)|reate(StyleSheet|Popup|EventObject))|t(o(GMTString|S(tring|ource)|U(TCString|pperCase)|Lo(caleString|werCase))|est|a(n|int(Enabled)?))|i(s(NaN|Finite)|ndexOf|talics)|d(isableExternalCapture|ump|etachEvent)|u(n(shift|taint|escape|watch)|pdateCommands)|j(oin|avaEnabled)|p(o(p|w)|ush|lugins.refresh|a(ddings|rse(Int|Float)?)|r(int|ompt|eference))|e(scape|nableExternalCapture|val|lementFromPoint|x(p|ec(Script|Command)?))|valueOf|UTC|queryCommand(State|Indeterm|Enabled|Value)|f(i(nd|le(ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(nt(size|color)|rward)|loor|romCharCode)|watch|l(ink|o(ad|g)|astIndexOf)|a(sin|nchor|cos|t(tachEvent|ob|an(2)?)|pply|lert|b(s|ort))|r(ou(nd|teEvents)|e(size(By|To)|calc|turnValue|place|verse|l(oad|ease(Capture|Events)))|andom)|g(o|et(ResponseHeader|M(i(nutes|lliseconds)|onth)|Se(conds|lection)|Hours|Year|Time(zoneOffset)?|Da(y|te)|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Da(y|te)|FullYear)|FullYear|A(ttention|llResponseHeaders)))|m(in|ove(B(y|elow)|To(Absolute)?|Above)|ergeAttributes|a(tch|rgins|x))|b(toa|ig|o(ld|rderWidths)|link|ack))\b(?=\()|([\s\S])/g,/\b(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)\b(?=\()|([\s\S])/g,/(s(ystemLanguage|cr(ipts|ollbars|een(X|Y|Top|Left))|t(yle(Sheets)?|atus(Text|bar)?)|ibling(Below|Above)|ource|uffixes|e(curity(Policy)?|l(ection|f)))|h(istory|ost(name)?|as(h|Focus))|y|X(MLDocument|SLDocument)|n(ext|ame(space(s|URI)|Prop))|M(IN_VALUE|AX_VALUE)|c(haracterSet|o(n(structor|trollers)|okieEnabled|lorDepth|mp(onents|lete))|urrent|puClass|l(i(p(boardData)?|entInformation)|osed|asses)|alle(e|r)|rypto)|t(o(olbar|p)|ext(Transform|Indent|Decoration|Align)|ags)|SQRT(1_2|2)|i(n(ner(Height|Width)|put)|ds|gnoreCase)|zIndex|o(scpu|n(readystatechange|Line)|uter(Height|Width)|p(sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(i(splay|alog(Height|Top|Width|Left|Arguments)|rectories)|e(scription|fault(Status|Ch(ecked|arset)|View)))|u(ser(Profile|Language|Agent)|n(iqueID|defined)|pdateInterval)|_content|p(ixelDepth|ort|ersonalbar|kcs11|l(ugins|atform)|a(thname|dding(Right|Bottom|Top|Left)|rent(Window|Layer)?|ge(X(Offset)?|Y(Offset)?))|r(o(to(col|type)|duct(Sub)?|mpter)|e(vious|fix)))|e(n(coding|abledPlugin)|x(ternal|pando)|mbeds)|v(isibility|endor(Sub)?|Linkcolor)|URLUnencoded|P(I|OSITIVE_INFINITY)|f(ilename|o(nt(Size|Family|Weight)|rmName)|rame(s|Element)|gColor)|E|whiteSpace|l(i(stStyleType|n(eHeight|kColor))|o(ca(tion(bar)?|lName)|wsrc)|e(ngth|ft(Context)?)|a(st(M(odified|atch)|Index|Paren)|yer(s|X)|nguage))|a(pp(MinorVersion|Name|Co(deName|re)|Version)|vail(Height|Top|Width|Left)|ll|r(ity|guments)|Linkcolor|bove)|r(ight(Context)?|e(sponse(XML|Text)|adyState))|global|x|m(imeTypes|ultiline|enubar|argin(Right|Bottom|Top|Left))|L(N(10|2)|OG(10E|2E))|b(o(ttom|rder(RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(Color|Image)))\b|([\s\S])/g,/(s(hape|ystemId|c(heme|ope|rolling)|ta(ndby|rt)|ize|ummary|pecified|e(ctionRowIndex|lected(Index)?)|rc)|h(space|t(tpEquiv|mlFor)|e(ight|aders)|ref(lang)?)|n(o(Resize|tation(s|Name)|Shade|Href|de(Name|Type|Value)|Wrap)|extSibling|ame)|c(h(ildNodes|Off|ecked|arset)?|ite|o(ntent|o(kie|rds)|de(Base|Type)?|l(s|Span|or)|mpact)|ell(s|Spacing|Padding)|l(ear|assName)|aption)|t(ype|Bodies|itle|Head|ext|a(rget|gName)|Foot)|i(sMap|ndex|d|m(plementation|ages))|o(ptions|wnerDocument|bject)|d(i(sabled|r)|o(c(type|umentElement)|main)|e(clare|f(er|ault(Selected|Checked|Value)))|at(eTime|a))|useMap|p(ublicId|arentNode|r(o(file|mpt)|eviousSibling))|e(n(ctype|tities)|vent|lements)|v(space|ersion|alue(Type)?|Link|Align)|URL|f(irstChild|orm(s)?|ace|rame(Border)?)|width|l(ink(s)?|o(ngDesc|wSrc)|a(stChild|ng|bel))|a(nchors|c(ce(ssKey|pt(Charset)?)|tion)|ttributes|pplets|l(t|ign)|r(chive|eas)|xis|Link|bbr)|r(ow(s|Span|Index)|ules|e(v|ferrer|l|adOnly))|m(ultiple|e(thod|dia)|a(rgin(Height|Width)|xLength))|b(o(dy|rder)|ackground|gColor))\b|([\s\S])/g,/\b(ELEMENT_NODE|ATTRIBUTE_NODE|TEXT_NODE|CDATA_SECTION_NODE|ENTITY_REFERENCE_NODE|ENTITY_NODE|PROCESSING_INSTRUCTION_NODE|COMMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_FRAGMENT_NODE|NOTATION_NODE|INDEX_SIZE_ERR|DOMSTRING_SIZE_ERR|HIERARCHY_REQUEST_ERR|WRONG_DOCUMENT_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR|NOT_SUPPORTED_ERR|INUSE_ATTRIBUTE_ERR)\b|([\s\S])/g,/\bon(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))\b|([\s\S])/g,/\(|/g,/!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?:|\*=|\/=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|void)\b|([\s\S])/g,/!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?:|\*=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|void)\b|([\s\S])/g,/\b(Infinity|NaN|undefined)\b|([\s\S])/g,/[=\(:]|/g,/return|/g,/\s*(\/)((?![\/\*\+\{\}\?]))|([\s\S])/g,/,[ \|\t]*|([\s\S])/g,/\.|([\s\S])/g,/\{|\}|([\s\S])/g,/\(|\)|([\s\S])/g,/\[|\]|([\s\S])/g,/\\\)|\\\\|([\s\S])/g,/(?=,|\))|([\s\S])/g,/throws|([\s\S])/g,/\u00ac|([\s\S])/g,/\b((a )?(ref( to)|reference to)|(does not|doesn't) (come (before|after)|contain|equal)|(start|begin)s? with|comes (before|after)|is(n't| not)?( (in|contained by|(less than|greater than)( or equal( to)?)?|equal( to)?))?|ends? with|contains?|equals?|than|and|div|mod|not|or|as)\b|(\u2260|\u2265|\u2264|>=|<=|\u00f7|&|=|>|<|\*|\+|\-|\/|\^)|([\s\S])/g,/to|/g,/then|/g,/\s*\b(return|prop(erty)?)(\b)|([\s\S])/g,/[\(\)]|([\s\S])/g,/\b(on error|try|to|on|tell|if|then|else if|else|repeat( (while|until|with))?|using terms from|from|through|thru|with timeout|times|end (tell|repeat|if|timeout|using terms from|error|try)|end|my|where|whose|considering|ignoring|global|local|exit|continue|returning|set|copy|put)\b|([\s\S])/g,/\b(every|some|index|named|from|to|through|thru|before|(in )?front of|after receiving|after|(in )?back of|beginning of|end of|in|of|first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|\d+(st|nd|rd|th)|last|front|back|middle)\b|([\s\S])/g,/\b(all (caps|lowercase)|bold|condensed|expanded|hidden|italic|outline|plain|shadow|small caps|strikethrough|(sub|super)script|underline)\b|([\s\S])/g,/\b(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO])\b|([\s\S])/g,/\b(null)\b|([\s\S])/g,/\b(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?|weekdays?|Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)\b|([\s\S])/g,/ignoring|/g,/considering|/g,/\b (application responses|current application|case|diacriticals|expansion|hyphens|punctuation|white space)\b|([\s\S])/g,/\b(space|return|tab)\b|([\s\S])/g,/\b(current application|it|me|version|result|pi|AppleScript)\b|([\s\S])/g,/\b(text item delimiters|print length|print depth)\b|([\s\S])/g,/\b(count (each|every)|number of|error|get|run)\b|([\s\S])/g,/\b(booleans?|integers?|reals?|numbers?|(linked )?lists?|vectors?|records?|items?|scripts?|events?|propert(y|ies)|constants?|prepositions?|reference forms?|handlers?|data|characters?|writing code( infos?)?|missing values?|references?|anything|missing value|upper case|app(lications?)?|text items?|((international|styled( Clipboard|Unicode)?|Unicode) )?text|(C | encoded| Pascal )?strings?|(type )?class(es)?|RGB colors?|pictures?|sounds?|versions?|file specifications?|alias(es)?|machines?|zones?|keystrokes?|seconds|dates?|months?|(cubic |square |cubic centi|square kilo|centi|kilo)met(er|re)s|(square |cubic )?(yards|feet)|(square )?miles|(cubic )?inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin))\b|([\s\S])/g,/\b\d+((\.(\d+\b)?)?(?:[eE]\+?\d*\b)?|\b)|([\s\S])/g,/set[ \t]|/g,/\s*([_a-zA-Z][_a-zA-Z0-9]*)(\s*(?=[ \t]+to))|([\s\S])/g,/\\\]|\\\\|([\s\S])/g,/(#\{)(([^\}]*)(\}))|([\s\S])/g,/&(?=\s*\$)|([\s\S])/g,/(array)(\s*(\())|([\s\S])/g,/\s*(:)|([\s\S])/g,/\b(self|cls)\b|([\s\S])/g,/^\s*(end)((?: (\3))?(\s*(?=\n)))|([\s\S])/g,/\b(above|against|apart from|around|aside from|at|below|beneath|beside|between|by|for|from|instead of|into|on|onto|out of|over|thru|under)(\s+(\w+)(\b))|([\s\S])/g,/\?>(?:\s*(?=\n)\n)?|([\s\S])/g,/\/|([\s\S])/g,/\\\/|([\s\S])/g,/(\{)|([\s\S])/g,/application |/g,/app |/g,/("|")|([\s\S])/g,/(\|)([^\|\n]*(\|))|([\s\S])/g,/(\u00ab)((data)( (utxt|utf8)(([0-9A-Fa-f]*)((\u00bb)((?: (as)( (Unicode text)))?)))))|([\s\S])/g,/(\->)((?:([A-Za-z_][A-Za-z_0-9]*)(\s*\()|((\$+)?([a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*)))?)|([\s\S])/g,/\b(__(?:abs|add|and|call|cmp|coerce|complex|contains|del|delattr|delete|delitem|delslice|div|divmod|enter|eq|exit|float|floordiv|ge|get|getattr|getattribute|getitem|getslice|gt|hash|hex|iadd|iand|idiv|ifloordiv|ilshift|imod|imul|init|int|invert|ior|ipow|irshift|isub|iter|itruediv|ixor|le|len|long|lshift|lt|mod|mul|ne|neg|new|nonzero|oct|or|pos|pow|radd|rand|rdiv|rdivmod|repr|rfloordiv|rlshift|rmod|rmul|ror|rpow|rrshift|rshift|rsub|rtruediv|rxor|set|setattr|setitem|setslice|str|sub|truediv|unicode|xor)__)\b|([\s\S])/g,/>[eimnosux]*|([\s\S])/g,/\.[a-zA-Z_][a-zA-Z_0-9]*\b(?!\s*\()|([\s\S])/g,/ (?:([\-_a-zA-Z0-9]+)((:)))?(([_a-zA-Z\-]+)(=))|([\s\S])/g,/^(MARKDOWN)((?=\n))|([\s\S])/g,/(<)(((?=([a-zA-Z0-9:]+))\4)((?=[^>]*><\/\3>)))|([\s\S])/g,/(<\?)(xml)|([\s\S])/g,/<!\-\-|([\s\S])/g,/<!|([\s\S])/g,/(?:^\s+)?(<)(((?:[sS][tT][yY][lL][eE]))(\b(?![^>]*\/>)))|([\s\S])/g,/(?:^\s+)?(<)(((?:[sS][cC][rR][iI][pP][tT]))(\b(?![^>]*\/>)))|([\s\S])/g,/(<\/?)((?:[bB][oO][dD][yY]|[hH][eE][aA][dD]|[hH][tT][mM][lL])\b)|([\s\S])/g,/(<\/?)((?:[aA][dD][dD][rR][eE][sS][sS]|[bB][lL][oO][cC][kK][qQ][uU][oO][tT][eE]|[dD][dD]|[dD][iI][vV]|[dD][lL]|[dD][tT]|[fF][iI][eE][lL][dD][sS][eE][tT]|[fF][oO][rR][mM]|[fF][rR][aA][mM][eE]|[fF][rR][aA][mM][eE][sS][eE][tT]|[hH]1|[hH]2|[hH]3|[hH]4|[hH]5|[hH]6|[iI][fF][rR][aA][mM][eE]|[nN][oO][fF][rR][aA][mM][eE][sS]|[oO][bB][jJ][eE][cC][tT]|[oO][lL]|[pP]|[uU][lL]|[aA][pP][pP][lL][eE][tT]|[cC][eE][nN][tT][eE][rR]|[dD][iI][rR]|[hH][rR]|[mM][eE][nN][uU]|[pP][rR][eE])\b)|([\s\S])/g,/(<\/?)((?:[aA]|[aA][bB][bB][rR]|[aA][cC][rR][oO][nN][yY][mM]|[aA][rR][eE][aA]|[bB]|[bB][aA][sS][eE]|[bB][aA][sS][eE][fF][oO][nN][tT]|[bB][dD][oO]|[bB][iI][gG]|[bB][rR]|[bB][uU][tT][tT][oO][nN]|[cC][aA][pP][tT][iI][oO][nN]|[cC][iI][tT][eE]|[cC][oO][dD][eE]|[cC][oO][lL]|[cC][oO][lL][gG][rR][oO][uU][pP]|[dD][eE][lL]|[dD][fF][nN]|[eE][mM]|[fF][oO][nN][tT]|[hH][eE][aA][dD]|[hH][tT][mM][lL]|[iI]|[iI][mM][gG]|[iI][nN][pP][uU][tT]|[iI][nN][sS]|[iI][sS][iI][nN][dD][eE][xX]|[kK][bB][dD]|[lL][aA][bB][eE][lL]|[lL][eE][gG][eE][nN][dD]|[lL][iI]|[lL][iI][nN][kK]|[mM][aA][pP]|[mM][eE][tT][aA]|[nN][oO][sS][cC][rR][iI][pP][tT]|[oO][pP][tT][gG][rR][oO][uU][pP]|[oO][pP][tT][iI][oO][nN]|[pP][aA][rR][aA][mM]|[qQ]|[sS]|[sS][aA][mM][pP]|[sS][cC][rR][iI][pP][tT]|[sS][eE][lL][eE][cC][tT]|[sS][mM][aA][lL][lL]|[sS][pP][aA][nN]|[sS][tT][rR][iI][kK][eE]|[sS][tT][rR][oO][nN][gG]|[sS][tT][yY][lL][eE]|[sS][uU][bB]|[sS][uU][pP]|[tT][aA][bB][lL][eE]|[tT][bB][oO][dD][yY]|[tT][dD]|[tT][eE][xX][tT][aA][rR][eE][aA]|[tT][fF][oO][oO][tT]|[tT][hH]|[tT][hH][eE][aA][dD]|[tT][iI][tT][lL][eE]|[tT][rR]|[tT][tT]|[uU]|[vV][aA][rR])\b)|([\s\S])/g,/(<\/?)([a-zA-Z0-9:]+)|([\s\S])/g,/<>|([\s\S])/g,/\\'|\\\\|([\s\S])/g,/(?=;;)|([\s\S])/g,/\\[\\'\[\]]|([\s\S])/g,/(?=\s*extends|(?=\n)|\{)|([\s\S])/g,/(?=\s*\b(?:([eE][xX][tT][eE][nN][dD][sS])))|(?=\n)|([\s\S])/g,/,\s*([a-zA-Z0-9_]+)(\s*)|([\s\S])/g,/(?=\)\s*:)|([\s\S])/g,/\b([a-zA-Z_][a-zA-Z_0-9]*)(\s*(?:(,)|(?=[\n\)])))|([\s\S])/g,/(?=\b(?:esac)\b)|([\s\S])/g,/^(JAVASCRIPT)((;?)((?=\n)\n?))|([\s\S])/g,/(\$)((_(COOKIE|FILES|GET|POST|REQUEST))\b)|([\s\S])/g,/\$|/g,/(#)((?!\{).*(?=\n)\n?)|([\s\S])/g,/((?: ?\/)?>)|([\s\S])/g,/(?=>)|([\s\S])/g,/"[^">]*"|([\s\S])/g,/(\-\-)(.*(?=\n)\n?)|([\s\S])/g,/\(\*|([\s\S])/g,/(\w*)(\s*(=))|([\s\S])/g,/\][eimnosux]*|([\s\S])/g,/(array)(\()|([\s\S])/g,/(?:\b([sS]([hH][uU][fF][fF][lL][eE]|[oO][rR][tT])|[nN]([eE][xX][tT]|[aA][tT]([sS][oO][rR][tT]|[cC][aA][sS][eE][sS][oO][rR][tT]))|[cC]([oO]([uU][nN][tT]|[mM][pP][aA][cC][tT])|[uU][rR][rR][eE][nN][tT])|[iI][nN]_[aA][rR][rR][aA][yY]|[uU]([sS][oO][rR][tT]|[kK][sS][oO][rR][tT]|[aA][sS][oO][rR][tT])|[pP][rR][eE][vV]|[eE]([nN][dD]|[xX][tT][rR][aA][cC][tT])|[kK]([sS][oO][rR][tT]|[eE][yY]|[rR][sS][oO][rR][tT])|[aA]([sS][oO][rR][tT]|[rR]([sS][oO][rR][tT]|[rR][aA][yY]_([sS]([hH][iI][fF][tT]|[uU][mM]|[pP][lL][iI][cC][eE]|[eE][aA][rR][cC][hH]|[lL][iI][cC][eE])|[cC]([hH]([uU][nN][kK]|[aA][nN][gG][eE]_[kK][eE][yY]_[cC][aA][sS][eE])|[oO]([uU][nN][tT]_[vV][aA][lL][uU][eE][sS]|[mM][bB][iI][nN][eE]))|[iI][nN][tT][eE][rR][sS][eE][cC][tT](_([uU]([kK][eE][yY]|[aA][sS][sS][oO][cC])|[kK][eE][yY]|[aA][sS][sS][oO][cC]))?|[dD][iI][fF][fF](_([uU]([kK][eE][yY]|[aA][sS][sS][oO][cC])|[kK][eE][yY]|[aA][sS][sS][oO][cC]))?|[uU]([nN]([sS][hH][iI][fF][tT]|[iI][qQ][uU][eE])|[iI][nN][tT][eE][rR][sS][eE][cC][tT](_([uU][aA][sS][sS][oO][cC]|[aA][sS][sS][oO][cC]))?|[dD][iI][fF][fF](_([uU][aA][sS][sS][oO][cC]|[aA][sS][sS][oO][cC]))?)|[pP]([oO][pP]|[uU][sS][hH]|[aA][dD]|[rR][oO][dD][uU][cC][tT])|[vV][aA][lL][uU][eE][sS]|[kK][eE][yY]([sS]|_[eE][xX][iI][sS][tT][sS])|[fF]([iI][lL]([tT][eE][rR]|[lL](_[kK][eE][yY][sS])?)|[lL][iI][pP])|[wW][aA][lL][kK](_[rR][eE][cC][uU][rR][sS][iI][vV][eE])?|[rR]([eE]([dD][uU][cC][eE]|[vV][eE][rR][sS][eE])|[aA][nN][dD])|[mM]([uU][lL][tT][iI][sS][oO][rR][tT]|[eE][rR][gG][eE](_[rR][eE][cC][uU][rR][sS][iI][vV][eE])?|[aA][pP]))))|[rR]([sS][oO][rR][tT]|[eE][sS][eE][tT]|[aA][nN][gG][eE])|[mM]([iI][nN]|[aA][xX]))(?=\s*\())|([\s\S])/g,/(?:\b[aA][sS][sS][eE][rR][tT](_[oO][pP][tT][iI][oO][nN][sS])?(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[aA][tT][tT][rR]_[iI][sS]_[iI][dD](?=\s*\())|([\s\S])/g,/(?:\b[bB][aA][sS][eE]64_([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])(?=\s*\())|([\s\S])/g,/(?:\b([hH][iI][gG][hH][lL][iI][gG][hH][tT]_([sS][tT][rR][iI][nN][gG]|[fF][iI][lL][eE])|[sS]([yY][sS]_[gG][eE][tT][lL][oO][aA][dD][aA][vV][gG]|[eE][tT]_([iI][nN][cC][lL][uU][dD][eE]_[pP][aA][tT][hH]|[mM][aA][gG][iI][cC]_[qQ][uU][oO][tT][eE][sS]_[rR][uU][nN][tT][iI][mM][eE])|[lL][eE][eE][pP])|[cC]([oO][nN]([sS][tT][aA][nN][tT]|[nN][eE][cC][tT][iI][oO][nN]_([sS][tT][aA][tT][uU][sS]|[aA][bB][oO][rR][tT][eE][dD]))|[aA][lL][lL]_[uU][sS][eE][rR]_([fF][uU][nN][cC](_[aA][rR][rR][aA][yY])?|[mM][eE][tT][hH][oO][dD](_[aA][rR][rR][aA][yY])?))|[tT][iI][mM][eE]_([sS][lL][eE][eE][pP]_[uU][nN][tT][iI][lL]|[nN][aA][nN][oO][sS][lL][eE][eE][pP])|[iI]([sS]_[uU][pP][lL][oO][aA][dD][eE][dD]_[fF][iI][lL][eE]|[nN]([iI]_([sS][eE][tT]|[rR][eE][sS][tT][oO][rR][eE]|[gG][eE][tT](_[aA][lL][lL])?)|[eE][tT]_([nN][tT][oO][pP]|[pP][tT][oO][nN]))|[pP]2[lL][oO][nN][gG]|[gG][nN][oO][rR][eE]_[uU][sS][eE][rR]_[aA][bB][oO][rR][tT]|[mM][pP][oO][rR][tT]_[rR][eE][qQ][uU][eE][sS][tT]_[vV][aA][rR][iI][aA][bB][lL][eE][sS])|[uU]([sS][lL][eE][eE][pP]|[nN][rR][eE][gG][iI][sS][tT][eE][rR]_[tT][iI][cC][kK]_[fF][uU][nN][cC][tT][iI][oO][nN])|[eE][rR][rR][oO][rR]_([lL][oO][gG]|[gG][eE][tT]_[lL][aA][sS][tT])|[pP]([hH][pP]_[sS][tT][rR][iI][pP]_[wW][hH][iI][tT][eE][sS][pP][aA][cC][eE]|[uU][tT][eE][nN][vV]|[aA][rR][sS][eE]_[iI][nN][iI]_[fF][iI][lL][eE]|[rR][iI][nN][tT]_[rR])|[fF][lL][uU][sS][hH]|[lL][oO][nN][gG]2[iI][pP]|[rR][eE]([sS][tT][oO][rR][eE]_[iI][nN][cC][lL][uU][dD][eE]_[pP][aA][tT][hH]|[gG][iI][sS][tT][eE][rR]_([sS][hH][uU][tT][dD][oO][wW][nN]_[fF][uU][nN][cC][tT][iI][oO][nN]|[tT][iI][cC][kK]_[fF][uU][nN][cC][tT][iI][oO][nN]))|[gG][eE][tT]([sS][eE][rR][vV][bB][yY]([nN][aA][mM][eE]|[pP][oO][rR][tT])|[oO][pP][tT]|_([cC]([uU][rR][rR][eE][nN][tT]_[uU][sS][eE][rR]|[fF][gG]_[vV][aA][rR])|[iI][nN][cC][lL][uU][dD][eE]_[pP][aA][tT][hH]|[mM][aA][gG][iI][cC]_[qQ][uU][oO][tT][eE][sS]_([gG][pP][cC]|[rR][uU][nN][tT][iI][mM][eE]))|[pP][rR][oO][tT][oO][bB][yY][nN]([uU][mM][bB][eE][rR]|[aA][mM][eE])|[eE][nN][vV])|[mM][oO][vV][eE]_[uU][pP][lL][oO][aA][dD][eE][dD]_[fF][iI][lL][eE])(?=\s*\())|([\s\S])/g,/(?:\b[bB][cC]([sS]([cC][aA][lL][eE]|[uU][bB]|[qQ][rR][tT])|[cC][oO][mM][pP]|[dD][iI][vV]|[pP][oO][wW]([mM][oO][dD])?|[aA][dD][dD]|[mM]([oO][dD]|[uU][lL]))(?=\s*\())|([\s\S])/g,/(?:\b[bB][iI][rR][dD][sS][tT][eE][pP]_([cC]([oO]([nN][nN][eE][cC][tT]|[mM][mM][iI][tT])|[lL][oO][sS][eE])|[oO][fF][fF]_[aA][uU][tT][oO][cC][oO][mM][mM][iI][tT]|[eE][xX][eE][cC]|[fF]([iI][eE][lL][dD][nN]([uU][mM]|[aA][mM][eE])|[eE][tT][cC][hH]|[rR][eE][eE][rR][eE][sS][uU][lL][tT])|[aA][uU][tT][oO][cC][oO][mM][mM][iI][tT]|[rR]([oO][lL][lL][bB][aA][cC][kK]|[eE][sS][uU][lL][tT]))(?=\s*\())|([\s\S])/g,/(?:\b[gG][eE][tT]_[bB][rR][oO][wW][sS][eE][rR](?=\s*\())|([\s\S])/g,/(?:\b([sS]([tT][rR]([nN][cC]([aA][sS][eE][cC][mM][pP]|[mM][pP])|[cC]([aA][sS][eE][cC][mM][pP]|[mM][pP])|[lL][eE][nN])|[eE][tT]_[eE]([rR][rR][oO][rR]_[hH][aA][nN][dD][lL][eE][rR]|[xX][cC][eE][pP][tT][iI][oO][nN]_[hH][aA][nN][dD][lL][eE][rR]))|[cC]([lL][aA][sS][sS]_[eE][xX][iI][sS][tT][sS]|[rR][eE][aA][tT][eE]_[fF][uU][nN][cC][tT][iI][oO][nN])|[tT][rR][iI][gG][gG][eE][rR]_[eE][rR][rR][oO][rR]|[iI]([sS]_([sS][uU][bB][cC][lL][aA][sS][sS]_[oO][fF]|[aA])|[nN][tT][eE][rR][fF][aA][cC][eE]_[eE][xX][iI][sS][tT][sS])|[dD][eE]([fF][iI][nN][eE]([dD])?|[bB][uU][gG]_([pP][rR][iI][nN][tT]_[bB][aA][cC][kK][tT][rR][aA][cC][eE]|[bB][aA][cC][kK][tT][rR][aA][cC][eE]))|[zZ][eE][nN][dD]_[vV][eE][rR][sS][iI][oO][nN]|[pP][rR][oO][pP][eE][rR][tT][yY]_[eE][xX][iI][sS][tT][sS]|[eE]([aA][cC][hH]|[rR][rR][oO][rR]_[rR][eE][pP][oO][rR][tT][iI][nN][gG]|[xX][tT][eE][nN][sS][iI][oO][nN]_[lL][oO][aA][dD][eE][dD])|[fF][uU][nN][cC]([tT][iI][oO][nN]_[eE][xX][iI][sS][tT][sS]|_([nN][uU][mM]_[aA][rR][gG][sS]|[gG][eE][tT]_[aA][rR][gG]([sS])?))|[lL][eE][aA][kK]|[rR][eE][sS][tT][oO][rR][eE]_[eE]([rR][rR][oO][rR]_[hH][aA][nN][dD][lL][eE][rR]|[xX][cC][eE][pP][tT][iI][oO][nN]_[hH][aA][nN][dD][lL][eE][rR])|[gG][eE][tT]_([cC][lL][aA][sS][sS](_([vV][aA][rR][sS]|[mM][eE][tT][hH][oO][dD][sS]))?|[iI][nN][cC][lL][uU][dD][eE][dD]_[fF][iI][lL][eE][sS]|[dD][eE]([cC][lL][aA][rR][eE][dD]_([cC][lL][aA][sS][sS][eE][sS]|[iI][nN][tT][eE][rR][fF][aA][cC][eE][sS])|[fF][iI][nN][eE][dD]_([cC][oO][nN][sS][tT][aA][nN][tT][sS]|[vV][aA][rR][sS]|[fF][uU][nN][cC][tT][iI][oO][nN][sS]))|[oO][bB][jJ][eE][cC][tT]_[vV][aA][rR][sS]|[eE][xX][tT][eE][nN][sS][iI][oO][nN]_[fF][uU][nN][cC][sS]|[pP][aA][rR][eE][nN][tT]_[cC][lL][aA][sS][sS]|[lL][oO][aA][dD][eE][dD]_[eE][xX][tT][eE][nN][sS][iI][oO][nN][sS]|[rR][eE][sS][oO][uU][rR][cC][eE]_[tT][yY][pP][eE])|[mM][eE][tT][hH][oO][dD]_[eE][xX][iI][sS][tT][sS])(?=\s*\())|([\s\S])/g,/(?:\b[bB][zZ]([cC][oO][mM][pP][rR][eE][sS][sS]|[dD][eE][cC][oO][mM][pP][rR][eE][sS][sS]|[oO][pP][eE][nN]|[eE][rR][rR]([sS][tT][rR]|[nN][oO]|[oO][rR])|[rR][eE][aA][dD])(?=\s*\())|([\s\S])/g,/(?:\b([jJ][dD][tT][oO][uU][nN][iI][xX]|[uU][nN][iI][xX][tT][oO][jJ][dD])(?=\s*\())|([\s\S])/g,/(?:\b([cC][aA][lL]_([tT][oO]_[jJ][dD]|[iI][nN][fF][oO]|[dD][aA][yY][sS]_[iI][nN]_[mM][oO][nN][tT][hH]|[fF][rR][oO][mM]_[jJ][dD])|[jJ]([dD]([tT][oO]([jJ]([uU][lL][iI][aA][nN]|[eE][wW][iI][sS][hH])|[fF][rR][eE][nN][cC][hH]|[gG][rR][eE][gG][oO][rR][iI][aA][nN])|[dD][aA][yY][oO][fF][wW][eE][eE][kK]|[mM][oO][nN][tT][hH][nN][aA][mM][eE])|[uU][lL][iI][aA][nN][tT][oO][jJ][dD]|[eE][wW][iI][sS][hH][tT][oO][jJ][dD])|[fF][rR][eE][nN][cC][hH][tT][oO][jJ][dD]|[gG][rR][eE][gG][oO][rR][iI][aA][nN][tT][oO][jJ][dD])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[cC][hH][aA][rR][aA][cC][tT][eE][rR][dD][aA][tT][aA]_([sS][uU][bB][sS][tT][rR][iI][nN][gG]_[dD][aA][tT][aA]|[iI][nN][sS][eE][rR][tT]_[dD][aA][tT][aA]|[dD][eE][lL][eE][tT][eE]_[dD][aA][tT][aA]|[aA][pP][pP][eE][nN][dD]_[dD][aA][tT][aA]|[rR][eE][pP][lL][aA][cC][eE]_[dD][aA][tT][aA])(?=\s*\())|([\s\S])/g,/(?:\b[cC][oO][mM]_([cC][rR][eE][aA][tT][eE]_[gG][uU][iI][dD]|[pP][rR][iI][nN][tT]_[tT][yY][pP][eE][iI][nN][fF][oO]|[eE][vV][eE][nN][tT]_[sS][iI][nN][kK]|[lL][oO][aA][dD]_[tT][yY][pP][eE][lL][iI][bB]|[gG][eE][tT]_[aA][cC][tT][iI][vV][eE]_[oO][bB][jJ][eE][cC][tT]|[mM][eE][sS][sS][aA][gG][eE]_[pP][uU][mM][pP])(?=\s*\())|([\s\S])/g,/(?:\b[vV][aA][rR][iI][aA][nN][tT]_([sS]([uU][bB]|[eE][tT](_[tT][yY][pP][eE])?)|[nN]([oO][tT]|[eE][gG])|[cC]([aA]([sS][tT]|[tT])|[mM][pP])|[iI]([nN][tT]|[dD][iI][vV]|[mM][pP])|[oO][rR]|[dD]([iI][vV]|[aA][tT][eE]_([tT][oO]_[tT][iI][mM][eE][sS][tT][aA][mM][pP]|[fF][rR][oO][mM]_[tT][iI][mM][eE][sS][tT][aA][mM][pP]))|[pP][oO][wW]|[eE][qQ][vV]|[fF][iI][xX]|[aA]([nN][dD]|[dD][dD]|[bB][sS])|[gG][eE][tT]_[tT][yY][pP][eE]|[rR][oO][uU][nN][dD]|[xX][oO][rR]|[mM]([oO][dD]|[uU][lL]))(?=\s*\())|([\s\S])/g,/(?:\b[cC][rR][cC]32(?=\s*\())|([\s\S])/g,/(?:\b[cC][rR][yY][pP][tT](?=\s*\())|([\s\S])/g,/(?:\b[cC][tT][yY][pP][eE]_([sS][pP][aA][cC][eE]|[cC][nN][tT][rR][lL]|[dD][iI][gG][iI][tT]|[uU][pP][pP][eE][rR]|[pP]([uU][nN][cC][tT]|[rR][iI][nN][tT])|[lL][oO][wW][eE][rR]|[aA][lL]([nN][uU][mM]|[pP][hH][aA])|[gG][rR][aA][pP][hH]|[xX][dD][iI][gG][iI][tT])(?=\s*\())|([\s\S])/g,/(?:\b[cC][oO][nN][vV][eE][rR][tT]_[cC][yY][rR]_[sS][tT][rR][iI][nN][gG](?=\s*\())|([\s\S])/g,/(?:\b[sS][tT][rR][pP][tT][iI][mM][eE](?=\s*\())|([\s\S])/g,/(?:\b[dD][bB][aA]_([hH][aA][nN][dD][lL][eE][rR][sS]|[sS][yY][nN][cC]|[nN][eE][xX][tT][kK][eE][yY]|[cC][lL][oO][sS][eE]|[iI][nN][sS][eE][rR][tT]|[dD][eE][lL][eE][tT][eE]|[oO][pP]([tT][iI][mM][iI][zZ][eE]|[eE][nN])|[eE][xX][iI][sS][tT][sS]|[pP][oO][pP][eE][nN]|[kK][eE][yY]_[sS][pP][lL][iI][tT]|[fF]([iI][rR][sS][tT][kK][eE][yY]|[eE][tT][cC][hH])|[lL][iI][sS][tT]|[rR][eE][pP][lL][aA][cC][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][bB][aA][sS][eE]_([nN][uU][mM]([fF][iI][eE][lL][dD][sS]|[rR][eE][cC][oO][rR][dD][sS])|[cC]([lL][oO][sS][eE]|[rR][eE][aA][tT][eE])|[dD][eE][lL][eE][tT][eE]_[rR][eE][cC][oO][rR][dD]|[oO][pP][eE][nN]|[pP][aA][cC][kK]|[aA][dD][dD]_[rR][eE][cC][oO][rR][dD]|[gG][eE][tT]_([hH][eE][aA][dD][eE][rR]_[iI][nN][fF][oO]|[rR][eE][cC][oO][rR][dD](_[wW][iI][tT][hH]_[nN][aA][mM][eE][sS])?)|[rR][eE][pP][lL][aA][cC][eE]_[rR][eE][cC][oO][rR][dD])(?=\s*\())|([\s\S])/g,/(?:\b([sS][cC][aA][nN][dD][iI][rR]|[cC]([hH]([dD][iI][rR]|[rR][oO][oO][tT])|[lL][oO][sS][eE][dD][iI][rR])|[dD][iI][rR]|[oO][pP][eE][nN][dD][iI][rR]|[rR][eE]([aA][dD][dD][iI][rR]|[wW][iI][nN][dD][dD][iI][rR])|[gG]([eE][tT][cC][wW][dD]|[lL][oO][bB]))(?=\s*\())|([\s\S])/g,/(?:\b[dD][lL](?=\s*\())|([\s\S])/g,/(?:\b([dD][nN][sS]_([cC][hH][eE][cC][kK]_[rR][eE][cC][oO][rR][dD]|[gG][eE][tT]_([rR][eE][cC][oO][rR][dD]|[mM][xX]))|[gG][eE][tT][hH][oO][sS][tT][bB][yY]([nN][aA][mM][eE]([lL])?|[aA][dD][dD][rR]))(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][cC][uU][mM][eE][nN][tT]_([sS]([cC][hH][eE][mM][aA]_[vV][aA][lL][iI][dD][aA][tT][eE](_[fF][iI][lL][eE])?|[aA][vV][eE](_[hH][tT][mM][lL](_[fF][iI][lL][eE])?|[xX][mM][lL])?)|[nN][oO][rR][mM][aA][lL][iI][zZ][eE]_[dD][oO][cC][uU][mM][eE][nN][tT]|[cC][rR][eE][aA][tT][eE]_([cC]([dD][aA][tT][aA][sS][eE][cC][tT][iI][oO][nN]|[oO][mM][mM][eE][nN][tT])|[tT][eE][xX][tT]_[nN][oO][dD][eE]|[dD][oO][cC][uU][mM][eE][nN][tT]_[fF][rR][aA][gG][mM][eE][nN][tT]|[pP][rR][oO][cC][eE][sS][sS][iI][nN][gG]_[iI][nN][sS][tT][rR][uU][cC][tT][iI][oO][nN]|[eE]([nN][tT][iI][tT][yY]_[rR][eE][fF][eE][rR][eE][nN][cC][eE]|[lL][eE][mM][eE][nN][tT](_[nN][sS])?)|[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN][sS])?)|[iI][mM][pP][oO][rR][tT]_[nN][oO][dD][eE]|[vV][aA][lL][iI][dD][aA][tT][eE]|[lL][oO][aA][dD](_[hH][tT][mM][lL](_[fF][iI][lL][eE])?|[xX][mM][lL])?|[aA][dD][oO][pP][tT]_[nN][oO][dD][eE]|[rR][eE]([nN][aA][mM][eE]_[nN][oO][dD][eE]|[lL][aA][xX][nN][gG]_[vV][aA][lL][iI][dD][aA][tT][eE]_([fF][iI][lL][eE]|[xX][mM][lL]))|[gG][eE][tT]_[eE][lL][eE][mM][eE][nN][tT]([sS]_[bB][yY]_[tT][aA][gG]_[nN][aA][mM][eE](_[nN][sS])?|_[bB][yY]_[iI][dD])|[xX][iI][nN][cC][lL][uU][dD][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][cC][oO][nN][fF][iI][gG][uU][rR][aA][tT][iI][oO][nN]_([sS][eE][tT]_[pP][aA][rR][aA][mM][eE][tT][eE][rR]|[cC][aA][nN]_[sS][eE][tT]_[pP][aA][rR][aA][mM][eE][tT][eE][rR]|[gG][eE][tT]_[pP][aA][rR][aA][mM][eE][tT][eE][rR])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][eE][rR][rR][oO][rR][hH][aA][nN][dD][lL][eE][rR]_[hH][aA][nN][dD][lL][eE]_[eE][rR][rR][oO][rR](?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][iI][mM][pP][lL][eE][mM][eE][nN][tT][aA][tT][iI][oO][nN]_([hH][aA][sS]_[fF][eE][aA][tT][uU][rR][eE]|[cC][rR][eE][aA][tT][eE]_[dD][oO][cC][uU][mM][eE][nN][tT](_[tT][yY][pP][eE])?|[gG][eE][tT]_[fF][eE][aA][tT][uU][rR][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][iI][mM][pP][lL][eE][mM][eE][nN][tT][aA][tT][iI][oO][nN][lL][iI][sS][tT]_[iI][tT][eE][mM](?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][iI][mM][pP][lL][eE][mM][eE][nN][tT][aA][tT][iI][oO][nN][sS][oO][uU][rR][cC][eE]_[gG][eE][tT]_[dD][oO][mM][iI][mM][pP][lL][eE][mM][eE][nN][tT][aA][tT][iI][oO][nN]([sS])?(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[dD][oO][mM][sS][tT][rR][iI][nN][gG][lL][iI][sS][tT]_[iI][tT][eE][mM](?=\s*\())|([\s\S])/g,/(?:\b[eE][aA][sS][tT][eE][rR]_[dD][aA]([yY][sS]|[tT][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[eE][lL][eE][mM][eE][nN][tT]_([hH][aA][sS]_[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN][sS])?|[sS][eE][tT]_([iI][dD]_[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN]([sS]|[oO][dD][eE]))?|[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN]([sS]|[oO][dD][eE](_[nN][sS])?))?)|[rR][eE][mM][oO][vV][eE]_[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN]([sS]|[oO][dD][eE]))?|[gG][eE][tT]_([eE][lL][eE][mM][eE][nN][tT][sS]_[bB][yY]_[tT][aA][gG]_[nN][aA][mM][eE](_[nN][sS])?|[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN]([sS]|[oO][dD][eE](_[nN][sS])?))?))(?=\s*\())|([\s\S])/g,/(?:\b([sS]([hH][eE][lL][lL]_[eE][xX][eE][cC]|[yY][sS][tT][eE][mM])|[pP]([aA][sS][sS][tT][hH][rR][uU]|[rR][oO][cC]_[nN][iI][cC][eE])|[eE]([sS][cC][aA][pP][eE][sS][hH][eE][lL][lL]([cC][mM][dD]|[aA][rR][gG])|[xX][eE][cC]))(?=\s*\())|([\s\S])/g,/(?:\b[eE][xX][iI][fF]_([iI][mM][aA][gG][eE][tT][yY][pP][eE]|[tT]([hH][uU][mM][bB][nN][aA][iI][lL]|[aA][gG][nN][aA][mM][eE])|[rR][eE][aA][dD]_[dD][aA][tT][aA])(?=\s*\())|([\s\S])/g,/(?:\b[fF][dD][fF]_([hH][eE][aA][dD][eE][rR]|[sS]([eE][tT]_([sS]([tT][aA][tT][uU][sS]|[uU][bB][mM][iI][tT]_[fF][oO][rR][mM]_[aA][cC][tT][iI][oO][nN])|[tT][aA][rR][gG][eE][tT]_[fF][rR][aA][mM][eE]|[oO]([nN]_[iI][mM][pP][oO][rR][tT]_[jJ][aA][vV][aA][sS][cC][rR][iI][pP][tT]|[pP][tT])|[jJ][aA][vV][aA][sS][cC][rR][iI][pP][tT]_[aA][cC][tT][iI][oO][nN]|[eE][nN][cC][oO][dD][iI][nN][gG]|[vV]([eE][rR][sS][iI][oO][nN]|[aA][lL][uU][eE])|[fF]([iI][lL][eE]|[lL][aA][gG][sS])|[aA][pP])|[aA][vV][eE](_[sS][tT][rR][iI][nN][gG])?)|[nN][eE][xX][tT]_[fF][iI][eE][lL][dD]_[nN][aA][mM][eE]|[cC]([lL][oO][sS][eE]|[rR][eE][aA][tT][eE])|[oO][pP][eE][nN](_[sS][tT][rR][iI][nN][gG])?|[eE]([nN][uU][mM]_[vV][aA][lL][uU][eE][sS]|[rR][rR]([nN][oO]|[oO][rR]))|[aA][dD][dD]_([tT][eE][mM][pP][lL][aA][tT][eE]|[dD][oO][cC]_[jJ][aA][vV][aA][sS][cC][rR][iI][pP][tT])|[rR][eE][mM][oO][vV][eE]_[iI][tT][eE][mM]|[gG][eE][tT]_([sS][tT][aA][tT][uU][sS]|[oO][pP][tT]|[eE][nN][cC][oO][dD][iI][nN][gG]|[vV]([eE][rR][sS][iI][oO][nN]|[aA][lL][uU][eE])|[fF]([iI][lL][eE]|[lL][aA][gG][sS])|[aA]([tT][tT][aA][cC][hH][mM][eE][nN][tT]|[pP])))(?=\s*\())|([\s\S])/g,/(?:\b([sS][yY][sS]_[gG][eE][tT]_[tT][eE][mM][pP]_[dD][iI][rR]|[cC][oO][pP][yY]|[tT]([eE][mM][pP][nN][aA][mM]|[mM][pP][fF][iI][lL][eE])|[uU]([nN][lL][iI][nN][kK]|[mM][aA][sS][kK])|[pP]([cC][lL][oO][sS][eE]|[oO][pP][eE][nN])|[fF]([sS]([cC][aA][nN][fF]|[tT][aA][tT]|[eE][eE][kK])|[nN][mM][aA][tT][cC][hH]|[cC][lL][oO][sS][eE]|[tT]([eE][lL][lL]|[rR][uU][nN][cC][aA][tT][eE])|[iI][lL][eE](_([pP][uU][tT]_[cC][oO][nN][tT][eE][nN][tT][sS]|[gG][eE][tT]_[cC][oO][nN][tT][eE][nN][tT][sS]))?|[oO][pP][eE][nN]|[pP]([uU][tT][cC][sS][vV]|[aA][sS][sS][tT][hH][rR][uU])|[eE][oO][fF]|[fF][lL][uU][sS][hH]|[wW][rR][iI][tT][eE]|[lL][oO][cC][kK]|[rR][eE][aA][dD]|[gG][eE][tT]([sS]([sS])?|[cC]([sS][vV])?))|[rR]([eE]([nN][aA][mM][eE]|[aA]([dD][fF][iI][lL][eE]|[lL][pP][aA][tT][hH])|[wW][iI][nN][dD])|[mM][dD][iI][rR])|[gG][eE][tT]_[mM][eE][tT][aA]_[tT][aA][gG][sS]|[mM][kK][dD][iI][rR])(?=\s*\())|([\s\S])/g,/(?:\b([sS][tT][aA][tT]|[cC]([hH]([oO][wW][nN]|[gG][rR][pP]|[mM][oO][dD])|[lL][eE][aA][rR][sS][tT][aA][tT][cC][aA][cC][hH][eE])|[iI][sS]_([dD][iI][rR]|[eE][xX][eE][cC][uU][tT][aA][bB][lL][eE]|[fF][iI][lL][eE]|[lL][iI][nN][kK]|[wW][rR][iI][tT][aA][bB][lL][eE]|[rR][eE][aA][dD][aA][bB][lL][eE])|[tT][oO][uU][cC][hH]|[dD][iI][sS][kK]_([tT][oO][tT][aA][lL]_[sS][pP][aA][cC][eE]|[fF][rR][eE][eE]_[sS][pP][aA][cC][eE])|[fF][iI][lL][eE]([sS][iI][zZ][eE]|[cC][tT][iI][mM][eE]|[tT][yY][pP][eE]|[iI][nN][oO][dD][eE]|[oO][wW][nN][eE][rR]|_[eE][xX][iI][sS][tT][sS]|[pP][eE][rR][mM][sS]|[aA][tT][iI][mM][eE]|[gG][rR][oO][uU][pP]|[mM][tT][iI][mM][eE])|[lL]([sS][tT][aA][tT]|[cC][hH][gG][rR][pP]))(?=\s*\())|([\s\S])/g,/(?:\b[fF][iI][lL][tT][eE][rR]_([hH][aA][sS]_[vV][aA][rR]|[iI][nN][pP][uU][tT](_[aA][rR][rR][aA][yY])?|[vV][aA][rR](_[aA][rR][rR][aA][yY])?)(?=\s*\())|([\s\S])/g,/(?:\b([sS][pP][rR][iI][nN][tT][fF]|[pP][rR][iI][nN][tT][fF]|[vV]([sS][pP][rR][iI][nN][tT][fF]|[pP][rR][iI][nN][tT][fF]|[fF][pP][rR][iI][nN][tT][fF])|[fF][pP][rR][iI][nN][tT][fF])(?=\s*\())|([\s\S])/g,/(?:\b([pP][fF][sS][oO][cC][kK][oO][pP][eE][nN]|[fF][sS][oO][cC][kK][oO][pP][eE][nN])(?=\s*\())|([\s\S])/g,/(?:\b[fF][tT][oO][kK](?=\s*\())|([\s\S])/g,/(?:\b([iI][mM][aA][gG][eE]([sS]([yY]|[tT][rR][iI][nN][gG]([uU][pP])?|[eE][tT]([sS][tT][yY][lL][eE]|[tT]([hH][iI][cC][kK][nN][eE][sS][sS]|[iI][lL][eE])|[pP][iI][xX][eE][lL]|[bB][rR][uU][sS][hH])|[aA][vV][eE][aA][lL][pP][hH][aA]|[xX])|[cC]([hH][aA][rR]([uU][pP])?|[oO]([nN][vV][oO][lL][uU][tT][iI][oO][nN]|[pP][yY]([rR][eE][sS]([iI][zZ][eE][dD]|[aA][mM][pP][lL][eE][dD])|[mM][eE][rR][gG][eE]([gG][rR][aA][yY])?)?|[lL][oO][rR]([sS]([tT][oO][tT][aA][lL]|[eE][tT]|[fF][oO][rR][iI][nN][dD][eE][xX])|[cC][lL][oO][sS][eE][sS][tT]([hH][wW][bB]|[aA][lL][pP][hH][aA])?|[tT][rR][aA][nN][sS][pP][aA][rR][eE][nN][tT]|[dD][eE][aA][lL][lL][oO][cC][aA][tT][eE]|[eE][xX][aA][cC][tT]([aA][lL][pP][hH][aA])?|[aA]([tT]|[lL][lL][oO][cC][aA][tT][eE]([aA][lL][pP][hH][aA])?)|[rR][eE][sS][oO][lL][vV][eE]([aA][lL][pP][hH][aA])?|[mM][aA][tT][cC][hH]))|[rR][eE][aA][tT][eE]([tT][rR][uU][eE][cC][oO][lL][oO][rR]|[fF][rR][oO][mM]([sS][tT][rR][iI][nN][gG]|[jJ][pP][eE][gG]|[pP][nN][gG]|[wW][bB][mM][pP]|[gG]([iI][fF]|[dD](2([pP][aA][rR][tT])?)?)|[xX]([pP][mM]|[bB][mM])))?)|2[wW][bB][mM][pP]|[tT]([yY][pP][eE][sS]|[tT][fF]([tT][eE][xX][tT]|[bB][bB][oO][xX])|[rR][uU][eE][cC][oO][lL][oO][rR][tT][oO][pP][aA][lL][eE][tT][tT][eE])|[iI]([sS][tT][rR][uU][eE][cC][oO][lL][oO][rR]|[nN][tT][eE][rR][lL][aA][cC][eE])|[dD]([eE][sS][tT][rR][oO][yY]|[aA][sS][hH][eE][dD][lL][iI][nN][eE])|[jJ][pP][eE][gG]|[eE][lL][lL][iI][pP][sS][eE]|[pP]([sS]([sS][lL][aA][nN][tT][fF][oO][nN][tT]|[cC][oO][pP][yY][fF][oO][nN][tT]|[tT][eE][xX][tT]|[eE]([nN][cC][oO][dD][eE][fF][oO][nN][tT]|[xX][tT][eE][nN][dD][fF][oO][nN][tT])|[fF][rR][eE][eE][fF][oO][nN][tT]|[lL][oO][aA][dD][fF][oO][nN][tT]|[bB][bB][oO][xX])|[nN][gG]|[oO][lL][yY][gG][oO][nN]|[aA][lL][eE][tT][tT][eE][cC][oO][pP][yY])|[fF]([tT]([tT][eE][xX][tT]|[bB][bB][oO][xX])|[iI][lL]([tT][eE][rR]|[lL]([tT][oO][bB][oO][rR][dD][eE][rR]|[eE][dD]([pP][oO][lL][yY][gG][oO][nN]|[eE][lL][lL][iI][pP][sS][eE]|[aA][rR][cC]|[rR][eE][cC][tT][aA][nN][gG][lL][eE]))?)|[oO][nN][tT]([hH][eE][iI][gG][hH][tT]|[wW][iI][dD][tT][hH]))|[wW][bB][mM][pP]|[aA]([nN][tT][iI][aA][lL][iI][aA][sS]|[lL][pP][hH][aA][bB][lL][eE][nN][dD][iI][nN][gG]|[rR][cC])|[lL]([iI][nN][eE]|[oO][aA][dD][fF][oO][nN][tT]|[aA][yY][eE][rR][eE][fF][fF][eE][cC][tT])|[rR]([oO][tT][aA][tT][eE]|[eE][cC][tT][aA][nN][gG][lL][eE])|[gG]([iI][fF]|[dD](2)?|[aA][mM][mM][aA][cC][oO][rR][rR][eE][cC][tT]|[rR][aA][bB]([sS][cC][rR][eE][eE][nN]|[wW][iI][nN][dD][oO][wW]))|[xX][bB][mM])|[jJ][pP][eE][gG]2[wW][bB][mM][pP]|[pP][nN][gG]2[wW][bB][mM][pP]|[gG][dD]_[iI][nN][fF][oO])(?=\s*\())|([\s\S])/g,/(?:\b([nN][gG][eE][tT][tT][eE][xX][tT]|[tT][eE][xX][tT][dD][oO][mM][aA][iI][nN]|[dD]([nN][gG][eE][tT][tT][eE][xX][tT]|[cC]([nN][gG][eE][tT][tT][eE][xX][tT]|[gG][eE][tT][tT][eE][xX][tT])|[gG][eE][tT][tT][eE][xX][tT])|[gG][eE][tT][tT][eE][xX][tT]|[bB][iI][nN][dD]([tT][eE][xX][tT][dD][oO][mM][aA][iI][nN]|_[tT][eE][xX][tT][dD][oO][mM][aA][iI][nN]_[cC][oO][dD][eE][sS][eE][tT]))(?=\s*\())|([\s\S])/g,/(?:\b[gG][mM][pP]_([hH][aA][mM][dD][iI][sS][tT]|[sS]([cC][aA][nN](1|0)|[iI][gG][nN]|[tT][rR][vV][aA][lL]|[uU][bB]|[eE][tT][bB][iI][tT]|[qQ][rR][tT]([rR][eE][mM])?)|[cC]([oO][mM]|[lL][rR][bB][iI][tT]|[mM][pP])|[nN][eE]([gG]|[xX][tT][pP][rR][iI][mM][eE])|[iI][nN]([tT][vV][aA][lL]|[iI][tT]|[vV][eE][rR][tT])|[oO][rR]|[dD][iI][vV](_([qQ]([rR])?|[rR])|[eE][xX][aA][cC][tT])|[jJ][aA][cC][oO][bB][iI]|[pP]([oO]([pP][cC][oO][uU][nN][tT]|[wW]([mM])?)|[eE][rR][fF][eE][cC][tT]_[sS][qQ][uU][aA][rR][eE]|[rR][oO][bB]_[pP][rR][iI][mM][eE])|[fF][aA][cC][tT]|[lL][eE][gG][eE][nN][dD][rR][eE]|[aA]([nN][dD]|[dD][dD]|[bB][sS])|[rR][aA][nN][dD][oO][mM]|[gG][cC][dD]([eE][xX][tT])?|[xX][oO][rR]|[mM]([oO][dD]|[uU][lL]))(?=\s*\())|([\s\S])/g,/(?:\b[hH][aA][sS][hH](_([hH][mM][aA][cC](_[fF][iI][lL][eE])?|[iI][nN][iI][tT]|[uU][pP][dD][aA][tT][eE](_([sS][tT][rR][eE][aA][mM]|[fF][iI][lL][eE]))?|[fF][iI]([nN][aA][lL]|[lL][eE])|[aA][lL][gG][oO][sS]))?(?=\s*\())|([\s\S])/g,/(?:\b[mM][dD]5(_[fF][iI][lL][eE])?(?=\s*\())|([\s\S])/g,/(?:\b[sS][hH][aA]1(_[fF][iI][lL][eE])?(?=\s*\())|([\s\S])/g,/(?:\b([sS][eE][tT]([cC][oO][oO][kK][iI][eE]|[rR][aA][wW][cC][oO][oO][kK][iI][eE])|[hH][eE][aA][dD][eE][rR]([sS]_([sS][eE][nN][tT]|[lL][iI][sS][tT]))?)(?=\s*\())|([\s\S])/g,/(?:\b([hH][tT][mM][lL]([sS][pP][eE][cC][iI][aA][lL][cC][hH][aA][rR][sS](_[dD][eE][cC][oO][dD][eE])?|_[eE][nN][tT][iI][tT][yY]_[dD][eE][cC][oO][dD][eE]|[eE][nN][tT][iI][tT][iI][eE][sS])|[gG][eE][tT]_[hH][tT][mM][lL]_[tT][rR][aA][nN][sS][lL][aA][tT][iI][oO][nN]_[tT][aA][bB][lL][eE])(?=\s*\())|([\s\S])/g,/(?:\b[hH][tT][tT][pP]_[bB][uU][iI][lL][dD]_[qQ][uU][eE][rR][yY](?=\s*\())|([\s\S])/g,/(?:\b[iI][bB][aA][sS][eE]_[bB][lL][oO][bB]_([cC]([aA][nN][cC][eE][lL]|[lL][oO][sS][eE]|[rR][eE][aA][tT][eE])|[iI]([nN][fF][oO]|[mM][pP][oO][rR][tT])|[oO][pP][eE][nN]|[eE][cC][hH][oO]|[aA][dD][dD]|[gG][eE][tT])(?=\s*\())|([\s\S])/g,/(?:\b[iI][bB][aA][sS][eE]_([sS][eE][tT]_[eE][vV][eE][nN][tT]_[hH][aA][nN][dD][lL][eE][rR]|[fF][rR][eE][eE]_[eE][vV][eE][nN][tT]_[hH][aA][nN][dD][lL][eE][rR]|[wW][aA][iI][tT]_[eE][vV][eE][nN][tT])(?=\s*\())|([\s\S])/g,/(?:\b[iI][bB][aA][sS][eE]_([nN]([uU][mM]_([pP][aA][rR][aA][mM][sS]|[fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[aA][mM][eE]_[rR][eE][sS][uU][lL][tT])|[eE][xX][eE][cC][uU][tT][eE]|[pP]([aA][rR][aA][mM]_[iI][nN][fF][oO]|[rR][eE][pP][aA][rR][eE])|[fF]([iI][eE][lL][dD]_[iI][nN][fF][oO]|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[aA][sS][sS][oO][cC]|[rR][oO][wW])|[rR][eE][eE]_([qQ][uU][eE][rR][yY]|[rR][eE][sS][uU][lL][tT]))|[qQ][uU][eE][rR][yY]|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS])(?=\s*\())|([\s\S])/g,/(?:\b[iI][bB][aA][sS][eE]_([sS][eE][rR][vV]([iI][cC][eE]_([dD][eE][tT][aA][cC][hH]|[aA][tT][tT][aA][cC][hH])|[eE][rR]_[iI][nN][fF][oO])|[dD]([eE][lL][eE][tT][eE]_[uU][sS][eE][rR]|[bB]_[iI][nN][fF][oO])|[aA][dD][dD]_[uU][sS][eE][rR]|[rR][eE][sS][tT][oO][rR][eE]|[bB][aA][cC][kK][uU][pP]|[mM]([oO][dD][iI][fF][yY]_[uU][sS][eE][rR]|[aA][iI][nN][tT][aA][iI][nN]_[dD][bB]))(?=\s*\())|([\s\S])/g,/(?:\b([iI][cC][oO][nN][vV](_([sS]([tT][rR]([pP][oO][sS]|[lL][eE][nN]|[rR][pP][oO][sS])|[uU][bB][sS][tT][rR]|[eE][tT]_[eE][nN][cC][oO][dD][iI][nN][gG])|[gG][eE][tT]_[eE][nN][cC][oO][dD][iI][nN][gG]|[mM][iI][mM][eE]_([dD][eE][cC][oO][dD][eE](_[hH][eE][aA][dD][eE][rR][sS])?|[eE][nN][cC][oO][dD][eE])))?|[oO][bB]_[iI][cC][oO][nN][vV]_[hH][aA][nN][dD][lL][eE][rR])(?=\s*\())|([\s\S])/g,/(?:\b([iI][mM][aA][gG][eE]_[tT][yY][pP][eE]_[tT][oO]_([eE][xX][tT][eE][nN][sS][iI][oO][nN]|[mM][iI][mM][eE]_[tT][yY][pP][eE])|[gG][eE][tT][iI][mM][aA][gG][eE][sS][iI][zZ][eE])(?=\s*\())|([\s\S])/g,/(?:\b([zZ][eE][nN][dD]_[lL][oO][gG][oO]_[gG][uU][iI][dD]|[pP][hH][pP]([cC][rR][eE][dD][iI][tT][sS]|[iI][nN][fF][oO]|_([sS][aA][pP][iI]_[nN][aA][mM][eE]|[iI][nN][iI]_[sS][cC][aA][nN][nN][eE][dD]_[fF][iI][lL][eE][sS]|[uU][nN][aA][mM][eE]|[eE][gG][gG]_[lL][oO][gG][oO]_[gG][uU][iI][dD]|[lL][oO][gG][oO]_[gG][uU][iI][dD]|[rR][eE][aA][lL]_[lL][oO][gG][oO]_[gG][uU][iI][dD])|[vV][eE][rR][sS][iI][oO][nN]))(?=\s*\())|([\s\S])/g,/(?:\b[iI][bB][aA][sS][eE]_([cC]([oO]([nN][nN][eE][cC][tT]|[mM][mM][iI][tT](_[rR][eE][tT])?)|[lL][oO][sS][eE])|[tT][rR][aA][nN][sS]|[dD][rR][oO][pP]_[dD][bB]|[pP][cC][oO][nN][nN][eE][cC][tT]|[eE][rR][rR]([cC][oO][dD][eE]|[mM][sS][gG])|[gG][eE][nN]_[iI][dD]|[rR][oO][lL][lL][bB][aA][cC][kK](_[rR][eE][tT])?)(?=\s*\())|([\s\S])/g,/(?:\b[cC][uU][rR][lL]_([sS][eE][tT][oO][pP][tT](_[aA][rR][rR][aA][yY])?|[cC]([oO][pP][yY]_[hH][aA][nN][dD][lL][eE]|[lL][oO][sS][eE])|[iI][nN][iI][tT]|[eE]([rR][rR]([nN][oO]|[oO][rR])|[xX][eE][cC])|[vV][eE][rR][sS][iI][oO][nN]|[gG][eE][tT][iI][nN][fF][oO])(?=\s*\())|([\s\S])/g,/(?:\b[iI][pP][tT][cC]([pP][aA][rR][sS][eE]|[eE][mM][bB][eE][dD])(?=\s*\())|([\s\S])/g,/(?:\b[jJ][sS][oO][nN]_([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])(?=\s*\())|([\s\S])/g,/(?:\b[lL][cC][gG]_[vV][aA][lL][uU][eE](?=\s*\())|([\s\S])/g,/(?:\b[lL][dD][aA][pP]_([sS]([tT][aA][rR][tT]_[tT][lL][sS]|[oO][rR][tT]|[eE]([tT]_([oO][pP][tT][iI][oO][nN]|[rR][eE][bB][iI][nN][dD]_[pP][rR][oO][cC])|[aA][rR][cC][hH])|[aA][sS][lL]_[bB][iI][nN][dD])|[nN][eE][xX][tT]_([eE][nN][tT][rR][yY]|[aA][tT][tT][rR][iI][bB][uU][tT][eE]|[rR][eE][fF][eE][rR][eE][nN][cC][eE])|[cC][oO]([nN][nN][eE][cC][tT]|[uU][nN][tT]_[eE][nN][tT][rR][iI][eE][sS]|[mM][pP][aA][rR][eE])|[tT]61_[tT][oO]_8859|8859_[tT][oO]_[tT]61|[dD]([nN]2[uU][fF][nN]|[eE][lL][eE][tT][eE])|[uU][nN][bB][iI][nN][dD]|[pP][aA][rR][sS][eE]_[rR][eE]([sS][uU][lL][tT]|[fF][eE][rR][eE][nN][cC][eE])|[eE]([rR][rR]([nN][oO]|2[sS][tT][rR]|[oO][rR])|[xX][pP][lL][oO][dD][eE]_[dD][nN])|[fF]([iI][rR][sS][tT]_([eE][nN][tT][rR][yY]|[aA][tT][tT][rR][iI][bB][uU][tT][eE]|[rR][eE][fF][eE][rR][eE][nN][cC][eE])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[aA][dD][dD]|[lL][iI][sS][tT]|[gG][eE][tT]_([oO][pP][tT][iI][oO][nN]|[dD][nN]|[eE][nN][tT][rR][iI][eE][sS]|[vV][aA][lL][uU][eE][sS]_[lL][eE][nN]|[aA][tT][tT][rR][iI][bB][uU][tT][eE][sS])|[rR][eE]([nN][aA][mM][eE]|[aA][dD])|[mM][oO][dD]_([dD][eE][lL]|[aA][dD][dD]|[rR][eE][pP][lL][aA][cC][eE])|[bB][iI][nN][dD])(?=\s*\())|([\s\S])/g,/(?:\b[lL][eE][vV][eE][nN][sS][hH][tT][eE][iI][nN](?=\s*\())|([\s\S])/g,/(?:\b[lL][iI][bB][xX][mM][lL]_([sS][eE][tT]_[sS][tT][rR][eE][aA][mM][sS]_[cC][oO][nN][tT][eE][xX][tT]|[cC][lL][eE][aA][rR]_[eE][rR][rR][oO][rR][sS]|[uU][sS][eE]_[iI][nN][tT][eE][rR][nN][aA][lL]_[eE][rR][rR][oO][rR][sS]|[gG][eE][tT]_([eE][rR][rR][oO][rR][sS]|[lL][aA][sS][tT]_[eE][rR][rR][oO][rR]))(?=\s*\())|([\s\S])/g,/(?:\b([sS][yY][mM][lL][iI][nN][kK]|[lL][iI][nN][kK]([iI][nN][fF][oO])?|[rR][eE][aA][dD][lL][iI][nN][kK])(?=\s*\())|([\s\S])/g,/(?:\b([eE][zZ][mM][lL][mM]_[hH][aA][sS][hH]|[mM][aA][iI][lL])(?=\s*\())|([\s\S])/g,/(?:\b[sS][eE][tT]_[tT][iI][mM][eE]_[lL][iI][mM][iI][tT](?=\s*\())|([\s\S])/g,/(?:\b([hH]([yY][pP][oO][tT]|[eE][xX][dD][eE][cC])|[sS]([iI][nN]([hH])?|[qQ][rR][tT])|[nN][uU][mM][bB][eE][rR]_[fF][oO][rR][mM][aA][tT]|[cC]([oO][sS]([hH])?|[eE][iI][lL])|[iI][sS]_([nN][aA][nN]|[iI][nN][fF][iI][nN][iI][tT][eE]|[fF][iI][nN][iI][tT][eE])|[tT][aA][nN]([hH])?|[oO][cC][tT][dD][eE][cC]|[dD][eE]([cC]([hH][eE][xX]|[oO][cC][tT]|[bB][iI][nN])|[gG]2[rR][aA][dD])|[eE][xX][pP]([mM]1)?|[pP]([iI]|[oO][wW])|[fF]([lL][oO][oO][rR]|[mM][oO][dD])|[lL][oO][gG](1([pP]|0))?|[aA]([sS][iI][nN]([hH])?|[cC][oO][sS]([hH])?|[tT][aA][nN]([hH]|2)?|[bB][sS])|[rR]([oO][uU][nN][dD]|[aA][dD]2[dD][eE][gG])|[bB]([iI][nN][dD][eE][cC]|[aA][sS][eE]_[cC][oO][nN][vV][eE][rR][tT]))(?=\s*\())|([\s\S])/g,/(?:\b[mM][bB]_([sS]([tT][rR]([sS][tT][rR]|[cC][uU][tT]|[tT][oO]([uU][pP][pP][eE][rR]|[lL][oO][wW][eE][rR])|[iI]([sS][tT][rR]|[pP][oO][sS]|[mM][wW][iI][dD][tT][hH])|[pP][oO][sS]|[wW][iI][dD][tT][hH]|[lL][eE][nN]|[rR]([cC][hH][rR]|[iI]([cC][hH][rR]|[pP][oO][sS])|[pP][oO][sS]))|[uU][bB][sS][tT]([iI][tT][uU][tT][eE]_[cC][hH][aA][rR][aA][cC][tT][eE][rR]|[rR](_[cC][oO][uU][nN][tT])?)|[eE][nN][dD]_[mM][aA][iI][lL])|[hH][tT][tT][pP]_([iI][nN][pP][uU][tT]|[oO][uU][tT][pP][uU][tT])|[cC]([hH][eE][cC][kK]_[eE][nN][cC][oO][dD][iI][nN][gG]|[oO][nN][vV][eE][rR][tT]_([cC][aA][sS][eE]|[eE][nN][cC][oO][dD][iI][nN][gG]|[vV][aA][rR][iI][aA][bB][lL][eE][sS]|[kK][aA][nN][aA]))|[iI][nN][tT][eE][rR][nN][aA][lL]_[eE][nN][cC][oO][dD][iI][nN][gG]|[oO][uU][tT][pP][uU][tT]_[hH][aA][nN][dD][lL][eE][rR]|[dD][eE]([cC][oO][dD][eE]_([nN][uU][mM][eE][rR][iI][cC][eE][nN][tT][iI][tT][yY]|[mM][iI][mM][eE][hH][eE][aA][dD][eE][rR])|[tT][eE][cC][tT]_([oO][rR][dD][eE][rR]|[eE][nN][cC][oO][dD][iI][nN][gG]))|[eE][nN][cC][oO][dD][eE]_([nN][uU][mM][eE][rR][iI][cC][eE][nN][tT][iI][tT][yY]|[mM][iI][mM][eE][hH][eE][aA][dD][eE][rR])|[pP]([aA][rR][sS][eE]_[sS][tT][rR]|[rR][eE][fF][eE][rR][rR][eE][dD]_[mM][iI][mM][eE]_[nN][aA][mM][eE])|[lL]([iI][sS][tT]_([eE][nN][cC][oO][dD][iI][nN][gG][sS](_[aA][lL][iI][aA][sS]_[nN][aA][mM][eE][sS])?|[mM][iI][mM][eE]_[nN][aA][mM][eE][sS])|[aA][nN][gG][uU][aA][gG][eE])|[gG][eE][tT]_[iI][nN][fF][oO])(?=\s*\())|([\s\S])/g,/(?:\b[mM]([cC][rR][yY][pP][tT]_([cC]([fF][bB]|[rR][eE][aA][tT][eE]_[iI][vV]|[bB][cC])|[oO][fF][bB]|[dD][eE][cC][rR][yY][pP][tT]|[eE]([cC][bB]|[nN][cC](_([sS][eE][lL][fF]_[tT][eE][sS][tT]|[iI][sS]_[bB][lL][oO][cC][kK]_([aA][lL][gG][oO][rR][iI][tT][hH][mM](_[mM][oO][dD][eE])?|[mM][oO][dD][eE])|[gG][eE][tT]_([sS][uU][pP][pP][oO][rR][tT][eE][dD]_[kK][eE][yY]_[sS][iI][zZ][eE][sS]|[iI][vV]_[sS][iI][zZ][eE]|[kK][eE][yY]_[sS][iI][zZ][eE]|[aA][lL][gG][oO][rR][iI][tT][hH][mM][sS]_[nN][aA][mM][eE]|[mM][oO][dD][eE][sS]_[nN][aA][mM][eE]|[bB][lL][oO][cC][kK]_[sS][iI][zZ][eE]))|[rR][yY][pP][tT]))|[lL][iI][sS][tT]_([aA][lL][gG][oO][rR][iI][tT][hH][mM][sS]|[mM][oO][dD][eE][sS])|[gG][eE]([nN][eE][rR][iI][cC](_([iI][nN][iI][tT]|[dD][eE][iI][nN][iI][tT]))?|[tT]_([cC][iI][pP][hH][eE][rR]_[nN][aA][mM][eE]|[iI][vV]_[sS][iI][zZ][eE]|[kK][eE][yY]_[sS][iI][zZ][eE]|[bB][lL][oO][cC][kK]_[sS][iI][zZ][eE]))|[mM][oO][dD][uU][lL][eE]_([sS][eE][lL][fF]_[tT][eE][sS][tT]|[cC][lL][oO][sS][eE]|[iI][sS]_[bB][lL][oO][cC][kK]_([aA][lL][gG][oO][rR][iI][tT][hH][mM](_[mM][oO][dD][eE])?|[mM][oO][dD][eE])|[oO][pP][eE][nN]|[gG][eE][tT]_([sS][uU][pP][pP][oO][rR][tT][eE][dD]_[kK][eE][yY]_[sS][iI][zZ][eE][sS]|[aA][lL][gG][oO]_([kK][eE][yY]_[sS][iI][zZ][eE]|[bB][lL][oO][cC][kK]_[sS][iI][zZ][eE]))))|[dD][eE][cC][rR][yY][pP][tT]_[gG][eE][nN][eE][rR][iI][cC])(?=\s*\())|([\s\S])/g,/(?:\b[mM][eE][tT][aA][pP][hH][oO][nN][eE](?=\s*\())|([\s\S])/g,/(?:\b[mM][hH][aA][sS][hH](_([cC][oO][uU][nN][tT]|[kK][eE][yY][gG][eE][nN]_[sS]2[kK]|[gG][eE][tT]_([hH][aA][sS][hH]_[nN][aA][mM][eE]|[bB][lL][oO][cC][kK]_[sS][iI][zZ][eE])))?(?=\s*\())|([\s\S])/g,/(?:\b([gG][eE][tT]([tT][iI][mM][eE][oO][fF][dD][aA][yY]|[rR][uU][sS][aA][gG][eE])|[mM][iI][cC][rR][oO][tT][iI][mM][eE])(?=\s*\())|([\s\S])/g,/(?:\b[mM][iI][mM][eE]_[cC][oO][nN][tT][eE][nN][tT]_[tT][yY][pP][eE](?=\s*\())|([\s\S])/g,/(?:\b([sS][wW][fF]([pP][rR][eE][bB][uU][iI][lL][tT][cC][lL][iI][pP]_[iI][nN][iI][tT]|[vV][iI][dD][eE][oO][sS][tT][rR][eE][aA][mM]_[iI][nN][iI][tT])|[mM][iI][nN][gG]_([sS][eE][tT]([sS][cC][aA][lL][eE]|[cC][uU][bB][iI][cC][tT][hH][rR][eE][sS][hH][oO][lL][dD])|[uU][sS][eE]([sS][wW][fF][vV][eE][rR][sS][iI][oO][nN]|[cC][oO][nN][sS][tT][aA][nN][tT][sS])|[kK][eE][yY][pP][rR][eE][sS][sS]))(?=\s*\())|([\s\S])/g,/(?:\b[cC][uU][rR][lL]_[mM][uU][lL][tT][iI]_([sS][eE][lL][eE][cC][tT]|[cC][lL][oO][sS][eE]|[iI][nN]([iI][tT]|[fF][oO]_[rR][eE][aA][dD])|[eE][xX][eE][cC]|[aA][dD][dD]_[hH][aA][nN][dD][lL][eE]|[gG][eE][tT][cC][oO][nN][tT][eE][nN][tT]|[rR][eE][mM][oO][vV][eE]_[hH][aA][nN][dD][lL][eE])(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL][iI]_([sS]([sS][lL]_[sS][eE][tT]|[tT]([oO][rR][eE]_[rR][eE][sS][uU][lL][tT]|[aA][tT]|[mM][tT]_([sS]([tT][oO][rR][eE]_[rR][eE][sS][uU][lL][tT]|[eE][nN][dD]_[lL][oO][nN][gG]_[dD][aA][tT][aA]|[qQ][lL][sS][tT][aA][tT][eE])|[nN][uU][mM]_[rR][oO][wW][sS]|[cC][lL][oO][sS][eE]|[iI][nN]([sS][eE][rR][tT]_[iI][dD]|[iI][tT])|[dD][aA][tT][aA]_[sS][eE][eE][kK]|[pP]([aA][rR][aA][mM]_[cC][oO][uU][nN][tT]|[rR][eE][pP][aA][rR][eE])|[eE]([rR][rR]([nN][oO]|[oO][rR])|[xX][eE][cC][uU][tT][eE])|[fF]([iI][eE][lL][dD]_[cC][oO][uU][nN][tT]|[eE][tT][cC][hH]|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[aA]([tT][tT][rR]_([sS][eE][tT]|[gG][eE][tT])|[fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS])|[rR][eE][sS]([uU][lL][tT]_[mM][eE][tT][aA][dD][aA][tT][aA]|[eE][tT])|[bB][iI][nN][dD]_([pP][aA][rR][aA][mM]|[rR][eE][sS][uU][lL][tT])))|[eE]([tT]_[lL][oO][cC][aA][lL]_[iI][nN][fF][iI][lL][eE]_([hH][aA][nN][dD][lL][eE][rR]|[dD][eE][fF][aA][uU][lL][tT])|[lL][eE][cC][tT]_[dD][bB])|[qQ][lL][sS][tT][aA][tT][eE])|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][xX][tT]_[rR][eE][sS][uU][lL][tT])|[cC]([hH][aA]([nN][gG][eE]_[uU][sS][eE][rR]|[rR][aA][cC][tT][eE][rR]_[sS][eE][tT]_[nN][aA][mM][eE])|[oO][mM][mM][iI][tT]|[lL][oO][sS][eE])|[tT][hH][rR][eE][aA][dD]_([sS][aA][fF][eE]|[iI][dD])|[iI][nN]([sS][eE][rR][tT]_[iI][dD]|[iI][tT]|[fF][oO])|[oO][pP][tT][iI][oO][nN][sS]|[dD]([uU][mM][pP]_[dD][eE][bB][uU][gG]_[iI][nN][fF][oO]|[eE][bB][uU][gG]|[aA][tT][aA]_[sS][eE][eE][kK])|[uU][sS][eE]_[rR][eE][sS][uU][lL][tT]|[pP]([iI][nN][gG]|[rR][eE][pP][aA][rR][eE])|[eE][rR][rR]([nN][oO]|[oO][rR])|[kK][iI][lL][lL]|[fF]([iI][eE][lL][dD]_([sS][eE][eE][kK]|[cC][oO][uU][nN][tT]|[tT][eE][lL][lL])|[eE][tT][cC][hH]_([fF][iI][eE][lL][dD]([sS]|_[dD][iI][rR][eE][cC][tT])?|[lL][eE][nN][gG][tT][hH][sS]|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[wW][aA][rR][nN][iI][nN][gG]_[cC][oO][uU][nN][tT]|[aA]([uU][tT][oO][cC][oO][mM][mM][iI][tT]|[fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS])|[rR]([oO][lL][lL][bB][aA][cC][kK]|[eE][aA][lL]_([cC][oO][nN][nN][eE][cC][tT]|[eE][sS][cC][aA][pP][eE]_[sS][tT][rR][iI][nN][gG]|[qQ][uU][eE][rR][yY]))|[gG][eE][tT]_([sS][eE][rR][vV][eE][rR]_([iI][nN][fF][oO]|[vV][eE][rR][sS][iI][oO][nN])|[hH][oO][sS][tT]_[iI][nN][fF][oO]|[cC][lL][iI][eE][nN][tT]_([iI][nN][fF][oO]|[vV][eE][rR][sS][iI][oO][nN])|[pP][rR][oO][tT][oO]_[iI][nN][fF][oO])|[mM][oO][rR][eE]_[rR][eE][sS][uU][lL][tT][sS])(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL][iI]_[eE][mM][bB][eE][dD][dD][eE][dD]_[sS][eE][rR][vV][eE][rR]_([sS][tT][aA][rR][tT]|[eE][nN][dD])(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL][iI]_([sS]([tT][mM][tT]_[gG][eE][tT]_[wW][aA][rR][nN][iI][nN][gG][sS]|[eE][tT]_[cC][hH][aA][rR][sS][eE][tT])|[cC][oO][nN][nN][eE][cC][tT](_[eE][rR][rR]([nN][oO]|[oO][rR]))?|[qQ][uU][eE][rR][yY]|[fF][eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[aA]([sS][sS][oO][cC]|[rR][rR][aA][yY]))|[gG][eE][tT]_([cC][hH][aA][rR][sS][eE][tT]|[wW][aA][rR][nN][iI][nN][gG][sS])|[mM][uU][lL][tT][iI]_[qQ][uU][eE][rR][yY])(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL][iI]_([sS]([eE][nN][dD]_[qQ][uU][eE][rR][yY]|[lL][aA][vV][eE]_[qQ][uU][eE][rR][yY])|[dD][iI][sS][aA][bB][lL][eE]_[rR]([pP][lL]_[pP][aA][rR][sS][eE]|[eE][aA][dD][sS]_[fF][rR][oO][mM]_[mM][aA][sS][tT][eE][rR])|[eE][nN][aA][bB][lL][eE]_[rR]([pP][lL]_[pP][aA][rR][sS][eE]|[eE][aA][dD][sS]_[fF][rR][oO][mM]_[mM][aA][sS][tT][eE][rR])|[rR][pP][lL]_([pP]([aA][rR][sS][eE]_[eE][nN][aA][bB][lL][eE][dD]|[rR][oO][bB][eE])|[qQ][uU][eE][rR][yY]_[tT][yY][pP][eE])|[mM][aA][sS][tT][eE][rR]_[qQ][uU][eE][rR][yY])(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL][iI]_[rR][eE][pP][oO][rR][tT](?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[nN][aA][mM][eE][dD][nN][oO][dD][eE][mM][aA][pP]_([sS][eE][tT]_[nN][aA][mM][eE][dD]_[iI][tT][eE][mM](_[nN][sS])?|[iI][tT][eE][mM]|[rR][eE][mM][oO][vV][eE]_[nN][aA][mM][eE][dD]_[iI][tT][eE][mM](_[nN][sS])?|[gG][eE][tT]_[nN][aA][mM][eE][dD]_[iI][tT][eE][mM](_[nN][sS])?)(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[nN][aA][mM][eE][lL][iI][sS][tT]_[gG][eE][tT]_[nN][aA][mM][eE]([sS][pP][aA][cC][eE]_[uU][rR][iI])?(?=\s*\())|([\s\S])/g,/(?:\b[nN][cC][uU][rR][sS][eE][sS]_([sS]([hH][oO][wW]_[pP][aA][nN][eE][lL]|[cC][rR](_([sS][eE][tT]|[iI][nN][iI][tT]|[dD][uU][mM][pP]|[rR][eE][sS][tT][oO][rR][eE])|[lL])|[tT][aA]([nN][dD]([oO][uU][tT]|[eE][nN][dD])|[rR][tT]_[cC][oO][lL][oO][rR])|[lL][kK]_([sS][eE][tT]|[nN][oO][uU][tT][rR][eE][fF][rR][eE][sS][hH]|[cC]([oO][lL][oO][rR]|[lL][eE][aA][rR])|[iI][nN][iI][tT]|[tT][oO][uU][cC][hH]|[aA][tT][tT][rR]([sS][eE][tT]|[oO]([nN]|[fF][fF]))?|[rR][eE]([sS][tT][oO][rR][eE]|[fF][rR][eE][sS][hH]))|[aA][vV][eE][tT][tT][yY])|[hH]([iI][dD][eE]_[pP][aA][nN][eE][lL]|[lL][iI][nN][eE]|[aA]([sS]_([cC][oO][lL][oO][rR][sS]|[iI]([cC]|[lL])|[kK][eE][yY])|[lL][fF][dD][eE][lL][aA][yY]))|[nN]([oO]([nN][lL]|[cC][bB][rR][eE][aA][kK]|[eE][cC][hH][oO]|[qQ][iI][fF][lL][uU][sS][hH]|[rR][aA][wW])|[eE][wW](_[pP][aA][nN][eE][lL]|[pP][aA][dD]|[wW][iI][nN])|[aA][pP][mM][sS]|[lL])|[cC]([oO][lL][oO][rR]_([sS][eE][tT]|[cC][oO][nN][tT][eE][nN][tT])|[uU][rR][sS]_[sS][eE][tT]|[lL]([eE][aA][rR]|[rR][tT][oO]([eE][oO][lL]|[bB][oO][tT]))|[aA][nN]_[cC][hH][aA][nN][gG][eE]_[cC][oO][lL][oO][rR]|[bB][rR][eE][aA][kK])|[tT]([yY][pP][eE][aA][hH][eE][aA][dD]|[iI][mM][eE][oO][uU][tT]|[oO][pP]_[pP][aA][nN][eE][lL]|[eE][rR][mM]([nN][aA][mM][eE]|[aA][tT][tT][rR][sS]))|[iI]([sS][eE][nN][dD][wW][iI][nN]|[nN]([sS]([sS][tT][rR]|[cC][hH]|[tT][rR]|[dD][eE][lL][lL][nN]|[eE][rR][tT][lL][nN])|[cC][hH]|[iI][tT](_([cC][oO][lL][oO][rR]|[pP][aA][iI][rR]))?))|[dD]([oO][uU][pP][dD][aA][tT][eE]|[eE]([fF]([iI][nN][eE]_[kK][eE][yY]|_([sS][hH][eE][lL][lL]_[mM][oO][dD][eE]|[pP][rR][oO][gG]_[mM][oO][dD][eE]))|[lL]([cC][hH]|_[pP][aA][nN][eE][lL]|[eE][tT][eE][lL][nN]|[aA][yY]_[oO][uU][tT][pP][uU][tT]|[wW][iI][nN])))|[uU]([sS][eE]_([dD][eE][fF][aA][uU][lL][tT]_[cC][oO][lL][oO][rR][sS]|[eE]([nN][vV]|[xX][tT][eE][nN][dD][eE][dD]_[nN][aA][mM][eE][sS]))|[nN][gG][eE][tT]([cC][hH]|[mM][oO][uU][sS][eE])|[pP][dD][aA][tT][eE]_[pP][aA][nN][eE][lL][sS])|[pP]([nN][oO][uU][tT][rR][eE][fF][rR][eE][sS][hH]|[uU][tT][pP]|[aA]([nN][eE][lL]_([wW][iI][nN][dD][oO][wW]|[aA][bB][oO][vV][eE]|[bB][eE][lL][oO][wW])|[iI][rR]_[cC][oO][nN][tT][eE][nN][tT])|[rR][eE][fF][rR][eE][sS][hH])|[eE]([cC][hH][oO]([cC][hH][aA][rR])?|[nN][dD]|[rR][aA][sS][eE]([cC][hH][aA][rR])?)|[vV]([iI][dD][aA][tT][tT][rR]|[lL][iI][nN][eE])|[kK]([iI][lL][lL][cC][hH][aA][rR]|[eE][yY]([oO][kK]|[pP][aA][dD]))|[qQ][iI][fF][lL][uU][sS][hH]|[fF]([iI][lL][tT][eE][rR]|[lL]([uU][sS][hH][iI][nN][pP]|[aA][sS][hH]))|[lL][oO][nN][gG][nN][aA][mM][eE]|[wW]([sS][tT][aA][nN][dD]([oO][uU][tT]|[eE][nN][dD])|[hH][lL][iI][nN][eE]|[nN][oO][uU][tT][rR][eE][fF][rR][eE][sS][hH]|[cC]([oO][lL][oO][rR]_[sS][eE][tT]|[lL][eE][aA][rR])|[eE][rR][aA][sS][eE]|[vV][lL][iI][nN][eE]|[aA]([tT][tT][rR]([sS][eE][tT]|[oO]([nN]|[fF][fF]))|[dD][dD]([sS][tT][rR]|[cC][hH]))|[gG][eE][tT][cC][hH]|[rR][eE][fF][rR][eE][sS][hH]|[mM][oO]([uU][sS][eE]_[tT][rR][aA][fF][oO]|[vV][eE])|[bB][oO][rR][dD][eE][rR])|[aA]([sS][sS][uU][mM][eE]_[dD][eE][fF][aA][uU][lL][tT]_[cC][oO][lL][oO][rR][sS]|[tT][tT][rR]([sS][eE][tT]|[oO]([nN]|[fF][fF]))|[dD][dD]([sS][tT][rR]|[nN][sS][tT][rR]|[cC][hH]([sS][tT][rR]|[nN][sS][tT][rR])?))|[rR]([eE]([sS][eE][tT]([tT][yY]|_([sS][hH][eE][lL][lL]_[mM][oO][dD][eE]|[pP][rR][oO][gG]_[mM][oO][dD][eE]))|[pP][lL][aA][cC][eE]_[pP][aA][nN][eE][lL]|[fF][rR][eE][sS][hH])|[aA][wW])|[gG][eE][tT]([yY][xX]|[cC][hH]|[mM]([oO][uU][sS][eE]|[aA][xX][yY][xX]))|[bB]([oO]([tT][tT][oO][mM]_[pP][aA][nN][eE][lL]|[rR][dD][eE][rR])|[eE][eE][pP]|[kK][gG][dD]([sS][eE][tT])?|[aA][uU][dD][rR][aA][tT][eE])|[mM]([oO]([uU][sS][eE]([iI][nN][tT][eE][rR][vV][aA][lL]|_[tT][rR][aA][fF][oO]|[mM][aA][sS][kK])|[vV][eE](_[pP][aA][nN][eE][lL])?)|[eE][tT][aA]|[vV]([hH][lL][iI][nN][eE]|[cC][uU][rR]|[iI][nN][cC][hH]|[dD][eE][lL][cC][hH]|[vV][lL][iI][nN][eE]|[wW][aA][dD][dD][sS][tT][rR]|[aA][dD][dD]([sS][tT][rR]|[nN][sS][tT][rR]|[cC][hH]([sS][tT][rR]|[nN][sS][tT][rR])?)|[gG][eE][tT][cC][hH])))(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[nN][oO][dD][eE]_([sS][eE][tT]_[uU][sS][eE][rR]_[dD][aA][tT][aA]|[hH][aA][sS]_([cC][hH][iI][lL][dD]_[nN][oO][dD][eE][sS]|[aA][tT][tT][rR][iI][bB][uU][tT][eE][sS])|[nN][oO][rR][mM][aA][lL][iI][zZ][eE]|[cC]([oO][mM][pP][aA][rR][eE]_[dD][oO][cC][uU][mM][eE][nN][tT]_[pP][oO][sS][iI][tT][iI][oO][nN]|[lL][oO][nN][eE]_[nN][oO][dD][eE])|[iI]([sS]_([sS]([uU][pP][pP][oO][rR][tT][eE][dD]|[aA][mM][eE]_[nN][oO][dD][eE])|[dD][eE][fF][aA][uU][lL][tT]_[nN][aA][mM][eE][sS][pP][aA][cC][eE]|[eE][qQ][uU][aA][lL]_[nN][oO][dD][eE])|[nN][sS][eE][rR][tT]_[bB][eE][fF][oO][rR][eE])|[lL][oO][oO][kK][uU][pP]_([nN][aA][mM][eE][sS][pP][aA][cC][eE]_[uU][rR][iI]|[pP][rR][eE][fF][iI][xX])|[aA][pP][pP][eE][nN][dD]_[cC][hH][iI][lL][dD]|[gG][eE][tT]_([uU][sS][eE][rR]_[dD][aA][tT][aA]|[fF][eE][aA][tT][uU][rR][eE])|[rR][eE]([pP][lL][aA][cC][eE]_[cC][hH][iI][lL][dD]|[mM][oO][vV][eE]_[cC][hH][iI][lL][dD]))(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[nN][oO][dD][eE][lL][iI][sS][tT]_[iI][tT][eE][mM](?=\s*\())|([\s\S])/g,/(?:\b[nN][sS][aA][pP][iI]_([vV][iI][rR][tT][uU][aA][lL]|[rR][eE]([sS][pP][oO][nN][sS][eE]_[hH][eE][aA][dD][eE][rR][sS]|[qQ][uU][eE][sS][tT]_[hH][eE][aA][dD][eE][rR][sS]))(?=\s*\())|([\s\S])/g,/(?:\b[oO][cC][iI]([sS][eE][tT][bB][uU][fF][fF][eE][rR][iI][nN][gG][lL][oO][bB]|_([sS]([tT][aA][tT][eE][mM][eE][nN][tT]_[tT][yY][pP][eE]|[eE]([tT]_[pP][rR][eE][fF][eE][tT][cC][hH]|[rR][vV][eE][rR]_[vV][eE][rR][sS][iI][oO][nN]))|[cC]([oO]([nN][nN][eE][cC][tT]|[lL][lL][eE][cC][tT][iI][oO][nN]_([sS][iI][zZ][eE]|[tT][rR][iI][mM]|[eE][lL][eE][mM][eE][nN][tT]_([aA][sS][sS][iI][gG][nN]|[gG][eE][tT])|[aA]([sS][sS][iI][gG][nN]|[pP][pP][eE][nN][dD])|[mM][aA][xX])|[mM][mM][iI][tT])|[lL][oO][sS][eE]|[aA][nN][cC][eE][lL])|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][wW]_([cC]([oO]([nN][nN][eE][cC][tT]|[lL][lL][eE][cC][tT][iI][oO][nN])|[uU][rR][sS][oO][rR])|[dD][eE][sS][cC][rR][iI][pP][tT][oO][rR]))|[iI][nN][tT][eE][rR][nN][aA][lL]_[dD][eE][bB][uU][gG]|[dD][eE][fF][iI][nN][eE]_[bB][yY]_[nN][aA][mM][eE]|[pP]([cC][oO][nN][nN][eE][cC][tT]|[aA]([sS][sS][wW][oO][rR][dD]_[cC][hH][aA][nN][gG][eE]|[rR][sS][eE]))|[eE]([rR][rR][oO][rR]|[xX][eE][cC][uU][tT][eE])|[fF]([iI][eE][lL][dD]_([sS]([cC][aA][lL][eE]|[iI][zZ][eE])|[nN][aA][mM][eE]|[iI][sS]_[nN][uU][lL][lL]|[tT][yY][pP][eE](_[rR][aA][wW])?|[pP][rR][eE][cC][iI][sS][iI][oO][nN])|[eE][tT][cC][hH](_([oO][bB][jJ][eE][cC][tT]|[aA]([sS][sS][oO][cC]|[lL][lL]|[rR][rR][aA][yY])|[rR][oO][wW]))?|[rR][eE][eE]_([sS][tT][aA][tT][eE][mM][eE][nN][tT]|[cC][oO][lL][lL][eE][cC][tT][iI][oO][nN]|[dD][eE][sS][cC][rR][iI][pP][tT][oO][rR]))|[lL][oO][bB]_([sS]([iI][zZ][eE]|[eE][eE][kK]|[aA][vV][eE])|[cC]([oO][pP][yY]|[lL][oO][sS][eE])|[tT]([eE][lL][lL]|[rR][uU][nN][cC][aA][tT][eE])|[iI]([sS]_[eE][qQ][uU][aA][lL]|[mM][pP][oO][rR][tT])|[eE]([oO][fF]|[rR][aA][sS][eE]|[xX][pP][oO][rR][tT])|[fF][lL][uU][sS][hH]|[aA][pP][pP][eE][nN][dD]|[wW][rR][iI][tT][eE](_[tT][eE][mM][pP][oO][rR][aA][rR][yY])?|[lL][oO][aA][dD]|[rR][eE]([wW][iI][nN][dD]|[aA][dD]))|[rR]([oO][lL][lL][bB][aA][cC][kK]|[eE][sS][uU][lL][tT])|[bB][iI][nN][dD]_([aA][rR][rR][aA][yY]_[bB][yY]_[nN][aA][mM][eE]|[bB][yY]_[nN][aA][mM][eE]))|[fF][eE][tT][cC][hH][iI][nN][tT][oO]|[gG][eE][tT][bB][uU][fF][fF][eE][rR][iI][nN][gG][lL][oO][bB])(?=\s*\())|([\s\S])/g,/(?:\b[oO][pP][eE][nN][sS][sS][lL]_([sS]([iI][gG][nN]|[eE][aA][lL])|[cC][sS][rR]_([sS][iI][gG][nN]|[nN][eE][wW]|[eE][xX][pP][oO][rR][tT](_[tT][oO]_[fF][iI][lL][eE])?|[gG][eE][tT]_([sS][uU][bB][jJ][eE][cC][tT]|[pP][uU][bB][lL][iI][cC]_[kK][eE][yY]))|[oO][pP][eE][nN]|[eE][rR][rR][oO][rR]_[sS][tT][rR][iI][nN][gG]|[pP]([uU][bB][lL][iI][cC]_([dD][eE][cC][rR][yY][pP][tT]|[eE][nN][cC][rR][yY][pP][tT])|[kK]([cC][sS](12_([eE][xX][pP][oO][rR][tT](_[tT][oO]_[fF][iI][lL][eE])?|[rR][eE][aA][dD])|7_([sS][iI][gG][nN]|[dD][eE][cC][rR][yY][pP][tT]|[eE][nN][cC][rR][yY][pP][tT]|[vV][eE][rR][iI][fF][yY]))|[eE][yY]_([nN][eE][wW]|[eE][xX][pP][oO][rR][tT](_[tT][oO]_[fF][iI][lL][eE])?|[fF][rR][eE][eE]|[gG][eE][tT]_([dD][eE][tT][aA][iI][lL][sS]|[pP]([uU][bB][lL][iI][cC]|[rR][iI][vV][aA][tT][eE]))))|[rR][iI][vV][aA][tT][eE]_([dD][eE][cC][rR][yY][pP][tT]|[eE][nN][cC][rR][yY][pP][tT]))|[vV][eE][rR][iI][fF][yY]|[xX]509_([cC][hH][eE][cC][kK](_[pP][rR][iI][vV][aA][tT][eE]_[kK][eE][yY]|[pP][uU][rR][pP][oO][sS][eE])|[pP][aA][rR][sS][eE]|[eE][xX][pP][oO][rR][tT](_[tT][oO]_[fF][iI][lL][eE])?|[fF][rR][eE][eE]|[rR][eE][aA][dD]))(?=\s*\())|([\s\S])/g,/(?:\b[oO]([uU][tT][pP][uU][tT]_([aA][dD][dD]_[rR][eE][wW][rR][iI][tT][eE]_[vV][aA][rR]|[rR][eE][sS][eE][tT]_[rR][eE][wW][rR][iI][tT][eE]_[vV][aA][rR][sS])|[bB]_([sS][tT][aA][rR][tT]|[cC][lL][eE][aA][nN]|[iI][mM][pP][lL][iI][cC][iI][tT]_[fF][lL][uU][sS][hH]|[eE][nN][dD]_([cC][lL][eE][aA][nN]|[fF][lL][uU][sS][hH])|[fF][lL][uU][sS][hH]|[lL][iI][sS][tT]_[hH][aA][nN][dD][lL][eE][rR][sS]|[gG][eE][tT]_([sS][tT][aA][tT][uU][sS]|[cC]([oO][nN][tT][eE][nN][tT][sS]|[lL][eE][aA][nN])|[fF][lL][uU][sS][hH]|[lL][eE]([nN][gG][tT][hH]|[vV][eE][lL]))))(?=\s*\())|([\s\S])/g,/(?:\b([uU][nN][pP][aA][cC][kK]|[pP][aA][cC][kK])(?=\s*\())|([\s\S])/g,/(?:\b[gG][eE][tT]([lL][aA][sS][tT][mM][oO][dD]|[mM][yY]([iI][nN][oO][dD][eE]|[uU][iI][dD]|[pP][iI][dD]|[gG][iI][dD]))(?=\s*\())|([\s\S])/g,/(?:\b[pP][cC][nN][tT][lL]_([sS]([iI][gG][nN][aA][lL]|[eE][tT][pP][rR][iI][oO][rR][iI][tT][yY])|[eE][xX][eE][cC]|[fF][oO][rR][kK]|[wW]([sS][tT][oO][pP][sS][iI][gG]|[tT][eE][rR][mM][sS][iI][gG]|[iI][fF]([sS]([iI][gG][nN][aA][lL][eE][dD]|[tT][oO][pP][pP][eE][dD])|[eE][xX][iI][tT][eE][dD])|[eE][xX][iI][tT][sS][tT][aA][tT][uU][sS]|[aA][iI][tT]([pP][iI][dD])?)|[aA][lL][aA][rR][mM]|[gG][eE][tT][pP][rR][iI][oO][rR][iI][tT][yY])(?=\s*\())|([\s\S])/g,/(?:\b[pP][dD][oO]_[dD][rR][iI][vV][eE][rR][sS](?=\s*\())|([\s\S])/g,/(?:\b[pP][gG]_([sS][eE]([nN][dD]_([eE][xX][eE][cC][uU][tT][eE]|[pP][rR][eE][pP][aA][rR][eE]|[qQ][uU][eE][rR][yY](_[pP][aA][rR][aA][mM][sS])?)|[tT]_([cC][lL][iI][eE][nN][tT]_[eE][nN][cC][oO][dD][iI][nN][gG]|[eE][rR][rR][oO][rR]_[vV][eE][rR][bB][oO][sS][iI][tT][yY])|[lL][eE][cC][tT])|[hH][oO][sS][tT]|[nN][uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[cC]([oO]([nN]([nN][eE][cC][tT]([iI][oO][nN]_([sS][tT][aA][tT][uU][sS]|[rR][eE][sS][eE][tT]|[bB][uU][sS][yY]))?|[vV][eE][rR][tT])|[pP][yY]_([tT][oO]|[fF][rR][oO][mM]))|[aA][nN][cC][eE][lL]_[qQ][uU][eE][rR][yY]|[lL]([iI][eE][nN][tT]_[eE][nN][cC][oO][dD][iI][nN][gG]|[oO][sS][eE]))|[iI][nN][sS][eE][rR][tT]|[tT]([tT][yY]|[rR][aA]([nN][sS][aA][cC][tT][iI][oO][nN]_[sS][tT][aA][tT][uU][sS]|[cC][eE]))|[oO][pP][tT][iI][oO][nN][sS]|[dD]([eE][lL][eE][tT][eE]|[bB][nN][aA][mM][eE])|[uU]([nN]([tT][rR][aA][cC][eE]|[eE][sS][cC][aA][pP][eE]_[bB][yY][tT][eE][aA])|[pP][dD][aA][tT][eE])|[eE]([sS][cC][aA][pP][eE]_([sS][tT][rR][iI][nN][gG]|[bB][yY][tT][eE][aA])|[nN][dD]_[cC][oO][pP][yY]|[xX][eE][cC][uU][tT][eE])|[pP]([cC][oO][nN][nN][eE][cC][tT]|[iI][nN][gG]|[oO][rR][tT]|[uU][tT]_[lL][iI][nN][eE]|[aA][rR][aA][mM][eE][tT][eE][rR]_[sS][tT][aA][tT][uU][sS]|[rR][eE][pP][aA][rR][eE])|[vV][eE][rR][sS][iI][oO][nN]|[fF]([iI][eE][lL][dD]_([sS][iI][zZ][eE]|[nN]([uU][mM]|[aA][mM][eE])|[iI][sS]_[nN][uU][lL][lL]|[tT]([yY][pP][eE](_[oO][iI][dD])?|[aA][bB][lL][eE])|[pP][rR][tT][lL][eE][nN])|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[aA]([sS][sS][oO][cC]|[lL][lL](_[cC][oO][lL][uU][mM][nN][sS])?|[rR][rR][aA][yY])|[rR]([oO][wW]|[eE][sS][uU][lL][tT]))|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY](_[pP][aA][rR][aA][mM][sS])?|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS]|[lL]([oO]_([sS][eE][eE][kK]|[cC]([lL][oO][sS][eE]|[rR][eE][aA][tT][eE])|[tT][eE][lL][lL]|[iI][mM][pP][oO][rR][tT]|[oO][pP][eE][nN]|[uU][nN][lL][iI][nN][kK]|[eE][xX][pP][oO][rR][tT]|[wW][rR][iI][tT][eE]|[rR][eE][aA][dD](_[aA][lL][lL])?)|[aA][sS][tT]_([nN][oO][tT][iI][cC][eE]|[oO][iI][dD]|[eE][rR][rR][oO][rR]))|[gG][eE][tT]_([nN][oO][tT][iI][fF][yY]|[pP][iI][dD]|[rR][eE][sS][uU][lL][tT])|[rR][eE][sS][uU][lL][tT]_([sS]([tT][aA][tT][uU][sS]|[eE][eE][kK])|[eE][rR][rR][oO][rR](_[fF][iI][eE][lL][dD])?)|[mM][eE][tT][aA]_[dD][aA][tT][aA])(?=\s*\())|([\s\S])/g,/(?:\b([vV][iI][rR][tT][uU][aA][lL]|[aA][pP][aA][cC][hH][eE]_([sS][eE][tT][eE][nN][vV]|[nN][oO][tT][eE]|[cC][hH][iI][lL][dD]_[tT][eE][rR][mM][iI][nN][aA][tT][eE]|[lL][oO][oO][kK][uU][pP]_[uU][rR][iI]|[gG][eE][tT]_([vV][eE][rR][sS][iI][oO][nN]|[mM][oO][dD][uU][lL][eE][sS])|[rR][eE]([sS]([eE][tT]_[tT][iI][mM][eE][oO][uU][tT]|[pP][oO][nN][sS][eE]_[hH][eE][aA][dD][eE][rR][sS])|[qQ][uU][eE][sS][tT]_([sS]([oO][mM][eE]_[aA][uU][tT][hH]_[rR][eE][qQ][uU][iI][rR][eE][dD]|[uU][bB]_[rR][eE][qQ]_([lL][oO][oO][kK][uU][pP]_([uU][rR][iI]|[fF][iI][lL][eE])|[mM][eE][tT][hH][oO][dD]_[uU][rR][iI])|[eE]([tT]_([eE][tT][aA][gG]|[lL][aA][sS][tT]_[mM][oO][dD][iI][fF][iI][eE][dD])|[rR][vV][eE][rR]_[pP][oO][rR][tT])|[aA][tT][iI][sS][fF][iI][eE][sS])|[hH][eE][aA][dD][eE][rR][sS](_([iI][nN]|[oO][uU][tT]))?|[iI][sS]_[iI][nN][iI][tT][iI][aA][lL]_[rR][eE][qQ]|[dD][iI][sS][cC][aA][rR][dD]_[rR][eE][qQ][uU][eE][sS][tT]_[bB][oO][dD][yY]|[uU][pP][dD][aA][tT][eE]_[mM][tT][iI][mM][eE]|[eE][rR][rR]_[hH][eE][aA][dD][eE][rR][sS]_[oO][uU][tT]|[lL][oO][gG]_[eE][rR][rR][oO][rR]|[aA][uU][tT][hH]_([nN][aA][mM][eE]|[tT][yY][pP][eE])|[rR]([uU][nN]|[eE][mM][oO][tT][eE]_[hH][oO][sS][tT])|[mM][eE][eE][tT][sS]_[cC][oO][nN][dD][iI][tT][iI][oO][nN][sS])))|[gG][eE][tT][aA][lL][lL][hH][eE][aA][dD][eE][rR][sS])(?=\s*\())|([\s\S])/g,/(?:\b([sS][tT][rR]([tT][oO][tT][iI][mM][eE]|[fF][tT][iI][mM][eE])|[cC][hH][eE][cC][kK][dD][aA][tT][eE]|[tT][iI][mM][eE]([zZ][oO][nN][eE]_([nN][aA][mM][eE]_([fF][rR][oO][mM]_[aA][bB][bB][rR]|[gG][eE][tT])|[iI][dD][eE][nN][tT][iI][fF][iI][eE][rR][sS]_[lL][iI][sS][tT]|[tT][rR][aA][nN][sS][iI][tT][iI][oO][nN][sS]_[gG][eE][tT]|[oO]([pP][eE][nN]|[fF][fF][sS][eE][tT]_[gG][eE][tT])|[aA][bB][bB][rR][eE][vV][iI][aA][tT][iI][oO][nN][sS]_[lL][iI][sS][tT]))?|[iI][dD][aA][tT][eE]|[dD][aA][tT][eE](_([sS][uU][nN]([sS][eE][tT]|_[iI][nN][fF][oO]|[rR][iI][sS][eE])|[cC][rR][eE][aA][tT][eE]|[iI][sS][oO][dD][aA][tT][eE]_[sS][eE][tT]|[tT][iI][mM][eE]([zZ][oO][nN][eE]_([sS][eE][tT]|[gG][eE][tT])|_[sS][eE][tT])|[dD]([eE][fF][aA][uU][lL][tT]_[tT][iI][mM][eE][zZ][oO][nN][eE]_([sS][eE][tT]|[gG][eE][tT])|[aA][tT][eE]_[sS][eE][tT])|[oO][fF][fF][sS][eE][tT]_[gG][eE][tT]|[pP][aA][rR][sS][eE]|[fF][oO][rR][mM][aA][tT]|[mM][oO][dD][iI][fF][yY]))?|[lL][oO][cC][aA][lL][tT][iI][mM][eE]|[gG]([eE][tT][dD][aA][tT][eE]|[mM]([sS][tT][rR][fF][tT][iI][mM][eE]|[dD][aA][tT][eE]|[mM][kK][tT][iI][mM][eE]))|[mM][kK][tT][iI][mM][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[iI][mM][pP][oO][rR][tT]_[sS][iI][mM][pP][lL][eE][xX][mM][lL](?=\s*\())|([\s\S])/g,/(?:\b[fF][bB][sS][qQ][lL]_([hH][oO][sS][tT][nN][aA][mM][eE]|[sS]([tT]([oO][pP]_[dD][bB]|[aA][rR][tT]_[dD][bB])|[eE]([tT]_([cC][hH][aA][rR][aA][cC][tT][eE][rR][sS][eE][tT]|[tT][rR][aA][nN][sS][aA][cC][tT][iI][oO][nN]|[pP][aA][sS][sS][wW][oO][rR][dD]|[lL][oO][bB]_[mM][oO][dD][eE])|[lL][eE][cC][tT]_[dD][bB]))|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][xX][tT]_[rR][eE][sS][uU][lL][tT])|[cC]([hH][aA][nN][gG][eE]_[uU][sS][eE][rR]|[oO]([nN][nN][eE][cC][tT]|[mM][mM][iI][tT])|[lL][oO]([sS][eE]|[bB]_[sS][iI][zZ][eE])|[rR][eE][aA][tT][eE]_([cC][lL][oO][bB]|[dD][bB]|[bB][lL][oO][bB]))|[tT][aA][bB][lL][eE]_[nN][aA][mM][eE]|[iI][nN][sS][eE][rR][tT]_[iI][dD]|[dD]([aA][tT][aA](_[sS][eE][eE][kK]|[bB][aA][sS][eE](_[pP][aA][sS][sS][wW][oO][rR][dD])?)|[rR][oO][pP]_[dD][bB]|[bB]_([sS][tT][aA][tT][uU][sS]|[qQ][uU][eE][rR][yY]))|[uU][sS][eE][rR][nN][aA][mM][eE]|[eE][rR][rR]([nN][oO]|[oO][rR])|[pP]([cC][oO][nN][nN][eE][cC][tT]|[aA][sS][sS][wW][oO][rR][dD])|[fF]([iI][eE][lL][dD]_([sS][eE][eE][kK]|[nN][aA][mM][eE]|[tT]([yY][pP][eE]|[aA][bB][lL][eE])|[fF][lL][aA][gG][sS]|[lL][eE][nN])|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[lL][eE][nN][gG][tT][hH][sS]|[aA]([sS][sS][oO][cC]|[rR][rR][aA][yY])|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY]|[wW][aA][rR][nN][iI][nN][gG][sS]|[lL][iI][sS][tT]_([tT][aA][bB][lL][eE][sS]|[dD][bB][sS]|[fF][iI][eE][lL][dD][sS])|[aA]([uU][tT][oO][cC][oO][mM][mM][iI][tT]|[fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS])|[gG][eE][tT]_[aA][uU][tT][oO][sS][tT][aA][rR][tT]_[iI][nN][fF][oO]|[rR]([oO]([wW][sS]_[fF][eE][tT][cC][hH][eE][dD]|[lL][lL][bB][aA][cC][kK])|[eE]([sS][uU][lL][tT]|[aA][dD]_([cC][lL][oO][bB]|[bB][lL][oO][bB])))|[bB][lL][oO][bB]_[sS][iI][zZ][eE])(?=\s*\())|([\s\S])/g,/(?:\b[fF][tT][pP]_([sS]([sS][lL]_[cC][oO][nN][nN][eE][cC][tT]|[yY][sS][tT][yY][pP][eE]|[iI]([tT][eE]|[zZ][eE])|[eE][tT]_[oO][pP][tT][iI][oO][nN])|[nN]([lL][iI][sS][tT]|[bB]_([cC][oO][nN][tT][iI][nN][uU][eE]|[pP][uU][tT]|[fF]([pP][uU][tT]|[gG][eE][tT])|[gG][eE][tT]))|[cC]([hH]([dD][iI][rR]|[mM][oO][dD])|[dD][uU][pP]|[oO][nN][nN][eE][cC][tT]|[lL][oO][sS][eE])|[dD][eE][lL][eE][tT][eE]|[eE][xX][eE][cC]|[pP]([uU][tT]|[aA][sS][vV]|[wW][dD])|[fF]([pP][uU][tT]|[gG][eE][tT])|[aA][lL][lL][oO][cC]|[lL][oO][gG][iI][nN]|[gG][eE][tT](_[oO][pP][tT][iI][oO][nN])?|[rR]([eE][nN][aA][mM][eE]|[aA][wW]([lL][iI][sS][tT])?|[mM][dD][iI][rR])|[mM]([dD][tT][mM]|[kK][dD][iI][rR]))(?=\s*\())|([\s\S])/g,/(?:\b([vV][iI][rR][tT][uU][aA][lL]|[aA][pP][aA][cC][hH][eE]_([sS][eE][tT][eE][nN][vV]|[nN][oO][tT][eE]|[gG][eE][tT](_([vV][eE][rR][sS][iI][oO][nN]|[mM][oO][dD][uU][lL][eE][sS])|[eE][nN][vV])|[rR][eE][sS][pP][oO][nN][sS][eE]_[hH][eE][aA][dD][eE][rR][sS])|[gG][eE][tT][aA][lL][lL][hH][eE][aA][dD][eE][rR][sS])(?=\s*\())|([\s\S])/g,/(?:\b[iI][mM][aA][pP]_([hH][eE][aA][dD][eE][rR]([sS]|[iI][nN][fF][oO])|[sS]([cC][aA][nN]|[tT][aA][tT][uU][sS]|[oO][rR][tT]|[uU][bB][sS][cC][rR][iI][bB][eE]|[eE]([tT](_[qQ][uU][oO][tT][aA]|[fF][lL][aA][gG]_[fF][uU][lL][lL]|[aA][cC][lL])|[aA][rR][cC][hH])|[aA][vV][eE][bB][oO][dD][yY])|[cC]([hH][eE][cC][kK]|[lL]([oO][sS][eE]|[eE][aA][rR][fF][lL][aA][gG]_[fF][uU][lL][lL])|[rR][eE][aA][tT][eE][mM][aA][iI][lL][bB][oO][xX])|[nN][uU][mM]_([rR][eE][cC][eE][nN][tT]|[mM][sS][gG])|[tT]([hH][rR][eE][aA][dD]|[iI][mM][eE][oO][uU][tT])|8[bB][iI][tT]|[dD][eE][lL][eE][tT][eE]([mM][aA][iI][lL][bB][oO][xX])?|[oO][pP][eE][nN]|[uU]([nN]([sS][uU][bB][sS][cC][rR][iI][bB][eE]|[dD][eE][lL][eE][tT][eE])|[iI][dD]|[tT][fF](7_([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])|8))|[eE]([rR][rR][oO][rR][sS]|[xX][pP][uU][nN][gG][eE])|[pP][iI][nN][gG]|[qQ][pP][rR][iI][nN][tT]|[fF][eE][tT][cC][hH]([hH][eE][aA][dD][eE][rR]|[sS][tT][rR][uU][cC][tT][uU][rR][eE]|_[oO][vV][eE][rR][vV][iI][eE][wW]|[bB][oO][dD][yY])|[lL]([sS][uU][bB]|[iI][sS][tT]|[aA][sS][tT]_[eE][rR][rR][oO][rR])|[aA]([pP][pP][eE][nN][dD]|[lL][eE][rR][tT][sS])|[gG][eE][tT]([sS][uU][bB][sS][cC][rR][iI][bB][eE][dD]|_[qQ][uU][oO][tT][aA]([rR][oO][oO][tT])?|[aA][cC][lL]|[mM][aA][iI][lL][bB][oO][xX][eE][sS])|[rR]([eE]([nN][aA][mM][eE][mM][aA][iI][lL][bB][oO][xX]|[oO][pP][eE][nN])|[fF][cC]822_([pP][aA][rR][sS][eE]_([hH][eE][aA][dD][eE][rR][sS]|[aA][dD][rR][lL][iI][sS][tT])|[wW][rR][iI][tT][eE]_[aA][dD][dD][rR][eE][sS][sS]))|[mM]([sS][gG][nN][oO]|[iI][mM][eE]_[hH][eE][aA][dD][eE][rR]_[dD][eE][cC][oO][dD][eE]|[aA][iI][lL](_([cC][oO]([pP][yY]|[mM][pP][oO][sS][eE])|[mM][oO][vV][eE])|[bB][oO][xX][mM][sS][gG][iI][nN][fF][oO])?)|[bB]([iI][nN][aA][rR][yY]|[oO][dD][yY]([sS][tT][rR][uU][cC][tT])?|[aA][sS][eE]64))(?=\s*\())|([\s\S])/g,/(?:\b[mM][bB]_([sS][pP][lL][iI][tT]|[eE][rR][eE][gG]([iI](_[rR][eE][pP][lL][aA][cC][eE])?|_([sS][eE][aA][rR][cC][hH](_([sS][eE][tT][pP][oO][sS]|[iI][nN][iI][tT]|[pP][oO][sS]|[gG][eE][tT]([pP][oO][sS]|[rR][eE][gG][sS])|[rR][eE][gG][sS]))?|[rR][eE][pP][lL][aA][cC][eE]|[mM][aA][tT][cC][hH]))?|[rR][eE][gG][eE][xX]_([sS][eE][tT]_[oO][pP][tT][iI][oO][nN][sS]|[eE][nN][cC][oO][dD][iI][nN][gG]))(?=\s*\())|([\s\S])/g,/(?:\b[sS][mM][fF][iI]_([sS][eE][tT]([tT][iI][mM][eE][oO][uU][tT]|[fF][lL][aA][gG][sS]|[rR][eE][pP][lL][yY])|[cC][hH][gG][hH][eE][aA][dD][eE][rR]|[dD][eE][lL][rR][cC][pP][tT]|[aA][dD][dD]([hH][eE][aA][dD][eE][rR]|[rR][cC][pP][tT])|[rR][eE][pP][lL][aA][cC][eE][bB][oO][dD][yY]|[gG][eE][tT][sS][yY][mM][vV][aA][lL])(?=\s*\())|([\s\S])/g,/(?:\b[mM][sS][qQ][lL]_([sS][eE][lL][eE][cC][tT]_[dD][bB]|[nN][uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[cC]([oO][nN][nN][eE][cC][tT]|[lL][oO][sS][eE]|[rR][eE][aA][tT][eE]_[dD][bB])|[dD]([aA][tT][aA]_[sS][eE][eE][kK]|[rR][oO][pP]_[dD][bB]|[bB]_[qQ][uU][eE][rR][yY])|[eE][rR][rR][oO][rR]|[pP][cC][oO][nN][nN][eE][cC][tT]|[fF]([iI][eE][lL][dD]_([sS][eE][eE][kK]|[nN][aA][mM][eE]|[tT]([yY][pP][eE]|[aA][bB][lL][eE])|[fF][lL][aA][gG][sS]|[lL][eE][nN])|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[aA][rR][rR][aA][yY]|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY]|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS]|[lL][iI][sS][tT]_([tT][aA][bB][lL][eE][sS]|[dD][bB][sS]|[fF][iI][eE][lL][dD][sS])|[rR][eE][sS][uU][lL][tT])(?=\s*\())|([\s\S])/g,/(?:\b[mM][sS][sS][qQ][lL]_([sS][eE][lL][eE][cC][tT]_[dD][bB]|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][xX][tT]_[rR][eE][sS][uU][lL][tT])|[cC]([oO][nN][nN][eE][cC][tT]|[lL][oO][sS][eE])|[iI][nN][iI][tT]|[dD][aA][tT][aA]_[sS][eE][eE][kK]|[eE][xX][eE][cC][uU][tT][eE]|[pP][cC][oO][nN][nN][eE][cC][tT]|[qQ][uU][eE][rR][yY]|[fF]([iI][eE][lL][dD]_([sS][eE][eE][kK]|[nN][aA][mM][eE]|[tT][yY][pP][eE]|[lL][eE][nN][gG][tT][hH])|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[aA]([sS][sS][oO][cC]|[rR][rR][aA][yY])|[rR][oO][wW]|[bB][aA][tT][cC][hH])|[rR][eE][eE]_([sS][tT][aA][tT][eE][mM][eE][nN][tT]|[rR][eE][sS][uU][lL][tT]))|[gG]([uU][iI][dD]_[sS][tT][rR][iI][nN][gG]|[eE][tT]_[lL][aA][sS][tT]_[mM][eE][sS][sS][aA][gG][eE])|[rR]([oO][wW][sS]_[aA][fF][fF][eE][cC][tT][eE][dD]|[eE][sS][uU][lL][tT])|[bB][iI][nN][dD]|[mM][iI][nN]_([eE][rR][rR][oO][rR]_[sS][eE][vV][eE][rR][iI][tT][yY]|[mM][eE][sS][sS][aA][gG][eE]_[sS][eE][vV][eE][rR][iI][tT][yY]))(?=\s*\())|([\s\S])/g,/(?:\b[mM][yY][sS][qQ][lL]_([sS]([tT][aA][tT]|[eE]([tT]_[cC][hH][aA][rR][sS][eE][tT]|[lL][eE][cC][tT]_[dD][bB]))|[nN][uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[cC]([oO][nN][nN][eE][cC][tT]|[lL]([iI][eE][nN][tT]_[eE][nN][cC][oO][dD][iI][nN][gG]|[oO][sS][eE])|[rR][eE][aA][tT][eE]_[dD][bB])|[tT][hH][rR][eE][aA][dD]_[iI][dD]|[iI][nN]([sS][eE][rR][tT]_[iI][dD]|[fF][oO])|[dD]([aA][tT][aA]_[sS][eE][eE][kK]|[rR][oO][pP]_[dD][bB]|[bB]_[qQ][uU][eE][rR][yY])|[uU][nN][bB][uU][fF][fF][eE][rR][eE][dD]_[qQ][uU][eE][rR][yY]|[eE]([sS][cC][aA][pP][eE]_[sS][tT][rR][iI][nN][gG]|[rR][rR]([nN][oO]|[oO][rR]))|[pP]([cC][oO][nN][nN][eE][cC][tT]|[iI][nN][gG])|[fF]([iI][eE][lL][dD]_([sS][eE][eE][kK]|[nN][aA][mM][eE]|[tT]([yY][pP][eE]|[aA][bB][lL][eE])|[fF][lL][aA][gG][sS]|[lL][eE][nN])|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[lL][eE][nN][gG][tT][hH][sS]|[aA]([sS][sS][oO][cC]|[rR][rR][aA][yY])|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY]|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS]|[lL][iI][sS][tT]_([tT][aA][bB][lL][eE][sS]|[dD][bB][sS]|[pP][rR][oO][cC][eE][sS][sS][eE][sS]|[fF][iI][eE][lL][dD][sS])|[rR][eE]([sS][uU][lL][tT]|[aA][lL]_[eE][sS][cC][aA][pP][eE]_[sS][tT][rR][iI][nN][gG])|[gG][eE][tT]_([sS][eE][rR][vV][eE][rR]_[iI][nN][fF][oO]|[hH][oO][sS][tT]_[iI][nN][fF][oO]|[cC][lL][iI][eE][nN][tT]_[iI][nN][fF][oO]|[pP][rR][oO][tT][oO]_[iI][nN][fF][oO]))(?=\s*\())|([\s\S])/g,/(?:\b([sS][oO][lL][iI][dD]_[fF][eE][tT][cC][hH]_[pP][rR][eE][vV]|[oO][dD][bB][cC]_([sS]([tT][aA][tT][iI][sS][tT][iI][cC][sS]|[pP][eE][cC][iI][aA][lL][cC][oO][lL][uU][mM][nN][sS]|[eE][tT][oO][pP][tT][iI][oO][nN])|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][xX][tT]_[rR][eE][sS][uU][lL][tT])|[cC]([oO]([nN][nN][eE][cC][tT]|[lL][uU][mM][nN]([sS]|[pP][rR][iI][vV][iI][lL][eE][gG][eE][sS])|[mM][mM][iI][tT])|[uU][rR][sS][oO][rR]|[lL][oO][sS][eE](_[aA][lL][lL])?)|[tT][aA][bB][lL][eE]([sS]|[pP][rR][iI][vV][iI][lL][eE][gG][eE][sS])|[dD][aA][tT][aA]_[sS][oO][uU][rR][cC][eE]|[eE]([rR][rR][oO][rR]([mM][sS][gG])?|[xX][eE][cC]([uU][tT][eE])?)|[pP]([cC][oO][nN][nN][eE][cC][tT]|[rR]([iI][mM][aA][rR][yY][kK][eE][yY][sS]|[oO][cC][eE][dD][uU][rR][eE]([sS]|[cC][oO][lL][uU][mM][nN][sS])|[eE][pP][aA][rR][eE]))|[fF]([iI][eE][lL][dD]_([sS][cC][aA][lL][eE]|[nN]([uU][mM]|[aA][mM][eE])|[tT][yY][pP][eE]|[lL][eE][nN])|[oO][rR][eE][iI][gG][nN][kK][eE][yY][sS]|[eE][tT][cC][hH]_([iI][nN][tT][oO]|[oO][bB][jJ][eE][cC][tT]|[aA][rR][rR][aA][yY]|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[aA][uU][tT][oO][cC][oO][mM][mM][iI][tT]|[lL][oO][nN][gG][rR][eE][aA][dD][lL][eE][nN]|[gG][eE][tT][tT][yY][pP][eE][iI][nN][fF][oO]|[rR]([oO][lL][lL][bB][aA][cC][kK]|[eE][sS][uU][lL][tT](_[aA][lL][lL])?)|[bB][iI][nN][mM][oO][dD][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[pP][rR][eE][gG]_([sS][pP][lL][iI][tT]|[qQ][uU][oO][tT][eE]|[lL][aA][sS][tT]_[eE][rR][rR][oO][rR]|[gG][rR][eE][pP]|[rR][eE][pP][lL][aA][cC][eE](_[cC][aA][lL][lL][bB][aA][cC][kK])?|[mM][aA][tT][cC][hH](_[aA][lL][lL])?)(?=\s*\())|([\s\S])/g,/(?:\b([sS][pP][lL]_([cC][lL][aA][sS][sS][eE][sS]|[oO][bB][jJ][eE][cC][tT]_[hH][aA][sS][hH]|[aA][uU][tT][oO][lL][oO][aA][dD](_([cC][aA][lL][lL]|[uU][nN][rR][eE][gG][iI][sS][tT][eE][rR]|[eE][xX][tT][eE][nN][sS][iI][oO][nN][sS]|[fF][uU][nN][cC][tT][iI][oO][nN][sS]|[rR][eE][gG][iI][sS][tT][eE][rR]))?)|[cC][lL][aA][sS][sS]_([iI][mM][pP][lL][eE][mM][eE][nN][tT][sS]|[pP][aA][rR][eE][nN][tT][sS]))(?=\s*\())|([\s\S])/g,/(?:\b[sS][yY][bB][aA][sS][eE]_([sS][eE]([tT]_[mM][eE][sS][sS][aA][gG][eE]_[hH][aA][nN][dD][lL][eE][rR]|[lL][eE][cC][tT]_[dD][bB])|[nN][uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[cC]([oO][nN][nN][eE][cC][tT]|[lL][oO][sS][eE])|[dD]([eE][aA][dD][lL][oO][cC][kK]_[rR][eE][tT][rR][yY]_[cC][oO][uU][nN][tT]|[aA][tT][aA]_[sS][eE][eE][kK])|[uU][nN][bB][uU][fF][fF][eE][rR][eE][dD]_[qQ][uU][eE][rR][yY]|[pP][cC][oO][nN][nN][eE][cC][tT]|[fF]([iI][eE][lL][dD]_[sS][eE][eE][kK]|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[aA]([sS][sS][oO][cC]|[rR][rR][aA][yY])|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY]|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS]|[rR][eE][sS][uU][lL][tT]|[gG][eE][tT]_[lL][aA][sS][tT]_[mM][eE][sS][sS][aA][gG][eE]|[mM][iI][nN]_([sS][eE][rR][vV][eE][rR]_[sS][eE][vV][eE][rR][iI][tT][yY]|[cC][lL][iI][eE][nN][tT]_[sS][eE][vV][eE][rR][iI][tT][yY]))(?=\s*\())|([\s\S])/g,/(?:\b[sS][yY][bB][aA][sS][eE]_([sS][eE][lL][eE][cC][tT]_[dD][bB]|[nN][uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[cC]([oO][nN][nN][eE][cC][tT]|[lL][oO][sS][eE])|[dD][aA][tT][aA]_[sS][eE][eE][kK]|[pP][cC][oO][nN][nN][eE][cC][tT]|[fF]([iI][eE][lL][dD]_[sS][eE][eE][kK]|[eE][tT][cC][hH]_([oO][bB][jJ][eE][cC][tT]|[fF][iI][eE][lL][dD]|[aA][rR][rR][aA][yY]|[rR][oO][wW])|[rR][eE][eE]_[rR][eE][sS][uU][lL][tT])|[qQ][uU][eE][rR][yY]|[aA][fF][fF][eE][cC][tT][eE][dD]_[rR][oO][wW][sS]|[rR][eE][sS][uU][lL][tT]|[gG][eE][tT]_[lL][aA][sS][tT]_[mM][eE][sS][sS][aA][gG][eE]|[mM][iI][nN]_([eE][rR][rR][oO][rR]_[sS][eE][vV][eE][rR][iI][tT][yY]|[mM][eE][sS][sS][aA][gG][eE]_[sS][eE][vV][eE][rR][iI][tT][yY]))(?=\s*\())|([\s\S])/g,/(?:\b[xX][mM][lL][wW][rR][iI][tT][eE][rR]_([sS]([tT][aA][rR][tT]_([cC]([oO][mM][mM][eE][nN][tT]|[dD][aA][tT][aA])|[dD]([tT][dD](_([eE]([nN][tT][iI][tT][yY]|[lL][eE][mM][eE][nN][tT])|[aA][tT][tT][lL][iI][sS][tT]))?|[oO][cC][uU][mM][eE][nN][tT])|[pP][iI]|[eE][lL][eE][mM][eE][nN][tT](_[nN][sS])?|[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN][sS])?)|[eE][tT]_[iI][nN][dD][eE][nN][tT](_[sS][tT][rR][iI][nN][gG])?)|[tT][eE][xX][tT]|[oO]([uU][tT][pP][uU][tT]_[mM][eE][mM][oO][rR][yY]|[pP][eE][nN]_([uU][rR][iI]|[mM][eE][mM][oO][rR][yY]))|[eE][nN][dD]_([cC]([oO][mM][mM][eE][nN][tT]|[dD][aA][tT][aA])|[dD]([tT][dD](_([eE]([nN][tT][iI][tT][yY]|[lL][eE][mM][eE][nN][tT])|[aA][tT][tT][lL][iI][sS][tT]))?|[oO][cC][uU][mM][eE][nN][tT])|[pP][iI]|[eE][lL][eE][mM][eE][nN][tT]|[aA][tT][tT][rR][iI][bB][uU][tT][eE])|[fF]([uU][lL][lL]_[eE][nN][dD]_[eE][lL][eE][mM][eE][nN][tT]|[lL][uU][sS][hH])|[wW][rR][iI][tT][eE]_([cC]([oO][mM][mM][eE][nN][tT]|[dD][aA][tT][aA])|[dD][tT][dD](_([eE]([nN][tT][iI][tT][yY]|[lL][eE][mM][eE][nN][tT])|[aA][tT][tT][lL][iI][sS][tT]))?|[pP][iI]|[eE][lL][eE][mM][eE][nN][tT](_[nN][sS])?|[aA][tT][tT][rR][iI][bB][uU][tT][eE](_[nN][sS])?|[rR][aA][wW]))(?=\s*\())|([\s\S])/g,/(?:\b([sS]([tT][aA][tT]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[eE][tT]([cC][oO][mM][mM][eE][nN][tT]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[aA][rR][cC][hH][iI][vV][eE][cC][oO][mM][mM][eE][nN][tT]))|[cC]([lL][oO][sS][eE]|[rR][eE][aA][tT][eE][eE][mM][pP][tT][yY][dD][iI][rR])|[dD][eE][lL][eE][tT][eE]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[oO][pP][eE][nN]|[zZ][iI][pP]_([cC][lL][oO][sS][eE]|[oO][pP][eE][nN]|[eE][nN][tT][rR][yY]_([nN][aA][mM][eE]|[cC]([oO][mM][pP][rR][eE][sS][sS]([iI][oO][nN][mM][eE][tT][hH][oO][dD]|[eE][dD][sS][iI][zZ][eE])|[lL][oO][sS][eE])|[oO][pP][eE][nN]|[fF][iI][lL][eE][sS][iI][zZ][eE]|[rR][eE][aA][dD])|[rR][eE][aA][dD])|[uU][nN][cC][hH][aA][nN][gG][eE]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX]|[aA][lL][lL])|[lL][oO][cC][aA][tT][eE][nN][aA][mM][eE]|[aA][dD][dD][fF]([iI][lL][eE]|[rR][oO][mM][sS][tT][rR][iI][nN][gG])|[rR][eE][nN][aA][mM][eE]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[gG][eE][tT]([sS][tT][rR][eE][aA][mM]|[cC][oO][mM][mM][eE][nN][tT]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[nN][aA][mM][eE][iI][nN][dD][eE][xX]|[fF][rR][oO][mM]([nN][aA][mM][eE]|[iI][nN][dD][eE][xX])|[aA][rR][cC][hH][iI][vV][eE][cC][oO][mM][mM][eE][nN][tT]))(?=\s*\())|([\s\S])/g,/(?:\b[pP][oO][sS][iI][xX]_([sS]([tT][rR][eE][rR][rR][oO][rR]|[eE][tT]([sS][iI][dD]|[uU][iI][dD]|[pP][gG][iI][dD]|[eE]([uU][iI][dD]|[gG][iI][dD])|[gG][iI][dD]))|[cC][tT][eE][rR][mM][iI][dD]|[iI]([sS][aA][tT][tT][yY]|[nN][iI][tT][gG][rR][oO][uU][pP][sS])|[tT]([tT][yY][nN][aA][mM][eE]|[iI][mM][eE][sS])|[uU][nN][aA][mM][eE]|[kK][iI][lL][lL]|[aA][cC][cC][eE][sS][sS]|[gG][eE][tT]([sS][iI][dD]|[cC][wW][dD]|_[lL][aA][sS][tT]_[eE][rR][rR][oO][rR]|[uU][iI][dD]|[eE]([uU][iI][dD]|[gG][iI][dD])|[pP]([iI][dD]|[pP][iI][dD]|[wW]([nN][aA][mM]|[uU][iI][dD])|[gG]([iI][dD]|[rR][pP]))|[lL][oO][gG][iI][nN]|[rR][lL][iI][mM][iI][tT]|[gG]([iI][dD]|[rR]([nN][aA][mM]|[oO][uU][pP][sS]|[gG][iI][dD])))|[mM][kK]([nN][oO][dD]|[fF][iI][fF][oO]))(?=\s*\())|([\s\S])/g,/(?:\b[pP][rR][oO][cC]_([cC][lL][oO][sS][eE]|[tT][eE][rR][mM][iI][nN][aA][tT][eE]|[oO][pP][eE][nN]|[gG][eE][tT]_[sS][tT][aA][tT][uU][sS])(?=\s*\())|([\s\S])/g,/(?:\b[pP][sS][pP][eE][lL][lL]_([sS]([tT][oO][rR][eE]_[rR][eE][pP][lL][aA][cC][eE][mM][eE][nN][tT]|[uU][gG][gG][eE][sS][tT]|[aA][vV][eE]_[wW][oO][rR][dD][lL][iI][sS][tT])|[cC]([hH][eE][cC][kK]|[oO][nN][fF][iI][gG]_([sS][aA][vV][eE]_[rR][eE][pP][lL]|[cC][rR][eE][aA][tT][eE]|[iI][gG][nN][oO][rR][eE]|[dD]([iI][cC][tT]_[dD][iI][rR]|[aA][tT][aA]_[dD][iI][rR])|[pP][eE][rR][sS][oO][nN][aA][lL]|[rR]([uU][nN][tT][oO][gG][eE][tT][hH][eE][rR]|[eE][pP][lL])|[mM][oO][dD][eE])|[lL][eE][aA][rR]_[sS][eE][sS][sS][iI][oO][nN])|[nN][eE][wW](_([cC][oO][nN][fF][iI][gG]|[pP][eE][rR][sS][oO][nN][aA][lL]))?|[aA][dD][dD]_[tT][oO]_([sS][eE][sS][sS][iI][oO][nN]|[pP][eE][rR][sS][oO][nN][aA][lL]))(?=\s*\())|([\s\S])/g,/(?:\b[qQ][uU][oO][tT][eE][dD]_[pP][rR][iI][nN][tT][aA][bB][lL][eE]_[dD][eE][cC][oO][dD][eE](?=\s*\())|([\s\S])/g,/(?:\b([sS][rR][aA][nN][dD]|[gG][eE][tT][rR][aA][nN][dD][mM][aA][xX]|[rR][aA][nN][dD]|[mM][tT]_([sS][rR][aA][nN][dD]|[gG][eE][tT][rR][aA][nN][dD][mM][aA][xX]|[rR][aA][nN][dD]))(?=\s*\())|([\s\S])/g,/(?:\b[rR][eE][aA][dD][lL][iI][nN][eE](_([cC]([oO][mM][pP][lL][eE][tT][iI][oO][nN]_[fF][uU][nN][cC][tT][iI][oO][nN]|[aA][lL][lL][bB][aA][cC][kK]_([hH][aA][nN][dD][lL][eE][rR]_([iI][nN][sS][tT][aA][lL][lL]|[rR][eE][mM][oO][vV][eE])|[rR][eE][aA][dD]_[cC][hH][aA][rR])|[lL][eE][aA][rR]_[hH][iI][sS][tT][oO][rR][yY])|[iI][nN][fF][oO]|[oO][nN]_[nN][eE][wW]_[lL][iI][nN][eE]|[wW][rR][iI][tT][eE]_[hH][iI][sS][tT][oO][rR][yY]|[lL][iI][sS][tT]_[hH][iI][sS][tT][oO][rR][yY]|[aA][dD][dD]_[hH][iI][sS][tT][oO][rR][yY]|[rR][eE]([dD][iI][sS][pP][lL][aA][yY]|[aA][dD]_[hH][iI][sS][tT][oO][rR][yY])))?(?=\s*\())|([\s\S])/g,/(?:\b[rR][eE][cC][oO][dD][eE]_([sS][tT][rR][iI][nN][gG]|[fF][iI][lL][eE])(?=\s*\())|([\s\S])/g,/(?:\b([sS]([pP][lL][iI][tT]([iI])?|[qQ][lL]_[rR][eE][gG][cC][aA][sS][eE])|[eE][rR][eE][gG]([iI](_[rR][eE][pP][lL][aA][cC][eE])?|_[rR][eE][pP][lL][aA][cC][eE])?)(?=\s*\())|([\s\S])/g,/(?:\b[sS][eE][sS][sS][iI][oO][nN]_([sS]([tT][aA][rR][tT]|[eE][tT]_([sS][aA][vV][eE]_[hH][aA][nN][dD][lL][eE][rR]|[cC][oO][oO][kK][iI][eE]_[pP][aA][rR][aA][mM][sS])|[aA][vV][eE]_[pP][aA][tT][hH])|[cC][aA][cC][hH][eE]_([eE][xX][pP][iI][rR][eE]|[lL][iI][mM][iI][tT][eE][rR])|[nN][aA][mM][eE]|[iI]([sS]_[rR][eE][gG][iI][sS][tT][eE][rR][eE][dD]|[dD])|[dD][eE]([sS][tT][rR][oO][yY]|[cC][oO][dD][eE])|[uU][nN]([sS][eE][tT]|[rR][eE][gG][iI][sS][tT][eE][rR])|[eE][nN][cC][oO][dD][eE]|[wW][rR][iI][tT][eE]_[cC][lL][oO][sS][eE]|[rR][eE][gG]([iI][sS][tT][eE][rR]|[eE][nN][eE][rR][aA][tT][eE]_[iI][dD])|[gG][eE][tT]_[cC][oO][oO][kK][iI][eE]_[pP][aA][rR][aA][mM][sS]|[mM][oO][dD][uU][lL][eE]_[nN][aA][mM][eE])(?=\s*\())|([\s\S])/g,/(?:\b[sS][hH][mM][oO][pP]_([sS][iI][zZ][eE]|[cC][lL][oO][sS][eE]|[dD][eE][lL][eE][tT][eE]|[oO][pP][eE][nN]|[wW][rR][iI][tT][eE]|[rR][eE][aA][dD])(?=\s*\())|([\s\S])/g,/(?:\b[sS][iI][mM][pP][lL][eE][xX][mM][lL]_([iI][mM][pP][oO][rR][tT]_[dD][oO][mM]|[lL][oO][aA][dD]_([sS][tT][rR][iI][nN][gG]|[fF][iI][lL][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[cC][oO][nN][fF][iI][rR][mM]_[eE][xX][tT][nN][aA][mM][eE]_[cC][oO][mM][pP][iI][lL][eE][dD](?=\s*\())|([\s\S])/g,/(?:\b([sS][nN][mM][pP]([sS][eE][tT]|2_([sS][eE][tT]|[wW][aA][lL][kK]|[rR][eE][aA][lL]_[wW][aA][lL][kK]|[gG][eE][tT]([nN][eE][xX][tT])?)|3_([sS][eE][tT]|[wW][aA][lL][kK]|[rR][eE][aA][lL]_[wW][aA][lL][kK]|[gG][eE][tT]([nN][eE][xX][tT])?)|_([sS][eE][tT]_([oO][iI][dD]_[oO][uU][tT][pP][uU][tT]_[fF][oO][rR][mM][aA][tT]|[eE][nN][uU][mM]_[pP][rR][iI][nN][tT]|[vV][aA][lL][uU][eE][rR][eE][tT][rR][iI][eE][vV][aA][lL]|[qQ][uU][iI][cC][kK]_[pP][rR][iI][nN][tT])|[rR][eE][aA][dD]_[mM][iI][bB]|[gG][eE][tT]_([vV][aA][lL][uU][eE][rR][eE][tT][rR][iI][eE][vV][aA][lL]|[qQ][uU][iI][cC][kK]_[pP][rR][iI][nN][tT]))|[wW][aA][lL][kK]|[rR][eE][aA][lL][wW][aA][lL][kK]|[gG][eE][tT]([nN][eE][xX][tT])?)|[pP][hH][pP]_[sS][nN][mM][pP][vV]3)(?=\s*\())|([\s\S])/g,/(?:\b[sS][oO][cC][kK][eE][tT]_([sS]([hH][uU][tT][dD][oO][wW][nN]|[tT][rR][eE][rR][rR][oO][rR]|[eE]([nN][dD]([tT][oO])?|[tT]_([nN][oO][nN][bB][lL][oO][cC][kK]|[oO][pP][tT][iI][oO][nN]|[bB][lL][oO][cC][kK])|[lL][eE][cC][tT]))|[cC]([oO][nN][nN][eE][cC][tT]|[lL]([oO][sS][eE]|[eE][aA][rR]_[eE][rR][rR][oO][rR])|[rR][eE][aA][tT][eE](_([pP][aA][iI][rR]|[lL][iI][sS][tT][eE][nN]))?)|[wW][rR][iI][tT][eE]|[lL]([iI][sS][tT][eE][nN]|[aA][sS][tT]_[eE][rR][rR][oO][rR])|[aA][cC][cC][eE][pP][tT]|[gG][eE][tT]([sS][oO][cC][kK][nN][aA][mM][eE]|_[oO][pP][tT][iI][oO][nN]|[pP][eE][eE][rR][nN][aA][mM][eE])|[rR][eE]([cC][vV]([fF][rR][oO][mM])?|[aA][dD])|[bB][iI][nN][dD])(?=\s*\())|([\s\S])/g,/(?:\b[sS][oO][uU][nN][dD][eE][xX](?=\s*\())|([\s\S])/g,/(?:\b[iI][tT][eE][rR][aA][tT][oO][rR]_([cC][oO][uU][nN][tT]|[tT][oO]_[aA][rR][rR][aA][yY]|[aA][pP][pP][lL][yY])(?=\s*\())|([\s\S])/g,/(?:\b[sS][qQ][lL][iI][tT][eE]_([hH][aA][sS]_[pP][rR][eE][vV]|[sS]([iI][nN][gG][lL][eE]_[qQ][uU][eE][rR][yY]|[eE][eE][kK])|[nN]([uU][mM]_([fF][iI][eE][lL][dD][sS]|[rR][oO][wW][sS])|[eE][xX][tT])|[cC]([hH][aA][nN][gG][eE][sS]|[oO][lL][uU][mM][nN]|[uU][rR][rR][eE][nN][tT]|[lL][oO][sS][eE]|[rR][eE][aA][tT][eE]_([fF][uU][nN][cC][tT][iI][oO][nN]|[aA][gG][gG][rR][eE][gG][aA][tT][eE]))|[oO][pP][eE][nN]|[uU]([nN][bB][uU][fF][fF][eE][rR][eE][dD]_[qQ][uU][eE][rR][yY]|[dD][fF]_([dD][eE][cC][oO][dD][eE]_[bB][iI][nN][aA][rR][yY]|[eE][nN][cC][oO][dD][eE]_[bB][iI][nN][aA][rR][yY]))|[eE]([sS][cC][aA][pP][eE]_[sS][tT][rR][iI][nN][gG]|[rR][rR][oO][rR]_[sS][tT][rR][iI][nN][gG]|[xX][eE][cC])|[pP]([oO][pP][eE][nN]|[rR][eE][vV])|[kK][eE][yY]|[vV][aA][lL][iI][dD]|[qQ][uU][eE][rR][yY]|[fF]([iI][eE][lL][dD]_[nN][aA][mM][eE]|[eE][tT][cC][hH]_([sS][iI][nN][gG][lL][eE]|[cC][oO][lL][uU][mM][nN]_[tT][yY][pP][eE][sS]|[oO][bB][jJ][eE][cC][tT]|[aA]([lL][lL]|[rR][rR][aA][yY]))|[aA][cC][tT][oO][rR][yY])|[lL]([iI][bB]([eE][nN][cC][oO][dD][iI][nN][gG]|[vV][eE][rR][sS][iI][oO][nN])|[aA][sS][tT]_([iI][nN][sS][eE][rR][tT]_[rR][oO][wW][iI][dD]|[eE][rR][rR][oO][rR]))|[aA][rR][rR][aA][yY]_[qQ][uU][eE][rR][yY]|[rR][eE][wW][iI][nN][dD]|[bB][uU][sS][yY]_[tT][iI][mM][eE][oO][uU][tT])(?=\s*\())|([\s\S])/g,/(?:\b[sS][tT][rR][eE][aA][mM]_([sS]([oO][cC][kK][eE][tT]_([sS]([hH][uU][tT][dD][oO][wW][nN]|[eE]([nN][dD][tT][oO]|[rR][vV][eE][rR]))|[cC][lL][iI][eE][nN][tT]|[eE][nN][aA][bB][lL][eE]_[cC][rR][yY][pP][tT][oO]|[pP][aA][iI][rR]|[aA][cC][cC][eE][pP][tT]|[rR][eE][cC][vV][fF][rR][oO][mM]|[gG][eE][tT]_[nN][aA][mM][eE])|[eE]([tT]_([tT][iI][mM][eE][oO][uU][tT]|[wW][rR][iI][tT][eE]_[bB][uU][fF][fF][eE][rR]|[bB][lL][oO][cC][kK][iI][nN][gG])|[lL][eE][cC][tT]))|[cC][oO]([nN][tT][eE][xX][tT]_([sS][eE][tT]_([oO][pP][tT][iI][oO][nN]|[pP][aA][rR][aA][mM][sS])|[cC][rR][eE][aA][tT][eE]|[gG][eE][tT]_([dD][eE][fF][aA][uU][lL][tT]|[oO][pP][tT][iI][oO][nN][sS]))|[pP][yY]_[tT][oO]_[sS][tT][rR][eE][aA][mM])|[fF][iI][lL][tT][eE][rR]_([pP][rR][eE][pP][eE][nN][dD]|[aA][pP][pP][eE][nN][dD]|[rR][eE][mM][oO][vV][eE])|[gG][eE][tT]_([cC][oO][nN][tT][eE][nN][tT][sS]|[tT][rR][aA][nN][sS][pP][oO][rR][tT][sS]|[lL][iI][nN][eE]|[wW][rR][aA][pP][pP][eE][rR][sS]|[mM][eE][tT][aA]_[dD][aA][tT][aA]))(?=\s*\())|([\s\S])/g,/(?:\b([hH][eE][bB][rR][eE][vV]([cC])?|[sS]([sS][cC][aA][nN][fF]|[iI][mM][iI][lL][aA][rR]_[tT][eE][xX][tT]|[tT][rR]([sS]([tT][rR]|[pP][nN])|[nN][aA][tT][cC]([aA][sS][eE][cC][mM][pP]|[mM][pP])|[cC]([hH][rR]|[sS][pP][nN]|[oO][lL][lL])|[iI]([sS][tT][rR]|[pP]([sS][lL][aA][sS][hH][eE][sS]|[cC][sS][lL][aA][sS][hH][eE][sS]|[oO][sS]|_[tT][aA][gG][sS]))|[tT]([oO]([uU][pP][pP][eE][rR]|[kK]|[lL][oO][wW][eE][rR])|[rR])|_([sS]([hH][uU][fF][fF][lL][eE]|[pP][lL][iI][tT])|[iI][rR][eE][pP][lL][aA][cC][eE]|[pP][aA][dD]|[wW][oO][rR][dD]_[cC][oO][uU][nN][tT]|[rR]([oO][tT]13|[eE][pP]([eE][aA][tT]|[lL][aA][cC][eE])))|[pP]([oO][sS]|[bB][rR][kK])|[rR]([cC][hH][rR]|[iI][pP][oO][sS]|[eE][vV]|[pP][oO][sS]))|[uU][bB][sS][tT][rR](_([cC][oO]([uU][nN][tT]|[mM][pP][aA][rR][eE])|[rR][eE][pP][lL][aA][cC][eE]))?|[eE][tT][lL][oO][cC][aA][lL][eE])|[cC]([hH]([uU][nN][kK]_[sS][pP][lL][iI][tT]|[rR])|[oO][uU][nN][tT]_[cC][hH][aA][rR][sS])|[nN][lL](2[bB][rR]|_[lL][aA][nN][gG][iI][nN][fF][oO])|[iI][mM][pP][lL][oO][dD][eE]|[tT][rR][iI][mM]|[oO][rR][dD]|[dD][iI][rR][nN][aA][mM][eE]|[uU][cC]([fF][iI][rR][sS][tT]|[wW][oO][rR][dD][sS])|[jJ][oO][iI][nN]|[pP][aA]([tT][hH][iI][nN][fF][oO]|[rR][sS][eE]_[sS][tT][rR])|[eE][xX][pP][lL][oO][dD][eE]|[qQ][uU][oO][tT][eE][mM][eE][tT][aA]|[aA][dD][dD]([sS][lL][aA][sS][hH][eE][sS]|[cC][sS][lL][aA][sS][hH][eE][sS])|[wW][oO][rR][dD][wW][rR][aA][pP]|[lL]([tT][rR][iI][mM]|[oO][cC][aA][lL][eE][cC][oO][nN][vV])|[rR][tT][rR][iI][mM]|[mM][oO][nN][eE][yY]_[fF][oO][rR][mM][aA][tT]|[bB]([iI][nN]2[hH][eE][xX]|[aA][sS][eE][nN][aA][mM][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[sS][tT][rR][iI][nN][gG]_[eE][xX][tT][eE][nN][dD]_[fF][iI][nN][dD]_[oO][fF][fF][sS][eE][tT](16|32)(?=\s*\())|([\s\S])/g,/(?:\b([sS][yY][sS][lL][oO][gG]|[cC][lL][oO][sS][eE][lL][oO][gG]|[oO][pP][eE][nN][lL][oO][gG]|[dD][eE][fF][iI][nN][eE]_[sS][yY][sS][lL][oO][gG]_[vV][aA][rR][iI][aA][bB][lL][eE][sS])(?=\s*\())|([\s\S])/g,/(?:\b[mM][sS][gG]_([sS]([tT][aA][tT]_[qQ][uU][eE][uU][eE]|[eE]([nN][dD]|[tT]_[qQ][uU][eE][uU][eE]))|[rR][eE]([cC][eE][iI][vV][eE]|[mM][oO][vV][eE]_[qQ][uU][eE][uU][eE])|[gG][eE][tT]_[qQ][uU][eE][uU][eE])(?=\s*\())|([\s\S])/g,/(?:\b[sS][eE][mM]_([aA][cC][qQ][uU][iI][rR][eE]|[rR][eE]([lL][eE][aA][sS][eE]|[mM][oO][vV][eE])|[gG][eE][tT])(?=\s*\())|([\s\S])/g,/(?:\b[sS][hH][mM]_([dD][eE][tT][aA][cC][hH]|[pP][uU][tT]_[vV][aA][rR]|[aA][tT][tT][aA][cC][hH]|[gG][eE][tT]_[vV][aA][rR]|[rR][eE][mM][oO][vV][eE](_[vV][aA][rR])?)(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[tT][eE][xX][tT]_([sS][pP][lL][iI][tT]_[tT][eE][xX][tT]|[iI][sS]_[wW][hH][iI][tT][eE][sS][pP][aA][cC][eE]_[iI][nN]_[eE][lL][eE][mM][eE][nN][tT]_[cC][oO][nN][tT][eE][nN][tT]|[rR][eE][pP][lL][aA][cC][eE]_[wW][hH][oO][lL][eE]_[tT][eE][xX][tT])(?=\s*\())|([\s\S])/g,/(?:\b[tT][iI][dD][yY]_([cC]([oO][nN][fF][iI][gG]_[cC][oO][uU][nN][tT]|[lL][eE][aA][nN]_[rR][eE][pP][aA][iI][rR])|[iI][sS]_[xX]([hH][tT][mM][lL]|[mM][lL])|[dD][iI][aA][gG][nN][oO][sS][eE]|[eE][rR][rR][oO][rR]_[cC][oO][uU][nN][tT]|[pP][aA][rR][sS][eE]_([sS][tT][rR][iI][nN][gG]|[fF][iI][lL][eE])|[aA][cC][cC][eE][sS][sS]_[cC][oO][uU][nN][tT]|[wW][aA][rR][nN][iI][nN][gG]_[cC][oO][uU][nN][tT]|[rR][eE][pP][aA][iI][rR]_([sS][tT][rR][iI][nN][gG]|[fF][iI][lL][eE])|[gG][eE][tT]([oO][pP][tT]|_([hH]([tT][mM][lL](_[vV][eE][rR])?|[eE][aA][dD])|[sS][tT][aA][tT][uU][sS]|[cC][oO][nN][fF][iI][gG]|[oO]([uU][tT][pP][uU][tT]|[pP][tT]_[dD][oO][cC])|[eE][rR][rR][oO][rR]_[bB][uU][fF][fF][eE][rR]|[rR]([oO][oO][tT]|[eE][lL][eE][aA][sS][eE])|[bB][oO][dD][yY])))(?=\s*\())|([\s\S])/g,/(?:\b[tT][oO][kK][eE][nN]_([nN][aA][mM][eE]|[gG][eE][tT]_[aA][lL][lL])(?=\s*\())|([\s\S])/g,/(?:\b([sS]([tT][rR][vV][aA][lL]|[eE][tT][tT][yY][pP][eE])|[iI]([sS]_([sS]([cC][aA][lL][aA][rR]|[tT][rR][iI][nN][gG])|[cC][aA][lL][lL][aA][bB][lL][eE]|[nN][uU]([lL][lL]|[mM][eE][rR][iI][cC])|[oO][bB][jJ][eE][cC][tT]|[fF][lL][oO][aA][tT]|[aA][rR][rR][aA][yY]|[lL][oO][nN][gG]|[rR][eE][sS][oO][uU][rR][cC][eE]|[bB][oO][oO][lL])|[nN][tT][vV][aA][lL])|[fF][lL][oO][aA][tT][vV][aA][lL]|[gG][eE][tT][tT][yY][pP][eE])(?=\s*\())|([\s\S])/g,/(?:\b[uU][nN][iI][qQ][iI][dD](?=\s*\())|([\s\S])/g,/(?:\b([uU][rR][lL]([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])|[pP][aA][rR][sS][eE]_[uU][rR][lL]|[gG][eE][tT]_[hH][eE][aA][dD][eE][rR][sS]|[rR][aA][wW][uU][rR][lL]([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[sS][tT][rR][eE][aA][mM]_([fF][iI][lL][tT][eE][rR]_[rR][eE][gG][iI][sS][tT][eE][rR]|[gG][eE][tT]_[fF][iI][lL][tT][eE][rR][sS]|[bB][uU][cC][kK][eE][tT]_([nN][eE][wW]|[pP][rR][eE][pP][eE][nN][dD]|[aA][pP][pP][eE][nN][dD]|[mM][aA][kK][eE]_[wW][rR][iI][tT][eE][aA][bB][lL][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[uU][sS][eE][rR][dD][aA][tT][aA][hH][aA][nN][dD][lL][eE][rR]_[hH][aA][nN][dD][lL][eE](?=\s*\())|([\s\S])/g,/(?:\b[sS][tT][rR][eE][aA][mM]_[wW][rR][aA][pP][pP][eE][rR]_([uU][nN][rR][eE][gG][iI][sS][tT][eE][rR]|[rR][eE]([sS][tT][oO][rR][eE]|[gG][iI][sS][tT][eE][rR]))(?=\s*\())|([\s\S])/g,/(?:\b[cC][oO][nN][vV][eE][rR][tT]_[uU][uU]([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])(?=\s*\())|([\s\S])/g,/(?:\b([sS][eE][rR][iI][aA][lL][iI][zZ][eE]|[dD][eE][bB][uU][gG]_[zZ][vV][aA][lL]_[dD][uU][mM][pP]|[uU][nN][sS][eE][rR][iI][aA][lL][iI][zZ][eE]|[vV][aA][rR]_([dD][uU][mM][pP]|[eE][xX][pP][oO][rR][tT])|[mM][eE][mM][oO][rR][yY]_[gG][eE][tT]_([uU][sS][aA][gG][eE]|[pP][eE][aA][kK]_[uU][sS][aA][gG][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[vV][eE][rR][sS][iI][oO][nN]_[cC][oO][mM][pP][aA][rR][eE](?=\s*\())|([\s\S])/g,/(?:\b[wW][dD][dD][xX]_([sS][eE][rR][iI][aA][lL][iI][zZ][eE]_[vV][aA]([lL][uU][eE]|[rR][sS])|[dD][eE][sS][eE][rR][iI][aA][lL][iI][zZ][eE]|[pP][aA][cC][kK][eE][tT]_([sS][tT][aA][rR][tT]|[eE][nN][dD])|[aA][dD][dD]_[vV][aA][rR][sS])(?=\s*\())|([\s\S])/g,/(?:\b([uU][tT][fF]8_([dD][eE][cC][oO][dD][eE]|[eE][nN][cC][oO][dD][eE])|[xX][mM][lL]_([sS][eE][tT]_([sS][tT][aA][rR][tT]_[nN][aA][mM][eE][sS][pP][aA][cC][eE]_[dD][eE][cC][lL]_[hH][aA][nN][dD][lL][eE][rR]|[nN][oO][tT][aA][tT][iI][oO][nN]_[dD][eE][cC][lL]_[hH][aA][nN][dD][lL][eE][rR]|[cC][hH][aA][rR][aA][cC][tT][eE][rR]_[dD][aA][tT][aA]_[hH][aA][nN][dD][lL][eE][rR]|[dD][eE][fF][aA][uU][lL][tT]_[hH][aA][nN][dD][lL][eE][rR]|[oO][bB][jJ][eE][cC][tT]|[uU][nN][pP][aA][rR][sS][eE][dD]_[eE][nN][tT][iI][tT][yY]_[dD][eE][cC][lL]_[hH][aA][nN][dD][lL][eE][rR]|[pP][rR][oO][cC][eE][sS][sS][iI][nN][gG]_[iI][nN][sS][tT][rR][uU][cC][tT][iI][oO][nN]_[hH][aA][nN][dD][lL][eE][rR]|[eE]([nN][dD]_[nN][aA][mM][eE][sS][pP][aA][cC][eE]_[dD][eE][cC][lL]_[hH][aA][nN][dD][lL][eE][rR]|[lL][eE][mM][eE][nN][tT]_[hH][aA][nN][dD][lL][eE][rR]|[xX][tT][eE][rR][nN][aA][lL]_[eE][nN][tT][iI][tT][yY]_[rR][eE][fF]_[hH][aA][nN][dD][lL][eE][rR]))|[eE][rR][rR][oO][rR]_[sS][tT][rR][iI][nN][gG]|[pP][aA][rR][sS][eE](_[iI][nN][tT][oO]_[sS][tT][rR][uU][cC][tT]|[rR]_([sS][eE][tT]_[oO][pP][tT][iI][oO][nN]|[cC][rR][eE][aA][tT][eE](_[nN][sS])?|[fF][rR][eE][eE]|[gG][eE][tT]_[oO][pP][tT][iI][oO][nN]))?|[gG][eE][tT]_([cC][uU][rR][rR][eE][nN][tT]_([cC][oO][lL][uU][mM][nN]_[nN][uU][mM][bB][eE][rR]|[lL][iI][nN][eE]_[nN][uU][mM][bB][eE][rR]|[bB][yY][tT][eE]_[iI][nN][dD][eE][xX])|[eE][rR][rR][oO][rR]_[cC][oO][dD][eE])))(?=\s*\())|([\s\S])/g,/(?:\b[xX][mM][lL][rR][pP][cC]_([sS][eE]([tT]_[tT][yY][pP][eE]|[rR][vV][eE][rR]_([cC]([aA][lL][lL]_[mM][eE][tT][hH][oO][dD]|[rR][eE][aA][tT][eE])|[dD][eE][sS][tT][rR][oO][yY]|[aA][dD][dD]_[iI][nN][tT][rR][oO][sS][pP][eE][cC][tT][iI][oO][nN]_[dD][aA][tT][aA]|[rR][eE][gG][iI][sS][tT][eE][rR]_([iI][nN][tT][rR][oO][sS][pP][eE][cC][tT][iI][oO][nN]_[cC][aA][lL][lL][bB][aA][cC][kK]|[mM][eE][tT][hH][oO][dD])))|[iI][sS]_[fF][aA][uU][lL][tT]|[dD][eE][cC][oO][dD][eE](_[rR][eE][qQ][uU][eE][sS][tT])?|[pP][aA][rR][sS][eE]_[mM][eE][tT][hH][oO][dD]_[dD][eE][sS][cC][rR][iI][pP][tT][iI][oO][nN][sS]|[eE][nN][cC][oO][dD][eE](_[rR][eE][qQ][uU][eE][sS][tT])?|[gG][eE][tT]_[tT][yY][pP][eE])(?=\s*\())|([\s\S])/g,/(?:\b[dD][oO][mM]_[xX][pP][aA][tT][hH]_([eE][vV][aA][lL][uU][aA][tT][eE]|[qQ][uU][eE][rR][yY]|[rR][eE][gG][iI][sS][tT][eE][rR]_[nN][sS])(?=\s*\())|([\s\S])/g,/(?:\b[xX][sS][lL]_[xX][sS][lL][tT][pP][rR][oO][cC][eE][sS][sS][oO][rR]_([hH][aA][sS]_[eE][xX][sS][lL][tT]_[sS][uU][pP][pP][oO][rR][tT]|[sS][eE][tT]_[pP][aA][rR][aA][mM][eE][tT][eE][rR]|[tT][rR][aA][nN][sS][fF][oO][rR][mM]_[tT][oO]_([dD][oO][cC]|[uU][rR][iI]|[xX][mM][lL])|[iI][mM][pP][oO][rR][tT]_[sS][tT][yY][lL][eE][sS][hH][eE][eE][tT]|[rR][eE]([gG][iI][sS][tT][eE][rR]_[pP][hH][pP]_[fF][uU][nN][cC][tT][iI][oO][nN][sS]|[mM][oO][vV][eE]_[pP][aA][rR][aA][mM][eE][tT][eE][rR])|[gG][eE][tT]_[pP][aA][rR][aA][mM][eE][tT][eE][rR])(?=\s*\())|([\s\S])/g,/(?:\b([oO][bB]_[gG][zZ][hH][aA][nN][dD][lL][eE][rR]|[zZ][lL][iI][bB]_[gG][eE][tT]_[cC][oO][dD][iI][nN][gG]_[tT][yY][pP][eE]|[rR][eE][aA][dD][gG][zZ][fF][iI][lL][eE]|[gG][zZ]([cC][oO][mM][pP][rR][eE][sS][sS]|[iI][nN][fF][lL][aA][tT][eE]|[dD][eE][fF][lL][aA][tT][eE]|[oO][pP][eE][nN]|[uU][nN][cC][oO][mM][pP][rR][eE][sS][sS]|[eE][nN][cC][oO][dD][eE]|[fF][iI][lL][eE]))(?=\s*\())|([\s\S])/g,/(?:\b[iI][sS]_[iI][nN][tT]([eE][gG][eE][rR])?(?=\s*\())|([\s\S])/g,/(?:\b([rR][eE]([cC][uU][rR][sS][iI][vV][eE]([rR][eE][gG][eE][xX][iI][tT][eE][rR][aA][tT][oO][rR]|[cC][aA][cC][hH][iI][nN][gG][iI][tT][eE][rR][aA][tT][oO][rR]|[iI][tT][eE][rR][aA][tT][oO][rR][iI][tT][eE][rR][aA][tT][oO][rR]|[dD][iI][rR][eE][cC][tT][oO][rR][yY][iI][tT][eE][rR][aA][tT][oO][rR]|[fF][iI][lL][tT][eE][rR][iI][tT][eE][rR][aA][tT][oO][rR]|[aA][rR][rR][aA][yY][iI][tT][eE][rR][aA][tT][oO][rR])|[fF][lL][eE][cC][tT][iI][oO][nN]([mM][eE][tT][hH][oO][dD]|[cC][lL][aA][sS][sS]|[oO][bB][jJ][eE][cC][tT]|[eE][xX][tT][eE][nN][sS][iI][oO][nN]|[pP]([aA][rR][aA][mM][eE][tT][eE][rR]|[rR][oO][pP][eE][rR][tT][yY])|[fF][uU][nN][cC][tT][iI][oO][nN])?|[gG][eE][xX][iI][tT][eE][rR][aA][tT][oO][rR])|[sS]([tT][dD][cC][lL][aA][sS][sS]|[wW][fF]([sS]([hH][aA][pP][eE]|[oO][uU][nN][dD]|[pP][rR][iI][tT][eE])|[tT][eE][xX][tT]([fF][iI][eE][lL][dD])?|[dD][iI][sS][pP][lL][aA][yY][iI][tT][eE][mM]|[fF]([iI][lL][lL]|[oO][nN][tT]([cC][hH][aA]([rR])?)?)|[aA][cC][tT][iI][oO][nN]|[gG][rR][aA][dD][iI][eE][nN][tT]|[mM][oO]([vV][iI][eE]|[rR][pP][hH])|[bB]([iI][tT][mM][aA][pP]|[uU][tT][tT][oO][nN])))|[xX][mM][lL][rR][eE][aA][dD][eE][rR]|[tT][iI][dD][yY][nN][oO][dD][eE]|[sS]([iI][mM][pP][lL][eE][xX][mM][lL]([iI][tT][eE][rR][aA][tT][oO][rR]|[eE][lL][eE][mM][eE][nN][tT])|[oO][aA][pP]([sS][eE][rR][vV][eE][rR]|[hH][eE][aA][dD][eE][rR]|[cC][lL][iI][eE][nN][tT]|[pP][aA][rR][aA][mM]|[vV][aA][rR]|[fF][aA][uU][lL][tT])|[pP][lL]([tT][eE][mM][pP][fF][iI][lL][eE][oO][bB][jJ][eE][cC][tT]|[oO][bB][jJ][eE][cC][tT][sS][tT][oO][rR][aA][gG][eE]|[fF][iI][lL][eE]([iI][nN][fF][oO]|[oO][bB][jJ][eE][cC][tT])))|[nN][oO][rR][eE][wW][iI][nN][dD][iI][tT][eE][rR][aA][tT][oO][rR]|[cC]([oO][mM][pP][eE][rR][sS][iI][sS][tT][hH][eE][lL][pP][eE][rR]|[aA][cC][hH][iI][nN][gG][iI][tT][eE][rR][aA][tT][oO][rR])|[iI]([nN][fF][iI][nN][iI][tT][eE][iI][tT][eE][rR][aA][tT][oO][rR]|[tT][eE][rR][aA][tT][oO][rR][iI][tT][eE][rR][aA][tT][oO][rR])|[dD]([iI][rR][eE][cC][tT][oO][rR][yY][iI][tT][eE][rR][aA][tT][oO][rR]|[oO][mM]([xX][pP][aA][tT][hH]|[nN][oO][dD][eE]|[cC]([oO][mM][mM][eE][nN][tT]|[dD][aA][tT][aA][sS][eE][cC][tT][iI][oO][nN])|[tT][eE][xX][tT]|[dD][oO][cC][uU][mM][eE][nN][tT]([fF][rR][aA][gG][mM][eE][nN][tT])?|[pP][rR][oO][cC][eE][sS][sS][iI][nN][gG][iI][nN][sS][tT][rR][uU][cC][tT][iI][oO][nN]|[eE]([nN][tT][iI][tT][yY][rR][eE][fF][eE][rR][eE][nN][cC][eE]|[lL][eE][mM][eE][nN][tT])|[aA][tT][tT][rR]))|[pP]([dD][oO]([sS][tT][aA][tT][eE][mM][eE][nN][tT])?|[aA][rR][eE][nN][tT][iI][tT][eE][rR][aA][tT][oO][rR])|[eE]([rR][rR][oO][rR][eE][xX][cC][eE][pP][tT][iI][oO][nN]|[mM][pP][tT][yY][iI][tT][eE][rR][aA][tT][oO][rR]|[xX][cC][eE][pP][tT][iI][oO][nN])|[fF][iI][lL][tT][eE][rR][iI][tT][eE][rR][aA][tT][oO][rR]|[lL][iI][mM][iI][tT][iI][tT][eE][rR][aA][tT][oO][rR]|[aA]([pP]([pP][eE][nN][dD][iI][tT][eE][rR][aA][tT][oO][rR]|[aA][cC][hH][eE][rR][eE][qQ][uU][eE][sS][tT])|[rR][rR][aA][yY]([iI][tT][eE][rR][aA][tT][oO][rR]|[oO][bB][jJ][eE][cC][tT])))(?=\s*\())|([\s\S])/g,/(?:\b(([pP][rR][iI][nN][tT]|[eE][cC][hH][oO])\b|([iI][sS][sS][eE][tT]|[uU][nN][sS][eE][tT]|[eE]([vV][aA][lL]|[mM][pP][tT][yY])|[lL][iI][sS][tT])(?=\s*\()))|([\s\S])/g,/((\/[eimnosux]*))|([\s\S])/g,/(<\/)((?:[sS][cC][rR][iI][pP][tT]))|([\s\S])/g,/(\/\/)(.*?((?=<\/script)|(?=\n)\n?))|([\s\S])/g,/(\{(literal)(\}))|([\s\S])/g,/((\\.)|.)(\-((\\.)|[^\]]))|([\s\S])/g,/^(HTML)((;?)((?=\n)\n?))|([\s\S])/g,/\\(a|b|e|f|n|r|t|v|\\|')|([\s\S])/g,/\\[0-9]{3}|([\s\S])/g,/\\x[0-9a-fA-F]{2}|([\s\S])/g,/\\c.|([\s\S])/g,/:|\s|=|/g,/~|([\s\S])/g,/\*|\?|([\s\S])/g,/([\?\*\+@!])(\()|([\s\S])/g,/(\\x[0-9A-F]{2})|(\\[0-7]{3})|(\\\n)|(\\\\)|(\\")|(\\')|(\\a)|(\\b)|(\\f)|(\\n)|(\\r)|(\\t)|(\\v)|([\s\S])/g,/\}|(?=;|\))|([\s\S])/g,/\b(try|catch|finally|throw)\b|([\s\S])/g,/\?|:|([\s\S])/g,/\b(return|break|case|continue|default|do|while|for|switch|if|else)\b|([\s\S])/g,/\b(instanceof)\b|([\s\S])/g,/(==|!=|<=|>=|<>|<|>)|([\s\S])/g,/(=)|([\s\S])/g,/(!|&&|\|\|)|([\s\S])/g,/\S|/g,/\.(?=\S)|([\s\S])/g,/\\[bBAZzG]|\^|\$|([\s\S])/g,/\\[1-9][0-9]?|([\s\S])/g,/[\?\+\*][\?\+]?|\{(\d+,\d+|\d+,|,\d+|\d+)\}\??|([\s\S])/g,/\(\?#|([\s\S])/g,/#\s[a-zA-Z0-9,\. \t\?!-:\u0080-\uffff]*(?=\n)|([\s\S])/g,/\(\?[iLmsux]+\)|([\s\S])/g,/(\()(\?P=([a-zA-Z_][a-zA-Z_0-9]*\w*))(\))|([\s\S])/g,/(\()((\?=)|(\?!)|(\?<=)|(\?<!))|([\s\S])/g,/(\()(\?\(([1-9][0-9]?|[a-zA-Z_][a-zA-Z_0-9]*)(\)))|([\s\S])/g,/(\()(((\?P<)(([a-z]\w*)(>))|(\?:))?)|([\s\S])/g,/\$?"|([\s\S])/g,/\$'|([\s\S])/g,/\s*HTML(?=\n)|([\s\S])/g,/(?=;|\})|([\s\S])/g,/'\s*(?=(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)\b)|([\s\S])/g,/(\{\/(literal)(\}))|([\s\S])/g,/\\[wWsSdDhH]|\.|([\s\S])/g,/(\[)((\^)?)|([\s\S])/g,/|(?=(;|,|\(|\)|>|\[|\]|=))|([\s\S])/g,/(?=(;|,|\(|\)|>|\[|\]|=))|([\s\S])/g,/(?=<?xml|<(?:[hH][tT][mM][lL]\b)|!DOCTYPE (?:[hH][tT][mM][lL]\b))|([\s\S])/g,/^(TEXTILE)((?=\n))|([\s\S])/g,/\*\/.*\n|([\s\S])/g,/\/\/|([\s\S])/g,/\b(break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while)\b|([\s\S])/g,/\b(asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void)\b|([\s\S])/g,/\b(const|extern|register|restrict|static|volatile|inline)\b|([\s\S])/g,/\bk[A-Z]\w*\b|([\s\S])/g,/\bg[A-Z]\w*\b|([\s\S])/g,/\bs[A-Z]\w*\b|([\s\S])/g,/\b(NULL|true|false|TRUE|FALSE)\b|([\s\S])/g,/\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|\-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\b|([\s\S])/g,/^\s*#\s*(define)(\s+(([a-zA-Z_][a-zA-Z0-9_]*))((?:(\()((\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*((,)(\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*))*((?:\.\.\.)?))(\))))?))|([\s\S])/g,/^\s*#\s*(error|warning)(\b)|([\s\S])/g,/^\s*#\s*(include|import)(\b\s+)|([\s\S])/g,/^\s*#\s*(define|defined|elif|else|if|ifdef|ifndef|line|pragma|undef)(\b)|([\s\S])/g,/\b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t)\b|([\s\S])/g,/\b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\b|([\s\S])/g,/\b(int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t)\b|([\s\S])/g,/\b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\b|([\s\S])/g,/\b(AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam|ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr|Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber|ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64|SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32|UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr|UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char)\b|([\s\S])/g,/new|/g,/else|/g,/\w|/g,/&&|/g,/[\*&>]|/g,/(?:^|(?:(?=\s)|(?=\s*[A-Za-z_])))(\s*)((?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()((?=((?:[A-Za-z_](?=([A-Za-z0-9_]*))\6|::)+))\5|(?:(?:operator)(?:[\-\*&<>=\+!]+|\(\)|\[\])))(\s*(?=\()))|([\s\S])/g,/(?:^|(?:(?=\s)))(\s*)((?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()((?=((?:[A-Za-z_](?=([A-Za-z0-9_]*))\6|::)+))\5|(?:(?:operator)(?:[\-\*&<>=\+!]+|\(\)|\[\])))(\s*(?=\()))|([\s\S])/g,/(?:^|(?:(?=\s*[A-Za-z_])))(\s*)((?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()((?=((?:[A-Za-z_](?=([A-Za-z0-9_]*))\6|::)+))\5|(?:(?:operator)(?:[\-\*&<>=\+!]+|\(\)|\[\])))(\s*(?=\()))|([\s\S])/g,/(?:^)(\s*)((?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()((?=((?:[A-Za-z_](?=([A-Za-z0-9_]*))\6|::)+))\5|(?:(?:operator)(?:[\-\*&<>=\+!]+|\(\)|\[\])))(\s*(?=\()))|([\s\S])/g,/[\-a-z]|/g,/(?=[\-a-z])|([\s\S])/g,/(:)(\s*)|([\s\S])/g,/^\t*(RUBY)((?=\n))|([\s\S])/g,/^(\3)((?=\n))|([\s\S])/g,/(\?)(>)|([\s\S])/g,/^\t*(PYTHON)((?=\n))|([\s\S])/g,/(?=[^\]\s])|([\s\S])/g,/\b(id)(\b\s*(=))|([\s\S])/g,/(\|)|([\s\S])/g,/[_a-zA-Z][_a-zA-Z0-9]*|([\s\S])/g,/(?=\S)|([\s\S])/g,/^\t*(APPLESCRIPT)((?=\n))|([\s\S])/g,/(\s*)(\b(hypot(f|l)?|s(scanf|ystem|nprintf|ca(nf|lb(n(f|l)?|ln(f|l)?))|i(n(h(f|l)?|f|l)?|gn(al|bit))|tr(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(jmp|vbuf|locale|buf)|qrt(f|l)?|w(scanf|printf)|rand)|n(e(arbyint(f|l)?|xt(toward(f|l)?|after(f|l)?))|an(f|l)?)|c(s(in(h(f|l)?|f|l)?|qrt(f|l)?)|cos(h(f)?|f|l)?|imag(f|l)?|t(ime|an(h(f|l)?|f|l)?)|o(s(h(f|l)?|f|l)?|nj(f|l)?|pysign(f|l)?)|p(ow(f|l)?|roj(f|l)?)|e(il(f|l)?|xp(f|l)?)|l(o(ck|g(f|l)?)|earerr)|a(sin(h(f|l)?|f|l)?|cos(h(f|l)?|f|l)?|tan(h(f|l)?|f|l)?|lloc|rg(f|l)?|bs(f|l)?)|real(f|l)?|brt(f|l)?)|t(ime|o(upper|lower)|an(h(f|l)?|f|l)?|runc(f|l)?|gamma(f|l)?|mp(nam|file))|i(s(space|n(ormal|an)|cntrl|inf|digit|u(nordered|pper)|p(unct|rint)|finite|w(space|c(ntrl|type)|digit|upper|p(unct|rint)|lower|al(num|pha)|graph|xdigit|blank)|l(ower|ess(equal|greater)?)|al(num|pha)|gr(eater(equal)?|aph)|xdigit|blank)|logb(f|l)?|max(div|abs))|di(v|fftime)|_Exit|unget(c|wc)|p(ow(f|l)?|ut(s|c(har)?|wc(har)?)|error|rintf)|e(rf(c(f|l)?|f|l)?|x(it|p(2(f|l)?|f|l|m1(f|l)?)?))|v(s(scanf|nprintf|canf|printf|w(scanf|printf))|printf|f(scanf|printf|w(scanf|printf))|w(scanf|printf)|a_(start|copy|end|arg))|qsort|f(s(canf|e(tpos|ek))|close|tell|open|dim(f|l)?|p(classify|ut(s|c|w(s|c))|rintf)|e(holdexcept|set(e(nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(aiseexcept|ror)|get(e(nv|xceptflag)|round))|flush|w(scanf|ide|printf|rite)|loor(f|l)?|abs(f|l)?|get(s|c|pos|w(s|c))|re(open|e|ad|xp(f|l)?)|m(in(f|l)?|od(f|l)?|a(f|l|x(f|l)?)?))|l(d(iv|exp(f|l)?)|o(ngjmp|cal(time|econv)|g(1(p(f|l)?|0(f|l)?)|2(f|l)?|f|l|b(f|l)?)?)|abs|l(div|abs|r(int(f|l)?|ound(f|l)?))|r(int(f|l)?|ound(f|l)?)|gamma(f|l)?)|w(scanf|c(s(s(tr|pn)|nc(py|at|mp)|c(spn|hr|oll|py|at|mp)|to(imax|d|u(l(l)?|max)|k|f|l(d|l)?|mbs)|pbrk|ftime|len|r(chr|tombs)|xfrm)|to(b|mb)|rtomb)|printf|mem(set|c(hr|py|mp)|move))|a(s(sert|ctime|in(h(f|l)?|f|l)?)|cos(h(f|l)?|f|l)?|t(o(i|f|l(l)?)|exit|an(h(f|l)?|2(f|l)?|f|l)?)|b(s|ort))|g(et(s|c(har)?|env|wc(har)?)|mtime)|r(int(f|l)?|ound(f|l)?|e(name|alloc|wind|m(ove|quo(f|l)?|ainder(f|l)?))|a(nd|ise))|b(search|towc)|m(odf(f|l)?|em(set|c(hr|py|mp)|move)|ktime|alloc|b(s(init|towcs|rtowcs)|towc|len|r(towc|len))))(\b))|([\s\S])/g,/(?:(?=\s)(?:|)(\s+))?((\b(?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()(?=((?:(?!NS)[A-Za-z_](?=([A-Za-z0-9_]*))\6\b|::)+))\5)(\s*(\()))|([\s\S])/g,/(?:(?=\s)(?:)(\s+))?((\b(?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()(?=((?:(?!NS)[A-Za-z_](?=([A-Za-z0-9_]*))\6\b|::)+))\5)(\s*(\()))|([\s\S])/g,/((\b(?!(while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\s*\()(?=((?:(?!NS)[A-Za-z_](?=([A-Za-z0-9_]*))\6\b|::)+))\5)(\s*(\()))|([\s\S])/g,/(?:(?:(?=\s)\s+))((?=((?:[A-Za-z_](?=([A-Za-z0-9_]*))\3|::)+))\2|(?:(?:operator)(?:[\-\*&<>=\+!]+|\(\)|\[\]))?)(\s*(\())|([\s\S])/g,/\/\*\*\/|([\s\S])/g,/^(\3)((;?)((?=\n)))|([\s\S])/g,/^\s*(#\s*(if(n?def)?)(\b.*?(?:(?=(?:\/\/|\/\*))|(?=\n))))|([\s\S])/g,/\b(?:[a-z]\w*(\.))*([A-Z]+\w*)|([\s\S])/g,/(?=:)|([\s\S])/g,/\b([a-zA-Z_][a-zA-Z_0-9]*)(\s*(?:(,)|(?=[\n\):])))|([\s\S])/g,/(#)(.*(?=\n)\n?)|([\s\S])/g,/\b(?:(0[xX][0-9a-fA-F]*)[lL])|([\s\S])/g,/\b(?:(0[xX][0-9a-fA-F]*))|([\s\S])/g,/\b(?:(0[0-7]+)[lL])|([\s\S])/g,/\b(0[0-7]+)|([\s\S])/g,/[^a-zA-Z0-9_]|/g,/\b(?:(((\d+(\.(?=[^a-zA-Z_])\d*)?|\.\d+)([eE][\-\+]?\d+)?))[jJ])|([\s\S])/g,/\b(?:(((\d+(\.(?=[^a-zA-Z_])\d*)?)([eE][\-\+]?\d+)?))[jJ])|([\s\S])/g,/\b(?:(\d+\.\d*([eE][\-\+]?\d+)?))(?=[^a-zA-Z_])|([\s\S])/g,/[^0-9a-zA-Z_]|/g,/(?:(\.\d+([eE][\-\+]?\d+)?))|([\s\S])/g,/\b(?:(\d+[eE][\-\+]?\d+))|([\s\S])/g,/\b(?:([1-9]+[0-9]*|0)[lL])|([\s\S])/g,/\b([1-9]+[0-9]*|0)|([\s\S])/g,/\b(global)(\b)|([\s\S])/g,/\b(?:(import)|(from))(\b)|([\s\S])/g,/\b(elif|else|except|finally|for|if|try|while|with)\b|([\s\S])/g,/\b(break|continue|pass|raise|return|yield)\b|([\s\S])/g,/\b(and|in|is|not|or)\b|([\s\S])/g,/\b(as|assert|del|exec|print)(\b)|([\s\S])/g,/<=|>=|==|<|>|<>|([\s\S])/g,/\+=|\-=|\*=|\/=|\/\/=|%=|&=|\|=|\^=|>>=|<<=|\*\*=|([\s\S])/g,/\+|\-|\*|\*\*|\/|\/\/|%|<<|>>|&|\||\^|~|([\s\S])/g,/^\s*(class)(\s+(?=[a-zA-Z_][a-zA-Z_0-9]*\s*:))|([\s\S])/g,/^\s*(class)(\s+(?=[a-zA-Z_][a-zA-Z_0-9]*\s*\())|([\s\S])/g,/^\s*(class)(\s+(?=[a-zA-Z_][a-zA-Z_0-9]))|([\s\S])/g,/^\s*(def)(\s+(?=[A-Za-z_][A-Za-z0-9_]*\s*\())|([\s\S])/g,/^\s*(def)(\s+(?=[A-Za-z_][A-Za-z0-9_]*))|([\s\S])/g,/(lambda)((?=\s+))|([\s\S])/g,/^\s*(?=@\s*[A-Za-z_][A-Za-z0-9_]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*\s*\()|([\s\S])/g,/^\s*(?=@\s*[A-Za-z_][A-Za-z0-9_]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*)|([\s\S])/g,/\s*(\()|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*\s*\()|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*\s*\[)|([\s\S])/g,/\s*(\[)|([\s\S])/g,/\b(def|lambda)(\b)|([\s\S])/g,/\b(class)(\b)|([\s\S])/g,/\b(None|True|False|Ellipsis|NotImplemented)\b|([\s\S])/g,/(\[)((\s*(\]))(\b))|([\s\S])/g,/(\()(\s*(\)))|([\s\S])/g,/(\{)(\s*(\}))|([\s\S])/g,/page|include|taglib|([\s\S])/g,/\b(artwork|application|encoder|EQ preset|item|source|visual|(EQ |browser )?window|((audio CD|device|shared|URL|file) )?track|playlist window|((audio CD|device|radio tuner|library|folder|user) )?playlist)s?\b|([\s\S])/g,/\b(add|back track|convert|fast forward|(next|previous) track|pause|play(pause)?|refresh|resume|rewind|search|stop|update|eject|subscribe|update(Podcast|AllPodcasts)|download)\b|([\s\S])/g,/\b(current (playlist|stream (title|URL)|track)|player state)\b|([\s\S])/g,/\b(current (encoder|EQ preset|visual)|EQ enabled|fixed indexing|full screen|mute|player position|sound volume|visuals enabled|visual size)\b|([\s\S])/g,/\s*(?:(?=\})|(:))|([\s\S])/g,/\]\]>|([\s\S])/g,/[><]\(|([\s\S])/g,/&>|\d*>&\d*|\d*(>>|>|<)|\d*<&|\d*<>|([\s\S])/g,/(?=\w?[^=;]*(?:class|(?:@)?interface|enum)\s+\w+)|([\s\S])/g,/^(SQL)((;?)((?=\n)\n?))|([\s\S])/g,/^\s*#\s*if(n?def)?\b.*(?=\n)|([\s\S])/g,/|(?=\w)|([\s\S])/g,/(?=\w)|([\s\S])/g,/\s*((\/\/)(.*(?=\n)\n?))|([\s\S])/g,/\b(time)\b|([\s\S])/g,/[\|!]|([\s\S])/g,/\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|\-)?[0-9]+)?)\b|([\s\S])/g,/(\/)([imsxeADSUXu]*)(")|([\s\S])/g,/\\\}|\\\\|([\s\S])/g,/\b(?:void|boolean|byte|char|short|int|float|long|double)\b|([\s\S])/g,/\b(assert)(\s)|([\s\S])/g,/\s*\1(?=\n)|([\s\S])/g,/(?:^\s*)<\?python(?!.*\?>)|([\s\S])/g,/(\[{2})|([\s\S])/g,/(\({2})|([\s\S])/g,/(\{)((?=\s|(?=\n)))|([\s\S])/g,/[A-Za-z_][A-Za-z_0-9]*(?=\s*\()|([\s\S])/g,/(?!new)(?=\w)(?![^\{]*;)(?!.*\/\/)(?!.*=)(?=.*\()|([\s\S])/g,/'\/(?=(?=((\\.|[^'\/])+))\1\/[imsxeADSUXu]*')|([\s\S])/g,/\b([a-zA-Z\-:]+)|([\s\S])/g,/!|:[\-=\?]?|\*|@|#{1,2}|%{1,2}|\/|([\s\S])/g,/(\[)(([^\]]+)(\]))|([\s\S])/g,/(?=[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\()|([\s\S])/g,/(?=\{|;)|([\s\S])/g,/\b((alert|dialog) reply)\b|([\s\S])/g,/\b(file information)\b|([\s\S])/g,/\b(POSIX files?|system information|volume settings)\b|([\s\S])/g,/\b(URLs?|internet address(es)?|web pages?|FTP items?)\b|([\s\S])/g,/\b(info for|list (disks|folder)|mount volume|path to( resource)?)\b|([\s\S])/g,/\b(beep|choose (application|color|file( name)?|folder|from list|remote application|URL)|delay|display (alert|dialog)|say)\b|([\s\S])/g,/\b(ASCII (character|number)|localized string|offset|summarize)\b|([\s\S])/g,/\b(set the clipboard to|the clipboard|clipboard info)\b|([\s\S])/g,/\b(open for access|close access|read|write|get eof|set eof)\b|([\s\S])/g,/\b((load|store|run) script|scripting components)\b|([\s\S])/g,/\b(current date|do shell script|get volume settings|random number|round|set volume|system attribute|system info|time to GMT)\b|([\s\S])/g,/\b(opening folder|(closing|moving) folder window for|adding folder items to|removing folder items from)\b|([\s\S])/g,/\b(open location|handle CGI request)\b|([\s\S])/g,/\s*(?:(,)|(?=\]))|([\s\S])/g,/\b(and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield)\b|([\s\S])/g,/(?=\])|([\s\S])/g,/(\b0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*)(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\b)|([\s\S])/g,/\b([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%|([\s\S])/g,/[^'"\) \t]+|([\s\S])/g,/\\[`\\\$]|([\s\S])/g,/(>(<))(\/(?:([\-_a-zA-Z0-9]+)((:)))?(([\-_a-zA-Z0-9:]+)(>)))|([\s\S])/g,/(?=<\/(?:[sS][tT][yY][lL][eE]))|([\s\S])/g,/'|/g,/(')((('))((?!')))|([\s\S])/g,/([uU]r)(''')|([\s\S])/g,/([uU]R)(''')|([\s\S])/g,/(r)(''')|([\s\S])/g,/(R)(''')|([\s\S])/g,/([uU])(''')|([\s\S])/g,/([uU]r)(')|([\s\S])/g,/([uU]R)(')|([\s\S])/g,/(r)(')|([\s\S])/g,/(R)(')|([\s\S])/g,/([uU])(')|([\s\S])/g,/(''')((?=\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)))|([\s\S])/g,/(')((?=\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)))|([\s\S])/g,/(')|([\s\S])/g,/\s*(\))(\s*)|([\s\S])/g,/\bnew\b|([\s\S])/g,/\$\({2}|([\s\S])/g,/\$\(|([\s\S])/g,/\b(friend|explicit|virtual)\b|([\s\S])/g,/\b(private:|protected:|public:)|([\s\S])/g,/\b(catch|operator|try|throw|using)\b|([\s\S])/g,/\bdelete\b(\s*\[\])?|\bnew\b(?!\])|([\s\S])/g,/\b(f|m)[A-Z]\w*\b|([\s\S])/g,/\b(this)\b|([\s\S])/g,/\btemplate\b\s*|([\s\S])/g,/\b(const_cast|dynamic_cast|reinterpret_cast|static_cast)\b\s*|([\s\S])/g,/\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq)\b|([\s\S])/g,/\b(class|wchar_t)\b|([\s\S])/g,/\b(export|mutable|typename)\b|([\s\S])/g,/=|/g,/(?:^|(?:))((?=((?:[A-Za-z_][A-Za-z0-9_]*::)*))\2~[A-Za-z_][A-Za-z0-9_]*)(\s*(\())|([\s\S])/g,/(?:^)((?=((?:[A-Za-z_][A-Za-z0-9_]*::)*))\2~[A-Za-z_][A-Za-z0-9_]*)(\s*(\())|([\s\S])/g,/(?=\n)|'|([\s\S])/g,/\\(x[0-9a-fA-F]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)|([\s\S])/g,/;|&&|&|\|\||([\s\S])/g,/\\(\\|[abefnprtv'"\?]|[0-3]\d{0,2}|[4-7]\d?|x[a-fA-F0-9]{0,2})|([\s\S])/g,/(<!)((ENTITY)(\s([\-_a-zA-Z0-9]+)))|([\s\S])/g,/(<<<)((')([^']*(')))|([\s\S])/g,/(<<<)((")((\\("|\\)|[^"])*(")))|([\s\S])/g,/(<<<)(([^\s\\]|\\.)+)|([\s\S])/g,/^\s*(class)(\s+(([\.a-zA-Z0-9_:]+(\s*(<)(\s*[\.a-zA-Z0-9_:]+))?)|((<<)(\s*[\.a-zA-Z0-9_:]+))))|([\s\S])/g,/^\s*(module)(\s+(([A-Z]\w*(::))?(([A-Z]\w*(::))?(([A-Z]\w*(::))*([A-Z]\w*)))))|([\s\S])/g,/\belse(\s)+if\b|([\s\S])/g,/\b(BEGIN|begin|case|class|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![\?!])|([\s\S])/g,/\bdo\b\s*|([\s\S])/g,/\{|/g,/(\s+)|([\s\S])/g,/\b(and|not|or)\b|([\s\S])/g,/\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![\?!])|\bdefined\?|\bblock_given\?|([\s\S])/g,/\bdefined\?|\bblock_given\?|([\s\S])/g,/\b(nil|true|false)\b(?![\?!])|([\s\S])/g,/\b(__(FILE|LINE)__|self)\b(?![\?!])|([\s\S])/g,/\b(initialize|new|loop|include|extend|raise|attr_reader|attr_writer|attr_accessor|attr|catch|throw|private|module_function|public|protected)\b(?![\?!])|([\s\S])/g,/\b(require|gem)(\b)|([\s\S])/g,/(@)([a-zA-Z_]\w*)|([\s\S])/g,/(@@)([a-zA-Z_]\w*)|([\s\S])/g,/(\$)([a-zA-Z_]\w*)|([\s\S])/g,/(\$)(!|@|&|`|'|\+|\d+|~|=|\/|\\|,|;|\.|<|>|_|\*|\$|\?|:|"|\-[0adFiIlpv])|([\s\S])/g,/\b(ENV)(\[)|([\s\S])/g,/\b[A-Z]\w*(?=((\.|::)[A-Za-z]|\[))|([\s\S])/g,/\b[A-Z]\w*\b|([\s\S])/g,/(?=def\b)(def)(\s+((?=([a-zA-Z_]\w*(?=(\.|::))\5))\4?(?=([a-zA-Z_]\w*(?=([\?!]|=(?!>)))\7?|===?|>[>=]?|<=>|<[<=]?|[%&`\/\|]|\*\*?|=?~|[\-\+]@?|\[\]=?))\6)(\s*(\()))|([\s\S])/g,/(?=def\b)(def)(\s+((?=([a-zA-Z_]\w*(?=(\.|::))\5))\4?(?=([a-zA-Z_]\w*(?=([\?!]|=(?!>)))\7?|===?|>[>=]?|<=>|<[<=]?|[%&`\/\|]|\*\*?|=?~|[\-\+]@?|\[\]=?))\6)([ \t](?=[ \t]*[^\s#])))|([\s\S])/g,/(?=def\b)(def)(\b(\s+((?=([a-zA-Z_]\w*(?=(\.|::))\6))\5?(?=([a-zA-Z_]\w*(?=([\?!]|=(?!>)))\8?|===?|>[>=]?|<=>|<[<=]?|[%&`\/\|]|\*\*?|=?~|[\-\+]@?|\[\]=?))\7))?)|([\s\S])/g,/\b(0[xX][0-9a-fA-F](?=(_?[0-9a-fA-F]))\2*|\d(?=(_?\d))\3*(\.(?![^[:space:][:digit:]])(?=(_?\d))\5*)?([eE][\-\+]?\d(?=(_?\d))\7*)?|0[bB][01]+)\b|([\s\S])/g,/:'|([\s\S])/g,/:"|([\s\S])/g,/\/=|([\s\S])/g,/%x\{|([\s\S])/g,/%x\[|([\s\S])/g,/%x<|([\s\S])/g,/%x\(|([\s\S])/g,/%x([^\w])|([\s\S])/g,/[=>~\(\?:\[,\|&;]|/g,/[\s;]if\s|[\s;]or\s|/g,/[\s\.]sub\s|[\s;]and\s|[\s;]not\s|/g,/[\s\.]scan\s|[\s\.]sub!\s|[\s\.]gsub\s|[\s;]when\s|/g,/[\s;]while\s|[\s\.]index\s|[\s;]elsif\s|[\s\.]gsub!\s|[\s\.]match\s|/g,/[\s;]unless\s|/g,/[\s;]assert_match\s|/g,/^if\s|/g,/^when\s|/g,/^while\s|^elsif\s|/g,/^unless\s|/g,/(?:^||)\s*((\/))((?![\*\+\{\}\?]))|([\s\S])/g,/(?:^|)\s*((\/))((?![\*\+\{\}\?]))|([\s\S])/g,/(?:^)\s*((\/))((?![\*\+\{\}\?]))|([\s\S])/g,/%r\[|([\s\S])/g,/%r\(|([\s\S])/g,/%r<|([\s\S])/g,/%r([^\w])|([\s\S])/g,/%[QWSR]?\(|([\s\S])/g,/%[QWSR]?\[|([\s\S])/g,/%[QWSR]?<|([\s\S])/g,/%[QWSR]?\{|([\s\S])/g,/%[QWSR]([^\w])|([\s\S])/g,/%([^\w\s=])|([\s\S])/g,/%[qws]\(|([\s\S])/g,/%[qws]<|([\s\S])/g,/%[qws]\[|([\s\S])/g,/%[qws]\{|([\s\S])/g,/%[qws]([^\w])|([\s\S])/g,/(:)((?=([a-zA-Z_]\w*(?=([\?!]|=(?![>=])))\4?|===?|>[>=]?|<[<=]?|<=>|[%&`\/\|]|\*\*?|=?~|[\-\+]@?|\[\]=?|@@?[a-zA-Z_]\w*))\3)|([\s\S])/g,/(?=([a-zA-Z_]\w*(?=([\?!]|=(?![>=])))\2?|===?|>[>=]?|<[<=]?|<=>|[%`\/\|]|\*\*?|=?~|[\-\+]@?|\[\]=?|@@?[a-zA-Z_]\w*))\1(:)((?!:))|([\s\S])/g,/^=begin|([\s\S])/g,/(?:^[ \t]+)?(#)(.*(?=\n)\n?)|([\s\S])/g,/\?(\\(x[0-9a-fA-F]{1,2}(?![0-9a-fA-F])\b|0[0-7]{0,2}(?![0-7])\b|[^x0MC])|(\\[MC]\-)+\w|[^\s\\])|([\s\S])/g,/^__END__\n|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?!\s+#\s*([Cc]|sh|[Jj]ava))|([\s\S])/g,/(?=(<<\-HTML\b))\1|([\s\S])/g,/(?=(<<\-SQL\b))\1|([\s\S])/g,/(?=(<<\-(["\\']?)(\w+_(?:[eE][vV][aA][lL]))\2))\1|([\s\S])/g,/(?=(<<\-(\w+)))\1|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?=\s+#\s*[Cc](?!(\+\+|[Ss][Ss])))|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?=\s+#\s*[Cc]\+\+)|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?=\s+#\s*[Cc][Ss][Ss])|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?=\s+#\s*[Jj]ava[Ss]cript)|([\s\S])/g,/(?=(=\s*<<(\w+)))\1(?=\s+#\s*sh)|([\s\S])/g,/do|\{\s|/g,/do\s|/g,/<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<|([\s\S])/g,/[ \t]|/g,/<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|\?|([\s\S])/g,/<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|([\s\S])/g,/!+|\bnot\b|&&|\band\b|\|\||\bor\b|\^|([\s\S])/g,/\bnot\b|&&|\band\b|\|\||\bor\b|\^|([\s\S])/g,/(%|&|\*\*|\*|\+|\-|\/)|([\s\S])/g,/\||~|>>|([\s\S])/g,/\.|::|([\s\S])/g];
+var B=[[A[0],3,[1],[[2]]],[A[1],2,[1],[[]]],[A[2],3,[1],[[2]]],[A[3],1,[],[]],[A[4],1,[],[]],[A[5],4,[1,3],[[2],[]]],[A[6],3,[1,2],[[2],[]]],[A[7],1,[0],[[]]],[A[8],10,[1,4,5,6,7],[[2],[5,7,8],[7,8],[7,8],[8]]],[A[9],7,[1,3,4,5,6],[[2],[4,6],[6],[6],[]]],[A[10],5,[1,4],[[2],[]]],[A[11],1,[],[]],[A[12],1,[0],[[]]],[A[13],1,[0],[[]]],[A[14],1,[0],[[]]],[A[15],1,[0],[[]]],[A[16],1,[0],[[]]],[A[17],2,[],[]],[A[18],2,[],[]],[A[19],1,[],[]],[A[20],1,[],[]],[A[21],3,[],[]],[A[22],1,[0],[[]]],[A[23],1,[],[]],[A[24],1,[],[]],[A[3],1,[],[]],[A[25],3,[0,1],[[],[2]]],[A[26],1,[],[]],[A[27],4,[1,2],[[],[3]]],[A[28],4,[1,2],[[],[3]]],[A[29],1,[],[]],[A[29],1,[],[]],[A[31],1,[0],[[]]],[A[32],2,[1],[[]]],[A[27],4,[1,2],[[],[3]]],[A[28],4,[1,2],[[],[3]]],[A[29],1,[],[]],[A[33],10,[1,3,8],[[2,6],[5,6],[9]]],[A[34],4,[1,3],[[2],[]]],[A[35],9,[1,3,5,7],[[2],[4],[6],[8]]],[A[36],5,[1,3],[[2],[4]]],[A[37],34,[1,3,5,7,9,12,14,16,19,21,24,26,28,30,32],[[2],[4],[6],[8],[10,11],[13],[15,18],[17,18],[20],[22,23],[25],[27],[29,33],[31,33],[33]]],[A[38],3,[],[]],[A[39],1,[],[]],[A[40],11,[],[]],[A[41],4,[],[]],[A[42],1,[],[]],[A[43],5,[],[]],[A[44],3,[],[]],[A[45],1,[],[]],[A[46],4,[],[]],[A[47],1,[],[]],[A[48],2,[],[]],[A[49],1,[],[]],[A[50],1,[],[]],[A[51],1,[],[]],[A[52],1,[],[]],[A[53],5,[],[]],[A[54],2,[],[]],[A[55],2,[],[]],[A[56],4,[1,3],[[2],[]]],[A[57],3,[1],[[2]]],[A[58],5,[1,3],[[2],[4]]],[A[59],3,[1],[[2]]],[A[60],5,[1,3],[[2],[4]]],[A[61],3,[1],[[2]]],[A[62],3,[1],[[2]]],[A[63],1,[0],[[]]],[A[64],3,[1],[[2]]],[A[65],1,[],[]],[A[66],1,[0],[[]]],[A[67],1,[],[]],[A[68],5,[1,4],[[2],[]]],[A[11],1,[],[]],[A[69],1,[],[]],[A[70],1,[],[]],[A[24],1,[0],[[]]],[A[71],4,[1,3],[[2],[]]],[A[72],4,[1],[[2]]],[A[15],1,[0],[[]]],[A[32],2,[1],[[]]],[A[24],1,[0],[[]]],[A[3],1,[],[]],[A[73],1,[],[]],[A[74],1,[],[]],[A[1],2,[1],[[]]],[A[75],1,[0],[[]]],[A[3],1,[],[]],[A[4],1,[],[]],[A[76],5,[1,3],[[2],[4]]],[A[77],1,[0],[[]]],[A[78],1,[],[]],[A[65],1,[0],[[]]],[A[79],5,[1,2],[[4],[3,4]]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[82],1,[],[]],[A[83],6,[1,5],[[4],[]]],[A[84],1,[0],[[]]],[A[31],1,[0],[[]]],[A[84],1,[0],[[]]],[A[85],1,[],[]],[A[70],1,[],[]],[A[86],1,[],[]],[A[65],1,[0],[[]]],[A[82],1,[0],[[]]],[A[65],1,[0],[[]]],[A[87],3,[0,1],[[],[2]]],[A[88],6,[],[]],[A[32],2,[1],[[]]],[A[24],1,[0],[[]]],[A[89],1,[],[]],[A[90],2,[],[]],[A[91],2,[1],[[]]],[A[27],4,[1,2],[[],[3]]],[A[92],5,[1,2],[[4],[3,4]]],[A[29],1,[],[]],[A[82],1,[0],[[]]],[A[93],1,[],[]],[A[94],2,[],[]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[95],1,[],[]],[A[96],1,[],[]],[A[97],3,[1,2],[[],[]]],[A[98],3,[1],[[2]]],[A[82],1,[],[]],[A[99],1,[0],[[]]],[A[15],1,[0],[[]]],[A[66],1,[],[]],[A[100],1,[],[]],[A[101],4,[1],[[2]]],[A[102],5,[],[]],[A[103],3,[],[]],[A[104],4,[],[]],[A[105],3,[],[]],[A[106],2,[],[]],[A[107],2,[],[]],[A[108],1,[],[]],[A[109],7,[1,4,5],[[2],[6],[6]]],[A[110],4,[],[]],[A[111],5,[1,3],[[2],[4]]],[A[112],9,[],[]],[A[113],4,[1],[[3]]],[A[114],2,[1],[[]]],[A[115],8,[1,2,3,5,7],[[6],[6],[4,6],[6],[]]],[A[116],1,[],[]],[A[117],1,[],[]],[A[118],3,[0,1],[[],[2]]],[A[119],3,[1,2],[[2],[]]],[A[120],1,[],[]],[A[121],1,[],[]],[A[122],1,[],[]],[A[123],2,[],[]],[A[124],5,[1,3],[[2],[4]]],[A[16],1,[0],[[]]],[A[126],2,[],[]],[A[127],2,[],[]],[A[128],1,[],[]],[A[65],1,[0],[[]]],[A[24],1,[0],[[]]],[A[65],1,[0],[[]]],[A[129],1,[],[]],[A[90],2,[],[]],[A[16],1,[0],[[]]],[A[15],1,[0],[[]]],[A[130],3,[1],[[2]]],[A[131],1,[0],[[]]],[A[132],3,[1],[[2]]],[A[133],1,[],[]],[A[66],1,[0],[[]]],[A[97],3,[1,2],[[],[]]],[A[134],4,[1,3],[[2],[]]],[A[135],9,[1,3,5,7,8],[[2],[4],[6],[8],[]]],[A[136],6,[1,3],[[2],[4]]],[A[95],1,[],[]],[A[137],5,[1,3],[[2],[4]]],[A[138],5,[1,3],[[2],[4]]],[A[82],1,[0],[[]]],[A[139],1,[0],[[]]],[A[140],7,[1,2,5,6],[[4],[3,4],[6],[]]],[A[141],1,[],[]],[A[142],4,[1],[[2]]],[A[24],1,[0],[[]]],[A[143],4,[1],[[2]]],[A[23],1,[0],[[]]],[A[144],4,[1],[[2]]],[A[16],1,[0],[[]]],[A[145],1,[0],[[]]],[A[77],1,[0],[[]]],[A[67],1,[],[]],[A[146],2,[1],[[]]],[A[32],2,[1],[[]]],[A[147],2,[1],[[]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[16],1,[0],[[]]],[A[24],1,[0],[[]]],[A[151],2,[],[]],[A[152],5,[0,1,3],[[],[2],[4]]],[A[153],5,[0,1,3],[[],[2],[4]]],[A[154],5,[0,1,3],[[],[2],[4]]],[A[155],5,[0,1,3],[[],[2],[4]]],[A[16],1,[0],[[]]],[A[156],1,[],[]],[A[16],1,[0],[[]]],[A[66],1,[0],[[]]],[A[157],1,[0],[[]]],[A[1],2,[1],[[]]],[A[158],2,[1],[[]]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[159],5,[0,1,3],[[],[2],[4]]],[A[160],1,[0],[[]]],[A[161],2,[1],[[]]],[A[29],1,[],[]],[A[163],1,[],[]],[A[164],1,[0],[[]]],[A[165],1,[],[]],[A[166],1,[],[]],[A[167],1,[],[]],[A[168],6,[1,2,5],[[],[3],[]]],[A[169],20,[1,2,5,7,9,11,13,14,15,17,18,19],[[4],[3,4],[6],[],[],[12],[19],[19],[16,19],[19],[19],[]]],[A[170],11,[0],[[]]],[A[65],1,[0],[[]]],[A[171],1,[],[]],[A[172],1,[0],[[]]],[A[173],1,[],[]],[A[174],1,[0],[[]]],[A[175],6,[2],[[3]]],[A[16],1,[0],[[]]],[A[176],2,[],[]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[177],1,[0],[[]]],[A[85],1,[],[]],[A[70],1,[],[]],[A[178],1,[],[]],[A[180],1,[],[]],[A[146],2,[1],[[]]],[A[181],3,[1],[[2]]],[A[182],2,[1],[[]]],[A[183],2,[],[]],[A[184],2,[],[]],[A[185],3,[1],[[2]]],[A[186],4,[1],[[2]]],[A[187],4,[1],[[2]]],[A[188],4,[1],[[2]]],[A[189],4,[1],[[2]]],[A[190],4,[1],[[2]]],[A[191],4,[1],[[2]]],[A[192],5,[1,3],[[2],[4]]],[A[193],3,[1],[[2]]],[A[194],1,[],[]],[A[195],2,[1],[[]]],[A[196],3,[0,1],[[],[2]]],[A[65],1,[0],[[]]],[A[197],5,[1,4],[[2],[]]],[A[198],5,[1,4],[[2],[]]],[A[199],3,[1],[[2]]],[A[200],3,[1,2],[[],[]]],[A[201],1,[],[]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[82],1,[],[]],[A[202],2,[1],[[]]],[A[67],1,[],[]],[A[203],1,[0],[[]]],[A[204],12,[1,3,4,6,7,8,10],[[2],[10],[5,10],[7,10],[10],[9,10],[]]],[A[205],1,[0],[[]]],[A[207],4,[0,2],[[],[3]]],[A[208],3,[0,-1],[[],[]]],[A[209],2,[],[]],[A[84],1,[0],[[]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[16],1,[0],[[]]],[A[65],1,[],[]],[A[210],2,[1],[[]]],[A[211],1,[],[]],[A[24],1,[0],[[]]],[A[65],1,[],[]],[A[212],14,[1,3,5,6,9,11,13],[[2],[4],[8],[7,8],[10],[12],[]]],[A[213],14,[1,3,5,6,9,11,12],[[2],[4],[8],[7,8],[10,13],[13],[13]]],[A[214],14,[1,3,5,6,9,11,12],[[2],[4],[8],[7,8],[10,13],[13],[13]]],[A[215],7,[1,3,4],[[2],[6],[5,6]]],[A[216],10,[1,3,4,7],[[2],[6],[5,6],[8,9]]],[A[217],1,[0],[[]]],[A[218],1,[],[]],[A[219],1,[0],[[]]],[A[220],2,[],[]],[A[97],3,[1,2],[[],[]]],[A[221],2,[1],[[]]],[A[222],5,[1,3,4],[[2],[],[]]],[A[201],1,[],[]],[A[182],2,[1],[[]]],[A[82],1,[0],[[]]],[A[223],4,[1,3],[[2],[]]],[A[224],1,[0],[[]]],[A[225],3,[1],[[2]]],[A[226],1,[],[]],[A[146],2,[1],[[]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[227],1,[0],[[]]],[A[228],1,[0],[[]]],[A[229],4,[1,3],[[2],[]]],[A[230],2,[0],[[]]],[A[231],1,[0],[[]]],[A[232],1,[],[]],[A[15],1,[],[]],[A[29],1,[],[]],[A[16],1,[0],[[]]],[A[24],1,[0],[[]]],[A[234],3,[1],[[2]]],[A[235],3,[1],[[2]]],[A[236],3,[1],[[2]]],[A[237],1,[0],[[]]],[A[146],2,[1],[[]]],[A[240],1,[],[]],[A[241],1,[],[]],[A[242],1,[],[]],[A[243],3,[],[]],[A[16],1,[0],[[]]],[A[244],2,[],[]],[A[245],1,[],[]],[A[246],3,[0,1],[[],[2]]],[A[247],1,[],[]],[A[226],1,[],[]],[A[226],1,[0],[[]]],[A[97],3,[1,2],[[],[]]],[A[226],1,[],[]],[A[248],2,[],[]],[A[249],1,[0],[[]]],[A[217],1,[0],[[]]],[A[250],4,[1],[[2]]],[A[251],4,[1],[[2]]],[A[252],7,[1,3,5],[[2],[4],[6]]],[A[253],7,[1,3,5],[[2],[4],[6]]],[A[254],10,[],[]],[A[255],3,[1],[[2]]],[A[256],9,[1,3,5,6],[[2],[4],[8],[7,8]]],[A[257],2,[],[]],[A[258],11,[1,3,5,7,8,10],[[2],[4],[6],[9],[9],[]]],[A[259],4,[],[]],[A[260],4,[],[]],[A[261],9,[1,3,5,6,8],[[2],[4],[],[7],[]]],[A[262],4,[1,3],[[2],[]]],[A[263],1,[],[]],[A[264],2,[],[]],[A[265],1,[],[]],[A[266],2,[],[]],[A[267],2,[],[]],[A[268],2,[],[]],[A[269],3,[],[]],[A[270],1,[],[]],[A[271],2,[],[]],[A[272],2,[],[]],[A[273],1,[],[]],[A[274],4,[1,3],[[2],[]]],[A[276],5,[1,3],[[2],[4]]],[A[129],1,[],[]],[A[90],2,[],[]],[A[277],3,[0,1],[[],[2]]],[A[278],3,[],[]],[A[279],6,[],[]],[A[280],2,[],[]],[A[281],2,[],[]],[A[282],2,[],[]],[A[283],2,[],[]],[A[284],2,[],[]],[A[285],14,[],[]],[A[286],2,[],[]],[A[287],3,[],[]],[A[288],3,[],[]],[A[289],3,[],[]],[A[290],3,[],[]],[A[291],2,[],[]],[A[97],3,[1,2],[[],[]]],[A[16],1,[0],[[]]],[A[16],1,[0],[[]]],[A[292],1,[0],[[]]],[A[293],2,[],[]],[A[294],2,[],[]],[A[295],2,[],[]],[A[296],2,[],[]],[A[297],2,[],[]],[A[298],2,[1],[[]]],[A[299],1,[0],[[]]],[A[300],1,[0],[[]]],[A[301],1,[0],[[]]],[A[302],6,[1,3,5],[[2],[4],[]]],[A[303],4,[1,3],[[2],[]]],[A[84],1,[0],[[]]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[308],3,[1],[[2]]],[A[1],2,[1],[[]]],[A[292],1,[0],[[]]],[A[65],1,[0],[[]]],[A[31],1,[0],[[]]],[A[3],1,[],[]],[A[309],1,[0],[[]]],[A[310],3,[0],[[]]],[A[16],1,[0],[[]]],[A[3],1,[],[]],[A[226],1,[0],[[]]],[A[16],1,[0],[[]]],[A[311],3,[0,1],[[],[2]]],[A[312],2,[],[]],[A[313],2,[],[]],[A[314],11,[],[]],[A[315],4,[1],[[2]]],[A[316],3,[1,2],[[2],[]]],[A[317],3,[1,2],[[2],[]]],[A[318],3,[1,2],[[2],[]]],[A[319],3,[1,2],[[2],[]]],[A[320],3,[1,2],[[2],[]]],[A[321],3,[1,2],[[2],[]]],[A[322],3,[1,2],[[2],[]]],[A[323],3,[1,2],[[2],[]]],[A[324],3,[1,2],[[2],[]]],[A[325],3,[1,2],[[2],[]]],[A[326],4,[1],[[2]]],[A[327],4,[1],[[2]]],[A[81],2,[1],[[]]],[A[328],2,[1],[[]]],[A[24],1,[0],[[]]],[A[329],1,[],[]],[A[24],1,[0],[[]]],[A[3],1,[],[]],[A[331],2,[1],[[]]],[A[292],1,[0],[[]]],[A[332],1,[],[]],[A[333],1,[],[]],[A[334],3,[],[]],[A[335],3,[1],[[2]]],[A[336],3,[1],[[2]]],[A[49],1,[],[]],[A[337],4,[1],[[2]]],[A[338],4,[1],[[2]]],[A[339],15,[1,3,5,7,8,10,12],[[2],[4],[6,13],[13],[13],[11,13],[13]]],[A[340],1,[],[]],[A[341],1,[],[]],[A[65],1,[0],[[]]],[A[226],1,[0],[[]]],[A[342],1,[],[]],[A[69],1,[],[]],[A[70],1,[],[]],[A[343],2,[0,1],[[],[]]],[A[344],1,[0],[[]]],[A[345],3,[1],[[2]]],[A[346],3,[1],[[2]]],[A[347],3,[1],[[2]]],[A[84],1,[0],[[]]],[A[79],5,[1,2],[[4],[3,4]]],[A[348],2,[1],[[]]],[A[349],2,[],[]],[A[350],2,[],[]],[A[351],2,[],[]],[A[352],2,[],[]],[A[353],3,[],[]],[A[355],2,[],[]],[A[356],1,[],[]],[A[357],4,[1],[[2]]],[A[358],4,[1,3],[[2],[]]],[A[359],1,[],[]],[A[360],1,[0],[[]]],[A[361],2,[1],[[]]],[A[363],1,[],[]],[A[24],1,[0],[[]]],[A[226],1,[0],[[]]],[A[16],1,[0],[[]]],[A[146],2,[],[]],[A[364],2,[],[]],[A[23],1,[0],[[]]],[A[3],1,[],[]],[A[23],1,[],[]],[A[365],6,[0,1,4],[[],[2],[5]]],[A[366],6,[0,1,4],[[],[2],[5]]],[A[367],6,[0,1,4],[[],[2],[5]]],[A[368],6,[0,1,4],[[],[2],[5]]],[A[369],6,[0,1,4],[[],[2],[5]]],[A[370],6,[0,1,4],[[],[2],[5]]],[A[371],6,[0,1,4],[[],[2],[5]]],[A[372],6,[0,1,4],[[],[2],[5]]],[A[373],6,[0,1,4],[[],[2],[5]]],[A[374],6,[0,1,4],[[],[2],[5]]],[A[375],6,[0,1,4],[[],[2],[5]]],[A[376],6,[0,1,4],[[],[2],[5]]],[A[377],6,[0,1,4],[[],[2],[5]]],[A[378],6,[0,1,4],[[],[2],[5]]],[A[84],1,[0],[[]]],[A[379],1,[0],[[]]],[A[380],2,[1],[[]]],[A[381],5,[1,3],[[2],[4]]],[A[361],2,[1],[[]]],[A[382],1,[],[]],[A[383],2,[1],[[]]],[A[384],1,[0],[[]]],[A[385],10,[],[]],[A[356],1,[],[]],[A[386],4,[1,2,3],[[],[],[]]],[A[387],7,[1,3,5],[[2],[4],[6]]],[A[1],2,[1],[[]]],[A[388],4,[0],[[]]],[A[389],5,[1,4],[[2],[]]],[A[390],2,[],[]],[A[391],1,[],[]],[A[392],1,[0],[[]]],[A[393],1,[],[]],[A[394],1,[],[]],[A[395],1,[],[]],[A[396],1,[],[]],[A[203],1,[0],[[]]],[A[397],7,[1,3,4,5],[[2],[],[],[6]]],[A[98],3,[1],[[2]]],[A[24],1,[0],[[]]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[398],2,[],[]],[A[203],1,[0],[[]]],[A[27],4,[1,2],[[],[3]]],[A[92],5,[1,2],[[4],[3,4]]],[A[29],1,[],[]],[A[75],1,[],[]],[A[399],1,[0],[[]]],[A[75],1,[0],[[]]],[A[400],1,[0],[[]]],[A[401],5,[1,2,4],[[],[3],[]]],[A[4],1,[],[]],[A[232],1,[],[]],[A[203],1,[0],[[]]],[A[402],1,[],[]],[A[114],2,[1],[[]]],[A[97],3,[1,2],[[],[]]],[A[95],1,[],[]],[A[116],1,[],[]],[A[403],1,[],[]],[A[404],3,[1],[[2]]],[A[405],1,[],[]],[A[226],1,[],[]],[A[24],1,[0],[[]]],[A[406],2,[],[]],[A[407],2,[],[]],[A[408],3,[],[]],[A[409],1,[],[]],[A[410],1,[],[]],[A[411],1,[0],[[]]],[A[70],1,[],[]],[A[412],3,[],[]],[A[413],12,[],[]],[A[414],58,[],[]],[A[415],1,[],[]],[A[416],6,[1,2,4],[[],[3],[5]]],[A[98],3,[1],[[2]]],[A[32],2,[1],[[]]],[A[417],2,[],[]],[A[31],1,[0],[[]]],[A[16],1,[0],[[]]],[A[24],1,[0],[[]]],[A[418],5,[],[]],[A[420],1,[],[]],[A[421],1,[],[]],[A[422],1,[],[]],[A[423],1,[],[]],[A[424],3,[1],[[2]]],[A[425],1,[],[]],[A[226],1,[],[]],[A[426],2,[],[]],[A[427],2,[],[]],[A[29],1,[],[]],[A[66],1,[],[]],[A[416],6,[1,2,4],[[],[3],[5]]],[A[389],5,[1,4],[[2],[]]],[A[392],1,[0],[[]]],[A[66],1,[0],[[]]],[A[428],3,[1],[[2]]],[A[429],1,[],[]],[A[430],1,[],[]],[A[431],1,[],[]],[A[432],1,[],[]],[A[433],1,[],[]],[A[434],1,[0],[[]]],[A[435],3,[1],[[2]]],[A[436],2,[1],[[]]],[A[437],2,[],[]],[A[77],1,[0],[[]]],[A[438],2,[1],[[]]],[A[439],1,[],[]],[A[440],3,[],[]],[A[29],1,[],[]],[A[441],7,[1,2,4],[[6],[3,6],[5,6]]],[A[114],2,[1],[[]]],[A[443],1,[],[]],[A[180],1,[],[]],[A[445],2,[],[]],[A[446],2,[],[]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[98],3,[1],[[2]]],[A[77],1,[0],[[]]],[A[447],1,[],[]],[A[448],4,[1,2],[[],[3]]],[A[449],9,[1,2,5],[[4],[3,4],[8]]],[A[226],1,[0],[[]]],[A[82],1,[0],[[]]],[A[441],7,[1,2,4],[[6],[3,6],[5,6]]],[A[75],1,[0],[[]]],[A[450],6,[1,3,5],[[2],[4],[]]],[A[451],6,[1,3,5],[[2],[4],[]]],[A[452],1,[],[]],[A[453],2,[],[]],[A[201],1,[],[]],[A[455],1,[],[]],[A[436],2,[1],[[]]],[A[456],2,[0],[[]]],[A[446],2,[],[]],[A[457],1,[],[]],[A[458],3,[0,1],[[],[2]]],[A[459],3,[1],[[2]]],[A[32],2,[1],[[]]],[A[460],7,[1,3,5],[[2],[4],[6]]],[A[461],15,[1,3,5,7,9,11,13,14],[[2],[4],[6],[8],[10],[12],[14],[]]],[A[462],9,[1,3,5,7],[[2],[4],[6],[8]]],[A[463],13,[1,3,5,7,9,11,12],[[2],[4],[6],[8],[10],[12],[]]],[A[464],11,[1,3,5,7,9,10],[[2],[4],[6],[8],[10],[]]],[A[465],9,[1,3,5,7,8],[[2],[4],[6],[8],[]]],[A[466],9,[1,3,5,7,8],[[2],[4],[6],[8],[]]],[A[467],18,[1,2,4,5,6,7,9,10,12,14,16,17],[[11],[3,11],[5,11],[11],[11],[8,11],[10,11],[11],[13],[15],[17],[]]],[A[468],4,[1,3],[[2],[]]],[A[469],2,[],[]],[A[470],2,[],[]],[A[471],6,[],[]],[A[24],1,[0],[[]]],[A[16],1,[0],[[]]],[A[472],1,[0],[[]]],[A[217],1,[0],[[]]],[A[473],3,[1],[[2]]],[A[474],2,[1],[[]]],[A[475],2,[],[]],[A[476],2,[],[]],[A[477],2,[],[]],[A[478],2,[],[]],[A[479],1,[],[]],[A[480],1,[],[]],[A[481],1,[],[]],[A[482],2,[],[]],[A[483],2,[],[]],[A[484],2,[],[]],[A[485],90,[],[]],[A[486],31,[],[]],[A[487],101,[],[]],[A[488],65,[],[]],[A[489],2,[],[]],[A[490],32,[],[]],[A[492],2,[],[]],[A[493],2,[],[]],[A[494],2,[],[]],[A[497],3,[1],[[2]]],[A[265],1,[],[]],[A[498],1,[],[]],[A[499],1,[],[]],[A[500],1,[],[]],[A[501],1,[],[]],[A[502],1,[],[]],[A[65],1,[0],[[]]],[A[65],1,[0],[[]]],[A[503],1,[],[]],[A[226],1,[],[]],[A[504],1,[],[]],[A[505],1,[0],[[]]],[A[226],1,[],[]],[A[146],2,[1],[[]]],[A[506],1,[],[]],[A[507],18,[],[]],[A[510],4,[1],[[3]]],[A[116],1,[],[]],[A[511],1,[],[]],[A[512],5,[],[]],[A[513],5,[],[]],[A[514],4,[],[]],[A[515],1,[],[]],[A[516],2,[],[]],[A[517],13,[],[]],[A[520],2,[],[]],[A[521],2,[],[]],[A[522],2,[],[]],[A[523],2,[],[]],[A[524],3,[],[]],[A[525],22,[],[]],[A[526],4,[],[]],[A[528],3,[1],[[2]]],[A[75],1,[0],[[]]],[A[529],1,[],[]],[A[530],5,[1],[[2]]],[A[263],1,[],[]],[A[273],1,[],[]],[A[531],1,[],[]],[A[532],4,[1,3],[[2],[]]],[A[15],1,[],[]],[A[533],2,[1],[[]]],[A[534],2,[],[]],[A[535],5,[1,3],[[2],[4]]],[A[536],5,[1,3],[[2],[4]]],[A[75],1,[0],[[]]],[A[16],1,[0],[[]]],[A[3],1,[],[]],[A[67],1,[],[]],[A[85],1,[],[]],[A[70],1,[],[]],[A[84],1,[0],[[]]],[A[380],2,[1],[[]]],[A[537],1,[],[]],[A[538],1,[0],[[]]],[A[539],1,[],[]],[A[540],2,[1],[[]]],[A[543],2,[1],[[]]],[A[328],2,[1],[[]]],[A[328],2,[1],[[]]],[A[328],2,[1],[[]]],[A[544],4,[1,3],[[2],[]]],[A[545],14,[1,3,5,7,9,11,13],[[2],[4],[6],[8],[10],[12],[]]],[A[546],8,[1,3,5,6],[[2],[4],[],[7]]],[A[24],1,[0],[[]]],[A[70],1,[],[]],[A[328],2,[1],[[]]],[A[3],1,[],[]],[A[547],2,[],[]],[A[548],1,[0],[[]]],[A[222],5,[1,3,4],[[2],[],[]]],[A[201],1,[],[]],[A[182],2,[1],[[]]],[A[23],1,[0],[[]]],[A[549],1,[],[]],[A[550],7,[1,2,3,5],[[2,4],[4],[4],[6]]],[A[551],3,[0,1],[[],[2]]],[A[552],6,[1,3],[[2],[5]]],[A[553],3,[1,2],[[2],[]]],[A[554],1,[0],[[]]],[A[555],1,[0],[[]]],[A[556],5,[1,3],[[2],[4]]],[A[557],5,[1,3],[[2],[4]]],[A[558],3,[1,2],[[2],[]]],[A[559],3,[1,2],[[2],[]]],[A[560],3,[1,2],[[2],[]]],[A[561],3,[1,2],[[2],[]]],[A[562],1,[],[]],[A[15],1,[],[]],[A[65],1,[0],[[]]],[A[65],1,[],[]],[A[24],1,[0],[[]]],[A[563],1,[],[]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[564],1,[],[]],[A[75],1,[0],[[]]],[A[565],1,[],[]],[A[75],1,[],[]],[A[566],1,[],[]],[A[97],3,[1,2],[[],[]]],[A[567],2,[],[]],[A[568],3,[1],[[2]]],[A[569],1,[],[]],[A[570],4,[1,3],[[2],[]]],[A[457],1,[],[]],[A[571],1,[],[]],[A[75],1,[0],[[]]],[A[446],2,[],[]],[A[232],1,[],[]],[A[65],1,[0],[[]]],[A[333],1,[],[]],[A[80],4,[1,2],[[],[3]]],[A[81],2,[1,-1],[[],[]]],[A[572],5,[0,1,3],[[],[2],[4]]],[A[573],5,[1],[[2]]],[A[65],1,[],[]],[A[575],3,[1],[[2]]],[A[576],2,[1],[[]]],[A[577],1,[],[]],[A[578],1,[],[]],[A[579],3,[1],[[2]]],[A[580],1,[0],[[]]],[A[146],2,[1],[[]]],[A[581],4,[1,3],[[2],[]]],[A[117],1,[],[]],[A[582],1,[0],[[]]],[A[95],1,[],[]],[A[90],2,[],[]],[A[583],3,[1,2],[[2],[]]],[A[584],41,[],[]],[A[585],2,[],[]],[A[586],1,[],[]],[A[587],2,[],[]],[A[588],28,[],[]],[A[589],5,[],[]],[A[590],7,[],[]],[A[591],1,[],[]],[A[592],24,[],[]],[A[593],3,[],[]],[A[594],2,[],[]],[A[595],7,[],[]],[A[596],2,[],[]],[A[597],2,[],[]],[A[598],12,[],[]],[A[599],1,[],[]],[A[600],1,[],[]],[A[601],4,[],[]],[A[602],1,[],[]],[A[603],1,[],[]],[A[604],4,[],[]],[A[605],6,[],[]],[A[606],6,[],[]],[A[607],1,[],[]],[A[608],6,[],[]],[A[609],17,[],[]],[A[610],2,[],[]],[A[611],1,[],[]],[A[612],3,[],[]],[A[613],1,[],[]],[A[614],2,[],[]],[A[615],1,[],[]],[A[616],2,[],[]],[A[617],16,[],[]],[A[618],6,[],[]],[A[619],3,[],[]],[A[620],18,[],[]],[A[621],17,[],[]],[A[622],8,[],[]],[A[623],4,[],[]],[A[624],3,[],[]],[A[625],2,[],[]],[A[626],1,[],[]],[A[627],45,[],[]],[A[628],5,[],[]],[A[629],17,[],[]],[A[630],7,[],[]],[A[631],2,[],[]],[A[632],2,[],[]],[A[633],5,[],[]],[A[634],4,[],[]],[A[635],1,[],[]],[A[636],4,[],[]],[A[637],2,[],[]],[A[638],8,[],[]],[A[639],6,[],[]],[A[640],8,[],[]],[A[641],3,[],[]],[A[642],4,[],[]],[A[643],7,[],[]],[A[644],6,[],[]],[A[645],2,[],[]],[A[646],2,[],[]],[A[647],1,[],[]],[A[648],16,[],[]],[A[649],1,[],[]],[A[650],3,[],[]],[A[651],3,[],[]],[A[652],2,[],[]],[A[653],1,[],[]],[A[654],22,[],[]],[A[655],21,[],[]],[A[656],20,[],[]],[A[631],2,[],[]],[A[657],1,[],[]],[A[658],4,[],[]],[A[659],3,[],[]],[A[660],1,[],[]],[A[661],6,[],[]],[A[662],3,[],[]],[A[663],36,[],[]],[A[664],2,[],[]],[A[665],8,[],[]],[A[666],7,[],[]],[A[667],1,[],[]],[A[668],5,[],[]],[A[669],2,[],[]],[A[670],79,[],[]],[A[671],10,[],[]],[A[672],1,[],[]],[A[673],3,[],[]],[A[674],36,[],[]],[A[675],21,[],[]],[A[676],8,[],[]],[A[677],2,[],[]],[A[678],3,[],[]],[A[679],7,[],[]],[A[680],1,[],[]],[A[680],1,[],[]],[A[681],41,[],[]],[A[682],16,[],[]],[A[683],16,[],[]],[A[684],1,[],[]],[A[685],29,[],[]],[A[686],15,[],[]],[A[687],5,[],[]],[A[688],31,[],[]],[A[689],9,[],[]],[A[690],4,[],[]],[A[691],10,[],[]],[A[692],13,[],[]],[A[693],20,[],[]],[A[694],23,[],[]],[A[695],4,[],[]],[A[696],6,[],[]],[A[697],10,[],[]],[A[698],7,[],[]],[A[699],28,[],[]],[A[700],18,[],[]],[A[701],15,[],[]],[A[702],2,[],[]],[A[703],10,[],[]],[A[704],1,[],[]],[A[705],3,[],[]],[A[706],7,[],[]],[A[707],2,[],[]],[A[708],6,[],[]],[A[709],9,[],[]],[A[632],2,[],[]],[A[710],2,[],[]],[A[711],3,[],[]],[A[712],1,[],[]],[A[713],11,[],[]],[A[714],14,[],[]],[A[715],1,[],[]],[A[716],2,[],[]],[A[717],17,[],[]],[A[718],14,[],[]],[A[719],29,[],[]],[A[720],2,[],[]],[A[721],2,[],[]],[A[722],5,[],[]],[A[723],3,[],[]],[A[724],3,[],[]],[A[725],2,[],[]],[A[726],12,[],[]],[A[727],2,[],[]],[A[728],7,[],[]],[A[729],1,[],[]],[A[730],4,[],[]],[A[731],3,[],[]],[A[732],1,[],[]],[A[733],3,[],[]],[A[734],2,[],[]],[A[735],4,[],[]],[A[736],1,[],[]],[A[737],4,[],[]],[A[738],11,[],[]],[A[739],8,[],[]],[A[740],2,[],[]],[A[741],4,[],[]],[A[742],3,[],[]],[A[743],2,[],[]],[A[744],33,[],[]],[A[745],5,[],[]],[A[146],2,[],[]],[A[746],3,[1,2],[[],[]]],[A[84],1,[0],[[]]],[A[65],1,[0],[[]]],[A[77],1,[0],[[]]],[A[747],3,[1,2],[[2],[]]],[A[748],4,[1],[[2]]],[A[217],1,[0],[[]]],[A[23],1,[0],[[]]],[A[32],2,[1],[[]]],[A[100],1,[],[]],[A[749],4,[1,2],[[],[3]]],[A[361],2,[1],[[]]],[A[750],6,[2,5],[[3],[]]],[A[751],5,[0,1,3],[[],[2],[4]]],[A[24],1,[0],[[]]],[A[752],2,[],[]],[A[753],1,[],[]],[A[754],1,[],[]],[A[755],1,[],[]],[A[757],1,[],[]],[A[758],1,[],[]],[A[759],3,[1,2],[[2],[]]],[A[760],14,[1,2,3,4,5,6,7,8,9,10,11,12,13],[[],[],[],[],[],[],[],[],[],[],[],[],[]]],[A[32],2,[1],[[]]],[A[761],1,[],[]],[A[292],1,[],[]],[A[226],1,[],[]],[A[65],1,[0],[[]]],[A[762],2,[],[]],[A[763],1,[],[]],[A[764],2,[],[]],[A[765],2,[],[]],[A[766],2,[],[]],[A[767],2,[],[]],[A[267],2,[],[]],[A[268],2,[],[]],[A[768],2,[],[]],[A[770],1,[],[]],[A[265],1,[],[]],[A[411],1,[0],[[]]],[A[75],1,[0],[[]]],[A[771],1,[],[]],[A[772],1,[],[]],[A[773],2,[],[]],[A[171],1,[],[]],[A[774],1,[],[]],[A[775],1,[],[]],[A[776],1,[],[]],[A[777],5,[],[]],[A[778],7,[1,2,3,4,5,6],[[2],[],[],[],[],[]]],[A[779],5,[1,2,3],[[2],[],[4]]],[A[780],9,[1,4,6,7,8],[[2],[5],[7],[],[]]],[A[3],1,[],[]],[A[24],1,[0],[[]]],[A[781],1,[0],[[]]],[A[782],1,[0],[[]]],[A[200],3,[1,2],[[],[]]],[A[201],1,[],[]],[A[783],1,[0],[[]]],[A[784],1,[],[]],[A[122],1,[0],[[]]],[A[785],2,[0],[[]]],[A[786],4,[1,2],[[],[3]]],[A[787],1,[],[]],[A[3],1,[],[]],[A[788],4,[1,3],[[2],[]]],[A[95],1,[],[]],[A[217],1,[0],[[]]],[A[789],2,[],[]],[A[790],2,[],[]],[A[540],2,[1],[[]]],[A[245],1,[0],[[]]],[A[791],1,[],[]],[A[792],3,[0,1],[[],[2]]],[A[217],1,[0],[[]]],[A[793],1,[],[]],[A[794],1,[0],[[]]],[A[795],2,[],[]],[A[796],2,[],[]],[A[797],2,[],[]],[A[798],1,[],[]],[A[799],1,[],[]],[A[800],1,[],[]],[A[801],2,[],[]],[A[802],11,[],[]],[A[16],1,[0],[[]]],[A[24],1,[0],[[]]],[A[803],16,[1,3,6,8,11,15],[[2],[5],[7],[15],[12,14,15],[]]],[A[804],3,[1],[[2]]],[A[805],3,[1],[[2]]],[A[806],3,[1],[[2]]],[A[807],2,[],[]],[A[808],2,[],[]],[A[809],2,[],[]],[A[810],2,[],[]],[A[811],2,[],[]],[A[817],8,[1,4],[[2],[7]]],[A[818],8,[1,4],[[2],[7]]],[A[818],8,[1,4],[[2],[7]]],[A[819],8,[1,4],[[2],[7]]],[A[820],8,[1,4],[[2],[7]]],[A[820],8,[1,4],[[2],[7]]],[A[819],8,[1,4],[[2],[7]]],[A[820],8,[1,4],[[2],[7]]],[A[820],8,[1,4],[[2],[7]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[75],1,[],[]],[A[82],1,[0],[[]]],[A[822],1,[],[]],[A[823],3,[1],[[2]]],[A[824],3,[0,1],[[],[2]]],[A[825],3,[0,1],[[],[2]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[16],1,[0],[[]]],[A[141],1,[],[]],[A[826],3,[0,1],[[],[2]]],[A[82],1,[0],[[]]],[A[827],3,[0,1],[[],[2]]],[A[828],1,[],[]],[A[292],1,[],[]],[A[829],4,[1,3],[[2],[]]],[A[129],1,[],[]],[A[90],2,[],[]],[A[830],2,[1],[[]]],[A[831],1,[],[]],[A[117],1,[],[]],[A[832],1,[],[]],[A[833],3,[0,1],[[],[2]]],[A[24],1,[0],[[]]],[A[834],204,[1,3],[[2],[203]]],[A[835],9,[1,3,8],[[2],[7],[]]],[A[836],9,[1,3,8],[[2],[7],[]]],[A[836],9,[1,3,8],[[2],[7],[]]],[A[837],8,[-1,2,7],[[],[6],[]]],[A[838],6,[1,5],[[4],[]]],[A[1],2,[1],[[]]],[A[839],1,[0],[[]]],[A[84],1,[0],[[]]],[A[82],1,[0],[[]]],[A[292],1,[],[]],[A[75],1,[],[]],[A[840],5,[1,3],[[2],[4]]],[A[841],5,[1,2],[[],[4]]],[A[183],2,[],[]],[A[842],3,[1],[[2]]],[A[82],1,[],[]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[843],1,[],[]],[A[844],4,[1,3],[[2],[]]],[A[149],4,[1,2,3],[[],[],[]]],[A[150],3,[1,-1,2],[[],[],[]]],[A[845],3,[1],[[2]]],[A[846],2,[],[]],[A[847],2,[],[]],[A[848],2,[],[]],[A[849],2,[],[]],[A[851],6,[],[]],[A[852],6,[],[]],[A[853],3,[],[]],[A[855],3,[],[]],[A[856],2,[],[]],[A[857],2,[],[]],[A[858],2,[],[]],[A[859],3,[1],[[2]]],[A[860],4,[1,2],[[3],[3]]],[A[861],2,[],[]],[A[862],2,[],[]],[A[863],2,[],[]],[A[864],3,[1],[[2]]],[A[865],1,[],[]],[A[866],1,[],[]],[A[867],1,[],[]],[A[273],1,[],[]],[A[868],3,[1],[[2]]],[A[869],3,[1],[[2]]],[A[870],3,[1],[[2]]],[A[871],3,[1],[[2]]],[A[872],3,[1],[[2]]],[A[873],3,[1],[[2]]],[A[874],1,[],[]],[A[875],1,[],[]],[A[876],2,[1],[[]]],[A[877],1,[],[]],[A[878],1,[],[]],[A[879],2,[1],[[]]],[A[880],3,[1],[[2]]],[A[881],3,[1],[[2]]],[A[882],2,[],[]],[A[182],2,[],[]],[A[883],6,[1,3,4],[[2],[5],[5]]],[A[383],2,[1],[[]]],[A[884],4,[1,2,3],[[2],[],[]]],[A[885],4,[1,2,3],[[2],[],[]]],[A[540],2,[1],[[]]],[A[360],1,[0],[[]]],[A[886],1,[],[]],[A[379],1,[0],[[]]],[A[65],1,[0],[[]]],[A[65],1,[0],[[]]],[A[82],1,[0],[[]]],[A[887],7,[],[]],[A[888],5,[],[]],[A[889],4,[],[]],[A[890],3,[],[]],[A[891],2,[1],[[]]],[A[146],2,[1],[[]]],[A[23],1,[0],[[]]],[A[892],1,[0],[[]]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[893],1,[0],[[]]],[A[894],2,[],[]],[A[895],1,[],[]],[A[67],1,[],[]],[A[67],1,[],[]],[A[896],5,[0,1,3],[[],[2],[4]]],[A[579],3,[1],[[2]]],[A[845],3,[1],[[2]]],[A[217],1,[0],[[]]],[A[897],2,[],[]],[A[898],1,[],[]],[A[899],1,[],[]],[A[226],1,[],[]],[A[217],1,[0],[[]]],[A[900],4,[1,2],[[],[3]]],[A[901],2,[],[]],[A[902],1,[],[]],[A[903],10,[],[]],[A[904],4,[0],[[]]],[A[390],2,[],[]],[A[389],5,[1,4],[[2],[]]],[A[392],1,[0],[[]]],[A[393],1,[],[]],[A[82],1,[0],[[]]],[A[905],1,[],[]],[A[906],1,[],[]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[141],1,[],[]],[A[907],3,[1],[[2]]],[A[77],1,[],[]],[A[908],1,[0],[[]]],[A[909],1,[],[]],[A[69],1,[],[]],[A[70],1,[],[]],[A[910],2,[1],[[]]],[A[911],2,[1],[[]]],[A[182],2,[1],[[]]],[A[912],3,[1],[[2]]],[A[24],1,[0],[[]]],[A[203],1,[0],[[]]],[A[913],1,[],[]],[A[914],1,[],[]],[A[328],2,[1],[[]]],[A[3],1,[],[]],[A[915],3,[0],[[]]],[A[535],5,[1,3],[[2],[4]]],[A[82],1,[0],[[]]],[A[841],5,[1,2],[[],[4]]],[A[916],2,[],[]],[A[826],3,[0,1],[[],[2]]],[A[82],1,[0],[[]]],[A[82],1,[0],[[]]],[A[917],1,[],[]],[A[918],5,[1,4],[[2],[]]],[A[146],2,[1],[[]]],[A[919],1,[],[]],[A[182],2,[1],[[]]],[A[920],1,[],[]],[A[921],3,[],[]],[A[922],2,[],[]],[A[923],2,[],[]],[A[924],3,[],[]],[A[925],4,[],[]],[A[926],5,[],[]],[A[927],3,[],[]],[A[928],2,[],[]],[A[929],2,[],[]],[A[930],3,[],[]],[A[931],2,[],[]],[A[932],3,[],[]],[A[933],2,[],[]],[A[82],1,[],[]],[A[934],2,[1],[[]]],[A[935],2,[],[]],[A[75],1,[0],[[]]],[A[446],2,[],[]],[A[22],1,[0],[[]]],[A[936],1,[],[]],[A[146],2,[1],[[]]],[A[937],16,[],[]],[A[938],4,[],[]],[A[939],1,[],[]],[A[16],1,[0],[[]]],[A[361],2,[1],[[]]],[A[77],1,[0],[[]]],[A[16],1,[0],[[]]],[A[23],1,[0],[[]]],[A[940],1,[],[]],[A[95],1,[],[]],[A[82],1,[0],[[]]],[A[941],10,[1,2,4,5,6,8,9],[[3],[3],[5,7],[7],[7],[9],[]]],[A[24],1,[0],[[]]],[A[942],1,[],[]],[A[944],6,[1,3,4],[[2],[5],[5]]],[A[945],3,[1,2],[[2],[]]],[A[946],3,[1,2],[[2],[]]],[A[947],3,[1,2],[[2],[]]],[A[948],3,[1,2],[[2],[]]],[A[949],3,[1,2],[[2],[]]],[A[950],3,[1,2],[[2],[]]],[A[951],3,[1,2],[[2],[]]],[A[952],3,[1,2],[[2],[]]],[A[953],3,[1,2],[[2],[]]],[A[954],3,[1,2],[[2],[]]],[A[955],4,[1],[[2]]],[A[956],4,[1],[[2]]],[A[306],2,[1],[[]]],[A[957],2,[1],[[]]],[A[305],4,[1,2],[[],[3]]],[A[306],2,[1,-1],[[],[]]],[A[789],2,[],[]],[A[790],2,[],[]],[A[540],2,[1],[[]]],[A[958],3,[1],[[2]]],[A[939],1,[],[]],[A[959],1,[0],[[]]],[A[960],1,[0],[[]]],[A[23],1,[0],[[]]],[A[961],1,[0],[[]]],[A[962],2,[],[]],[A[963],2,[],[]],[A[964],2,[],[]],[A[965],2,[],[]],[A[966],2,[],[]],[A[967],2,[],[]],[A[968],1,[],[]],[A[969],2,[],[]],[A[970],2,[],[]],[A[971],2,[],[]],[A[972],2,[],[]],[A[974],5,[1,4],[[3],[]]],[A[975],5,[1,4],[[3],[]]],[A[974],5,[1,4],[[3],[]]],[A[975],5,[1,4],[[3],[]]],[A[4],1,[],[]],[A[976],1,[0],[[]]],[A[977],2,[],[]],[A[978],1,[],[]],[A[203],1,[0],[[]]],[A[66],1,[],[]],[A[82],1,[],[]],[A[24],1,[],[]],[A[232],1,[],[]],[A[15],1,[],[]],[A[77],1,[0],[[]]],[A[979],2,[],[]],[A[3],1,[],[]],[A[65],1,[],[]],[A[86],1,[],[]],[A[1],2,[1],[[]]],[A[980],6,[1,3,5],[[2],[4],[]]],[A[981],6,[1,2,3,5],[[2],[],[4],[]]],[A[982],8,[1,2,3,7],[[2],[],[4],[]]],[A[983],4,[1,2],[[2],[]]],[A[77],1,[0],[[]]],[A[984],11,[1,3,5,6,8,9],[[2],[],[],[7],[],[10]]],[A[985],13,[1,3,4,5,7,8,10,11],[[2],[],[6],[6],[9],[9],[12],[12]]],[A[986],2,[],[]],[A[987],2,[],[]],[A[988],1,[],[]],[A[990],2,[],[]],[A[991],2,[],[]],[A[992],2,[],[]],[A[993],1,[],[]],[A[994],2,[],[]],[A[995],3,[],[]],[A[996],2,[],[]],[A[997],3,[1],[[2]]],[A[998],3,[1],[[2]]],[A[999],3,[1],[[2]]],[A[1000],3,[1],[[2]]],[A[1001],3,[1],[[2]]],[A[1002],3,[1],[[2]]],[A[1003],3,[],[]],[A[1004],1,[],[]],[A[1005],10,[1,3,9],[[2],[8],[]]],[A[1006],9,[1,3],[[2],[8]]],[A[1007],9,[1,4],[[2],[]]],[A[1008],8,[],[]],[A[1009],1,[0],[[]]],[A[1010],1,[0],[[]]],[A[1011],1,[],[]],[A[24],1,[0],[[]]],[A[16],1,[0],[[]]],[A[23],1,[0],[[]]],[A[1012],1,[0],[[]]],[A[1013],1,[0],[[]]],[A[1014],1,[0],[[]]],[A[1015],1,[0],[[]]],[A[1016],2,[0],[[]]],[A[1028],4,[1,2],[[3],[3]]],[A[1029],4,[1,2],[[3],[3]]],[A[1029],4,[1,2],[[3],[3]]],[A[1030],4,[1,2],[[3],[3]]],[A[228],1,[0],[[]]],[A[1031],1,[0],[[]]],[A[1032],1,[0],[[]]],[A[1033],1,[0],[[]]],[A[1034],2,[0],[[]]],[A[1035],1,[0],[[]]],[A[1036],1,[0],[[]]],[A[1037],1,[0],[[]]],[A[1038],1,[0],[[]]],[A[1039],2,[0],[[]]],[A[1040],2,[0],[[]]],[A[1041],1,[0],[[]]],[A[1042],1,[0],[[]]],[A[1043],1,[0],[[]]],[A[1044],1,[0],[[]]],[A[1045],2,[0],[[]]],[A[1046],5,[1],[[2]]],[A[1047],5,[3],[[4]]],[A[1048],1,[0],[[]]],[A[1049],3,[1],[[2]]],[A[1050],4,[],[]],[A[1051],1,[0],[[]]],[A[1052],4,[0],[[]]],[A[1053],2,[0],[[]]],[A[1054],2,[0],[[]]],[A[1055],4,[0],[[]]],[A[1056],3,[0],[[]]],[A[1057],4,[0],[[]]],[A[1058],3,[0],[[]]],[A[1059],3,[0],[[]]],[A[1060],3,[0],[[]]],[A[1061],3,[0],[[]]],[A[830],2,[1],[[]]],[A[263],1,[],[]],[A[1064],1,[],[]],[A[1066],1,[],[]],[A[1067],1,[],[]],[A[1068],1,[],[]],[A[1069],1,[],[]],[A[1070],2,[],[]],[A[273],1,[],[]],[A[1071],1,[],[]],[A[116],1,[],[]],[A[265],1,[],[]],[A[117],1,[],[]],[A[1072],1,[],[]],[A[500],1,[],[]],[A[502],1,[],[]],[A[501],1,[],[]]];
+var H={487:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[0],["a.b.c"],[0,0],N,"",L))){break ifs;}}return J;}}),509:({scopes:"d.e.f.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1],["h.i.e.j.g"],[0,0],N,"d.e.f.g",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),21:({scopes:"k.l.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[2],["h.i.k.j.m"],[0,0],N,"k.l.m",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[3],[],[],N,"n.o.p.m",L))){break ifs;}}return J;}}),356:({scopes:"q.r.s.t",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[4],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[344].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),423:({scopes:"u.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[5],["h.i.e.v","w.x.e.v"],[0,0,1,1],N,"d.e.s.v",L))){M.push(424);O.push(" d.e.s.v");
+break ifs;}if((J=E(Q,P,B[6],["h.i.e.v","w.x.e.z.v"],[0,0,1,1],N,"d.e.y.z.v",L))){M.push(426);O.push(" d.e.y.z.v");
+break ifs;}if((J=E(Q,P,B[7],["h.i.q.v"],[0,0],N,"q.r.v",L))){M.push(427);O.push(" q.r.v");break ifs;}if((J=E(Q,P,B[8],["h.i.e.v","w.x.e.bb.v","w.x.e.v","h.bc.bb.v","w.x.e.bd.v"],[0,0,1,1,2,3,3,2,4,4],N,"d.e.ba.v",L))){M.push(428);
+O.push(" d.e.ba.v");break ifs;}if((J=E(Q,P,B[9],["h.i.e.v","w.x.e.bb.v","w.x.e.v","h.bc.bb.v","w.x.e.bd.v"],[0,0,1,1,2,3,3,2,4,4],N,"d.e.v",L))){M.push(429);
+O.push(" d.e.v");break ifs;}if((J=E(Q,P,B[10],["h.i.n.v","h.i.n.v"],[0,0,1,1],N,"n.o.w.v",L))){break ifs;
+}if((J=E(Q,P,B[11],[],[],N,"be.bf.bg.v",L))){break ifs;}if((J=E(Q,P,B[12],["h.bk.bj.bl.v"],[0,0],N,"bh.bi.bj.v",L))){M.push(430);
+O.push(" bh.bi.bj.v");break ifs;}if((J=E(Q,P,B[13],["h.bk.bj.bl.v"],[0,0],N,"bh.c.bj.v",L))){M.push(431);
+O.push(" bh.c.bj.v");break ifs;}if((J=E(Q,P,B[14],["h.i.k.bl.v"],[0,0],N,"k.bm.bn.v",L))){M.push(432);
+O.push(" k.bm.bn.v");break ifs;}}return J;}}),244:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[15],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(243);O.push("");break ifs;
+}}return J;}}),65:({scopes:"k.bq.br.bs.bt bh.bs.bj.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[16],["h.i.k.j.bt"],[0,0],N,"k.bq.br.bs.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[17],[],[],N,"q.bu.bv.bs",L))){break ifs;}if((J=E(Q,P,B[18],[],[],N,"q.bu.bw.bs",L))){break ifs;
+}if((J=E(Q,P,B[19],[],[],N,"k.bq.bx.by.bs",L))){M.push(59);O.push(" k.bq.bx.by.bs");break ifs;}if((J=E(Q,P,B[20],[],[],N,"k.bq.f.bz.by.bs",L))){M.push(60);
+O.push(" k.bq.f.bz.by.bs");break ifs;}if((J=E(Q,P,B[21],[],[],N,"k.bq.br.by.bs",L))){M.push(61);O.push(" k.bq.br.by.bs");
+break ifs;}if((J=E(Q,P,B[22],["n.o.p.bt"],[0,0],N,"k.bq.br.bs",L))){M.push(62);O.push(" k.bq.br.bs");
+break ifs;}if((J=E(Q,P,B[23],[],[],N,"k.bq.f.bz.bs",L))){M.push(63);O.push(" k.bq.f.bz.bs");break ifs;
+}if((J=E(Q,P,B[24],[],[],N,"k.bq.bx.bs",L))){M.push(64);O.push(" k.bq.bx.bs");break ifs;}if((J=E(Q,P,B[25],[],[],N,"n.o.p.bt",L))){break ifs;
+}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),293:({scopes:"k.bm.ca.cb.cc.cd u.g.cc.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[26],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.cc.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if(false){break ifs;}}return J;}}),130:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[27],[],[],N,"",L))){M.push(129);O.push("");break ifs;}}return J;}}),350:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[28],["d.s.ch","ce.cf.ci.cj.ch"],[0,1,1,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[29],["d.s.ch","ce.cf.ci.ck.ch"],[0,1,1,0],N,"",L))){M.push(348);
+O.push("");break ifs;}if((J=E(Q,P,B[30],[],[],N,"q.r.s.cl",L))){M.push(349);O.push(" q.r.s.cl");break ifs;
+}}return J;}}),124:({scopes:"q.r.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[31]:null),[],[],N,"q.r.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[159].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),190:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[32],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),417:({scopes:"d.co.cp.cq.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[33],["ce.cf.cr"],[0,0],N,"d.co.cp.cq.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),354:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[34],["d.s.ch","ce.cf.ci.cj.ch"],[0,1,1,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[35],["d.s.ch","ce.cf.ci.ck.ch"],[0,1,1,0],N,"",L))){M.push(352);
+O.push("");break ifs;}if((J=E(Q,P,B[36],[],[],N,"q.r.s.cl.cs",L))){M.push(353);O.push(" q.r.s.cl.cs");
+break ifs;}}return J;}}),256:({scopes:"bh.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[258].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[37],["ce.f.ct.bs","ce.f.bs","w.x.cu.bs"],[0,0,1,1,2,2],N,"d.ct.bs",L))){break ifs;
+}if((J=E(Q,P,B[38],["ce.f.ct.bs","ce.f.bs"],[0,0,1,1],N,"d.cv.bs",L))){break ifs;}if((J=E(Q,P,B[39],["ce.f.ct.bs","ce.f.cw.bs","w.x.cu.bs","ce.f.cx.bs"],[0,0,1,1,2,2,3,3],N,"d.cv.bs",L))){break ifs;
+}if((J=E(Q,P,B[40],["ce.f.ct.bs","ce.f.cw.bs"],[0,0,1,1],N,"d.cy.bs",L))){break ifs;}if((J=E(Q,P,B[41],["a.cz.bs","a.cz.bs","n.da.bs","a.cz.bs","n.da.bs","a.cz.bs","n.da.bs","n.da.bs","a.cz.bs","n.da.bs","a.cz.bs","a.cz.bs","a.cz.bs","n.da.bs","a.cz.bs"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14],N,"",L))){break ifs;
+}if((J=E(Q,P,B[42],[],[],N,"a.b.bs",L))){break ifs;}if((J=E(Q,P,B[43],[],[],N,"n.da.bs",L))){break ifs;
+}if((J=E(Q,P,B[44],[],[],N,"ce.f.db.bs",L))){break ifs;}if((J=E(Q,P,B[45],[],[],N,"ce.f.dc.ct.dd.bs",L))){break ifs;
+}if((J=E(Q,P,B[46],[],[],N,"ce.f.db.dd.bs",L))){break ifs;}if((J=E(Q,P,B[47],[],[],N,"ce.f.de.bs",L))){break ifs;
+}if((J=E(Q,P,B[48],[],[],N,"ce.f.df.bs",L))){break ifs;}if((J=E(Q,P,B[49],[],[],N,"ce.f.dg.bs",L))){break ifs;
+}if((J=E(Q,P,B[50],[],[],N,"ce.f.dh.bs",L))){break ifs;}if((J=E(Q,P,B[51],[],[],N,"ce.f.di.bs",L))){break ifs;
+}if((J=E(Q,P,B[52],[],[],N,"ce.f.dj.bs",L))){break ifs;}if((J=E(Q,P,B[53],[],[],N,"ce.dk.dl.bs",L))){break ifs;
+}if((J=E(Q,P,B[54],[],[],N,"ce.dk.dm.bs",L))){break ifs;}if((J=E(Q,P,B[55],[],[],N,"ce.dk.dn.bs",L))){break ifs;
+}if((J=E(Q,P,B[56],[],[],N,"ce.dk.do.bs",L))){break ifs;}if((J=E(Q,P,B[57],[],[],N,"dp.cu.dq.bs",L))){break ifs;
+}if((J=E(Q,P,B[58],[],[],N,"dp.cu.dr.bs",L))){break ifs;}if((J=E(Q,P,B[59],[],[],N,"dp.cu.k.bs",L))){break ifs;
+}if((J=E(Q,P,B[60],["n.f.ds.bs","n.f.dt.bs"],[0,0,1,1],N,"",L))){break ifs;}if((J=H[268].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[261].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),313:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[61],["ce.cf.cd"],[0,0],N,"d.bo.du.cd",L))){M.push(306);O.push(" d.bo.du.cd");
+break ifs;}if((J=E(Q,P,B[62],["ce.cf.cd","dw.f.dx.cd"],[0,0,1,1],N,"d.bo.dv.cd",L))){M.push(307);O.push(" d.bo.dv.cd");
+break ifs;}if((J=E(Q,P,B[63],["ce.cf.cd"],[0,0],N,"d.bo.dy.cd",L))){M.push(308);O.push(" d.bo.dy.cd");
+break ifs;}if((J=E(Q,P,B[64],["ce.cf.cd","dw.f.dx.cd"],[0,0,1,1],N,"d.bo.dz.cd",L))){M.push(309);O.push(" d.bo.dz.cd");
+break ifs;}if((J=E(Q,P,B[65],["ce.cf.cd"],[0,0],N,"d.bo.ea.cd",L))){M.push(311);O.push(" d.bo.ea.cd");
+break ifs;}if((J=E(Q,P,B[66],["ce.cf.cd"],[0,0],N,"d.bo.eb.cd",L))){M.push(312);O.push(" d.bo.eb.cd");
+break ifs;}}return J;}}),518:({scopes:"bh.bp.ec.bj.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[67],["h.bk.bj.bp.ec"],[0,0],N,"bh.bp.ec.bj.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[68],["h.i.q.bp.ec"],[0,0],N,"q.bu.bv.bp.ec",L))){break ifs;}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),389:({scopes:"q.r.l",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[69],[],[],N,"q.r.l",(function(){(L&&L());M.pop();O.pop();})))){}}return J;
+}}),250:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[70],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(249);O.push("");break ifs;
+}}return J;}}),128:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[71],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[121].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[122].go(Q,P,K,M,O,L))){break ifs;}if((J=H[120].go(Q,P,K,M,O,L))){break ifs;}if((J=H[137].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[142].go(Q,P,K,M,O,L))){break ifs;}if((J=H[143].go(Q,P,K,M,O,L))){break ifs;}if((J=H[140].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[136].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),511:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[72],["h.i.w.g","h.i.w.g"],[0,0,1,1],N,"n.o.w.g",L))){break ifs;}if((J=E(Q,P,B[73],[],[],N,"be.bf.bg.g",L))){break ifs;
+}}return J;}}),61:({scopes:"k.bq.br.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[74],[],[],N,"k.bq.br.by.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[75],[],[],N,"n.o.p.bt",L))){break ifs;
+}}return J;}}),264:({scopes:"k.bq.bx.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[76],["h.i.k.j.bs"],[0,0],N,"k.bq.bx.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[262].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),380:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[77],["w.x.cu.ee","h.i.ef.ch"],[0,0,1,1],N,"d.cu.ed.ee",L))){M.push(378);
+O.push(" d.cu.ed.ee");break ifs;}if((J=E(Q,P,B[78],["h.i.ef.ch"],[0,0],N,"d.cu.ed.eg.ee",L))){M.push(379);
+O.push(" d.cu.ed.eg.ee");break ifs;}}return J;}}),242:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[79],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(241);O.push("");break ifs;
+}}return J;}}),413:({scopes:"d.co.cp.eh.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[80],["ce.cf.cr"],[0,0],N,"d.co.cp.eh.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[422].go(Q,P,K,M,O,L))){break ifs;}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),489:({scopes:"k.bq.bx.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[81],["h.i.k.j.c"],[0,0],N,"k.bq.bx.c",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[82],[],[],N,"n.o.p.c",L))){break ifs;}}return J;}}),126:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[83],[],[],N,"q.r.cm",L))){M.push(124);O.push(" q.r.cm");break ifs;}if((J=E(Q,P,B[84],[],[],N,"q.r.cm",L))){M.push(125);
+O.push(" q.r.cm");break ifs;}}return J;}}),425:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[85],["h.i.e.v"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[434].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[436].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),198:({scopes:"k.bq.f.ei.ej.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[86],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.ej.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[230].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),262:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[87],[],[],N,"n.o.p.bs",L))){break ifs;}}return J;}}),352:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[88],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[342].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),132:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[142].go(Q,P,K,M,O,L))){break ifs;}if((J=H[137].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[136].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),141:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[89],["h.bc.ek.bu.cm","be.bf.el.cm"],[0,0,1,1],N,"",L))){break ifs;}}return J;
+}}),204:({scopes:"k.bq.f.ei.em.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[90],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.em.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[91],[],[],N,"n.o.p.bp",L))){break ifs;}if((J=H[242].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),254:({scopes:"k.l.en.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[92],["h.i.en.bp"],[0,0],N,"k.l.en.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),364:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[93],["d.s.ch","ce.cf.ci.ch"],[0,1,1,0],N,"",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),147:({scopes:"k.bq.br.r.eo.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[94]:B[95]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.eo.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),376:({scopes:"d.r.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[96],[],[],N,"d.r.ee",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[97],["dp.cu.er.ch","h.i.ef.ch"],[0,0,1,1],N,"d.eq.ch",L))){break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),461:({scopes:"q.r.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[98],["h.i.q.c"],[0,0],N,"q.r.c",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),202:({scopes:"k.bq.f.ei.f.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[99],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.f.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),44:({scopes:"q.r.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[100],["h.i.q.bt"],[0,0],N,"q.r.bt",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),67:({scopes:"k.bq.bx.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[101],[],[],N,"k.bq.bx.by.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[102],[],[],N,"n.o.p.bt",L))){break ifs;
+}}return J;}}),107:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[103],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[130].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),301:({scopes:"k.cn.es.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[104],["h.i.k.j.cd"],[0,0],N,"k.cn.es.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),200:({scopes:"k.bq.br.bp.et",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[105],["h.i.k.j.bp"],[0,0],N,"k.bq.br.bp.et",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[238].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),42:({scopes:"d.cu.eu.ev.bt d.ev.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[106],["h.i.ev.j.bt"],[0,0],N,"d.cu.eu.ev.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[79].go(Q,P,K,M,O,L))){break ifs;}if((J=H[48].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),291:({scopes:"k.bm.ca.cb.ew.cd u.g.ew.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[107],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.ew.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if(false){break ifs;}}return J;}}),120:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[108],[],[],N,"dp.cz.ex.cm",L))){break ifs;}}return J;}}),419:({scopes:"d.co.cq.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[109],["ce.cf.cr"],[0,0],N,"d.co.cq.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),15:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[110],["h.i.k.bl.ey"],[0,0],N,"k.bq.bx.ey",L))){M.push(14);O.push(" k.bq.bx.ey");
+break ifs;}}return J;}}),329:({scopes:"q.bu.ez.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[111],[],[],N,"q.bu.ez.ee",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[112],[],[],N,"h.bc.ek.ee",L))){break ifs;
+}}return J;}}),118:({scopes:"d.fa.fb.fc.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[113],["h.bc.fb.cm"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),362:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[114],["d.s.ch","ce.cf.ci.cj.ch"],[0,1,1,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[115],["d.s.ch","ce.cf.ci.ck.ch"],[0,1,1,0],N,"",L))){M.push(360);
+O.push(" q.r.s.t.cs");break ifs;}if((J=E(Q,P,B[116],[],[],N,"",L))){M.push(361);O.push("");break ifs;
+}}return J;}}),260:({scopes:"k.l.fd.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[117],["h.i.k.j.bs"],[0,0],N,"k.l.fd.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[263].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),305:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[118],[],[],N,"ce.dk.fe.cd",L))){break ifs;}if((J=E(Q,P,B[119],[],[],N,"ce.dk.fe.cd",L))){break ifs;
+}}return J;}}),149:({scopes:"k.bq.br.r.ff.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[120]:B[121]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.ff.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),38:({scopes:"d.fg.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[122],[],[],N,"d.fg.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[123],[],[],N,"w.f.fh.bt",L))){break ifs;
+}}return J;}}),166:({scopes:"k.bq.bx.fi.fj.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[124],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.fj.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),309:({scopes:"d.bo.dz.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[125],["ce.cf.cd"],[0,0],N,"d.bo.dz.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),340:({scopes:"d.r.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[126],[],[],N,"d.r.ch",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[342].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),196:({scopes:"k.l.fl.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[127],["h.i.k.j.bp"],[0,0],N,"k.l.fl.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),246:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[128],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(245);O.push("");break ifs;
+}}return J;}}),484:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[129],[],[],N,"",L))){M.push(483);O.push("");break ifs;}}return J;}}),105:({scopes:"d.cu.fm.cm w.x.cu.fm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[130],[],[],N,"d.cu.fm.cm",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[131],["h.i.fm.cm"],[0,0],N,"",L))){M.push(104);
+O.push("");break ifs;}}return J;}}),407:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[132],[],[],N,"dp.fn.fo.fp.cr",L))){break ifs;}if((J=E(Q,P,B[133],[],[],N,"dp.fn.fo.fq.cr",L))){break ifs;
+}if((J=E(Q,P,B[134],[],[],N,"dp.fn.fo.fr.cr",L))){break ifs;}if((J=E(Q,P,B[135],[],[],N,"dp.cu.fo.fp.cr",L))){break ifs;
+}if((J=E(Q,P,B[136],[],[],N,"dp.n.fo.cr",L))){break ifs;}if((J=E(Q,P,B[137],[],[],N,"dp.dw.fo.cr",L))){break ifs;
+}}return J;}}),52:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[138],[],[],N,"be.bf.fs.ft.bt",L))){break ifs;}if((J=E(Q,P,B[139],["ce.f.ft.bt","a.b.bt","be.bf.fu.ft.bt"],[0,0,1,1,2,2],N,"",L))){break ifs;
+}if((J=E(Q,P,B[140],[],[],N,"fv.fw.fx.bt",L))){break ifs;}if((J=E(Q,P,B[141],["ce.f.ft.bt","fv.fw.fx.bt"],[0,0,1,1],N,"",L))){break ifs;
+}if((J=E(Q,P,B[142],[],[],N,"ce.f.ft.bt",L))){break ifs;}if((J=E(Q,P,B[143],["ce.f.ft.bt"],[0,0],N,"d.e.fy.ft.bt",L))){break ifs;
+}}return J;}}),403:({scopes:"d.fz.ev.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[144],["h.bk.ev.cr"],[0,0],N,"d.fz.ev.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[145],["n.f.ga.cr","d.gb.cr","h.i.gb.cr","h.i.gb.cr","h.bc.gc.cr"],[0,1,2,2,3,3,1,0,4,4],N,"",L))){break ifs;
+}if((J=E(Q,P,B[146],[],[],N,"h.bc.gc.cr",L))){break ifs;}if((J=E(Q,P,B[147],[],[],N,"h.bc.ev.cr",L))){break ifs;
+}if((J=H[408].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),289:({scopes:"k.bm.ca.cb.g.cd u.g.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[148],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.g.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[494].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),441:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[149],["a.cz.ge.c","h.i.gf.bl.c"],[0,0,1,1],N,"d.gd.ge.c",L))){M.push(440);
+O.push(" d.gd.ge.c");break ifs;}if((J=E(Q,P,B[150],[],[],N,"a.cz.ge.c",L))){break ifs;}}return J;}}),493:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[490].go(Q,P,K,M,O,L))){break ifs;}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[463].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),482:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[151],[],[],N,"a.b.c",L))){break ifs;}if((J=H[485].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[486].go(Q,P,K,M,O,L))){break ifs;}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[152],[],[],N,"dw.gg.c",L))){break ifs;
+}}return J;}}),513:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[153],[],[],N,"",L))){M.push(512);O.push("");break ifs;}}return J;}}),139:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[154],["dw.gg.cu.cm","ce.dk.gh.cm"],[0,0,1,1],N,"",L))){M.push(138);O.push("");
+break ifs;}}return J;}}),266:({scopes:"k.bq.br.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[155],["h.i.k.j.bs"],[0,0],N,"k.bq.br.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[263].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),338:({scopes:"d.cu.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[125],(P-1))?B[156]:B[157]),[],[],N,"d.cu.ch",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[346].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[158],[],[],N,"a.b.ch",L))){break ifs;
+}if((J=H[341].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),439:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[485].go(Q,P,K,M,O,L))){break ifs;}if((J=H[486].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),378:({scopes:"d.cu.ed.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[159],["h.i.ef.ch"],[0,0],N,"d.cu.ed.ee",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),524:({scopes:"k.bq.bx.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[160],["h.i.k.j.g"],[0,0],N,"k.bq.bx.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;}if((J=H[511].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),50:({scopes:"d.ev.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[161],["h.i.ev.j.bt"],[0,0],N,"d.ev.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[51].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),336:({scopes:"d.s.ch.gi",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[162],[],[],N,"d.s.ch.gi",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[163],[],[],N,"h.bc.ek.ch",L))){break ifs;
+}if((J=E(Q,P,B[164],["h.i.k.bl.ch"],[0,0],N,"k.bq.br.gi.ch",L))){M.push(334);O.push(" k.bq.br.gi.ch");
+break ifs;}if((J=E(Q,P,B[165],["h.i.k.bl.ch"],[0,0],N,"k.bq.f.gj.gi.ch",L))){M.push(335);O.push(" k.bq.f.gj.gi.ch");
+break ifs;}}return J;}}),82:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[166],["h.i.dw.bt"],[0,0],N,"dw.f.bt",L))){break ifs;}}return J;}}),208:({scopes:"q.r.gk.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[167],["h.i.q.bp"],[0,0],N,"q.r.gk.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),311:({scopes:"d.bo.ea.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[168],["ce.cf.cd"],[0,0],N,"d.bo.ea.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[169],[],[],N,"d.bo.gl.cd",L))){M.push(310);O.push(" d.bo.gl.cd");break ifs;
+}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),252:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[170],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(251);O.push("");break ifs;
+}}return J;}}),168:({scopes:"k.bq.bx.fi.gm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[171],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.gm.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),399:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[172],["ce.cf.gn.cr","w.x.cz.go.cr"],[0,0,1,1],N,"d.gn.cr",L))){M.push(396);
+O.push(" d.gn.cr");break ifs;}if((J=E(Q,P,B[173],["ce.cf.gq.cr","w.x.cu.gr.cr","h.i.ef.cr","dw.gg.gr.cr","h.i.ef.cr"],[0,0,1,1,2,2,3,3,4,4],N,"d.cu.gp.cr",L))){M.push(397);
+O.push(" d.cu.gp.cr");break ifs;}if((J=E(Q,P,B[174],["ce.cf.gq.cr","w.x.cu.gr.cr"],[0,0,1,1],N,"d.cu.gs.cr",L))){M.push(398);
+O.push(" d.cu.gs.cr");break ifs;}if((J=H[421].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),40:({scopes:"d.fn.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[175],[],[],N,"d.fn.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[176],["a.b.gt.bt","w.f.fh.bt"],[0,0,1,1],N,"",L))){break ifs;
+}if((J=E(Q,P,B[177],["a.b.gu.bt","dp.fn.gu.bt"],[0,0,1,1],N,"",L))){M.push(39);O.push("");break ifs;}}return J;
+}}),186:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[178],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[238].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),401:({scopes:"q.r.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[179],["h.i.q.cr"],[0,0],N,"q.r.cr",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),495:({scopes:"d.e.gv.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[180],["h.i.e.g","d.bo.gw.g","w.x.e.g","h.i.e.g"],[0,1,1,0,2,2,3,3],N,"d.e.gv.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),443:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[181],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),268:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[182],["h.i.k.bl.bs"],[0,0],N,"k.bq.bx.bs",L))){break ifs;}if((J=E(Q,P,B[183],["h.i.k.bl.bs"],[0,0],N,"k.bq.bx.bs",L))){M.push(264);
+O.push(" k.bq.bx.bs");break ifs;}if((J=E(Q,P,B[184],["h.i.k.bl.bs"],[0,0],N,"k.bq.f.bz.bs",L))){break ifs;
+}if((J=E(Q,P,B[185],["h.i.k.bl.bs"],[0,0],N,"k.bq.f.bz.bs",L))){M.push(265);O.push(" k.bq.f.bz.bs");break ifs;
+}if((J=E(Q,P,B[186],["h.i.k.bl.bs"],[0,0],N,"k.bq.br.bs",L))){break ifs;}if((J=E(Q,P,B[187],["h.i.k.bl.bs"],[0,0],N,"k.bq.br.bs",L))){M.push(266);
+O.push(" k.bq.br.bs");break ifs;}if((J=E(Q,P,B[188],["h.i.k.bl.bs"],[0,0],N,"k.f.bq.gx.bs",L))){M.push(267);
+O.push(" k.f.bq.gx.bs");break ifs;}}return J;}}),188:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[189],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[244].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),92:({scopes:"w.x.cz.fn.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[190],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[132].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),315:({scopes:"d.fa.gy.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[191],["h.i.gy.cd"],[0,0],N,"d.fa.gy.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),415:({scopes:"d.co.cp.gz.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[192],["ce.cf.cr"],[0,0],N,"d.co.cp.gz.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[412].go(Q,P,K,M,O,L))){break ifs;}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),396:({scopes:"d.gn.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[193],["ce.cf.gn.cr"],[0,0],N,"d.gn.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),156:({scopes:"k.bq.br.fi.bs.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[194]:B[195]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.bs.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),522:({scopes:"k.bq.br.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[196],["h.i.k.j.g"],[0,0],N,"k.bq.br.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;}if((J=H[511].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),78:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[197],["h.i.k.bl.bt"],[0,0],N,"k.bq.bx.bt",L))){M.push(77);O.push(" k.bq.bx.bt d.ha.bq.bx.bt");
+break ifs;}}return J;}}),35:({scopes:"k.bm.ca.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[198],[],[],N,"k.bm.ca.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[199],["h.bk.bj.bl.bt","h.i.k.bt","ce.dk.ca.bt"],[0,1,1,2,2,0],N,"d.bj.g",L))){M.push(31);
+O.push(" d.bj.g u.g");break ifs;}if((J=E(Q,P,B[200],["h.bk.bj.bl.bt","h.i.k.bt","ce.dk.ca.bt"],[0,1,1,2,2,0],N,"d.bj.v",L))){M.push(32);
+O.push(" d.bj.v u.v");break ifs;}if((J=E(Q,P,B[201],["h.bk.bj.bl.bt","h.i.k.bt","ce.dk.ca.bt"],[0,1,1,2,2,0],N,"d.bj.bs",L))){M.push(33);
+O.push(" d.bj.bs bh.bs");break ifs;}if((J=E(Q,P,B[202],["h.bk.bj.bl.bt","h.i.k.bt","ce.dk.ca.bt"],[0,1,1,2,2,0],N,"d.bj.m",L))){M.push(34);
+O.push(" d.bj.m bh.m");break ifs;}}return J;}}),321:({scopes:"k.bq.br.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[203],["h.i.k.j.cd"],[0,0],N,"k.bq.br.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[204],[],[],N,"n.o.p.cd",L))){break ifs;}if((J=H[326].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[302].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),184:({scopes:"k.bq.br.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[205],["h.i.k.j.bp"],[0,0],N,"k.bq.br.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),248:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[206],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(247);O.push("");break ifs;
+}}return J;}}),213:({scopes:"k.bm.bj.bs.bp u.bs.bj.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[207],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.bs.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),507:({scopes:"d.e.r.gv.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[208],["h.i.e.j.g"],[0,0],N,"d.e.r.gv.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),429:({scopes:"d.e.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[209],["h.i.e.v"],[0,0],N,"d.e.v",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[437].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),145:({scopes:"k.bq.br.r.hb.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[210]:B[211]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.hb.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),32:({scopes:"d.bj.v u.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[212],["h.bk.bj.j.bt","ce.dk.ca.bt","h.i.k.bt"],[0,1,1,2,2,0],N,"d.bj.v",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[423].go(Q,P,K,M,O,L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),272:({scopes:"d.bo.hc.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[213],["h.hd.hc.cd"],[0,0],N,"d.bo.hc.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[214],["h.i.he.cd"],[0,0],N,"d.bo.he.cd",L))){M.push(270);O.push(" d.bo.he.cd");
+break ifs;}if((J=E(Q,P,(G(Q,A[162],(P-1))?B[215]:null),[],[],N,"d.bo.hf.cd",L))){M.push(271);O.push(" d.bo.hf.cd");
+break ifs;}}return J;}}),499:({scopes:"n.f.hg.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[216],[],[],N,"n.f.hg.g",(function(){(L&&L());M.pop();O.pop();})))){}}return J;
+}}),192:({scopes:"k.l.fl.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[217],["h.i.k.j.bp"],[0,0],N,"k.l.fl.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[240].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),30:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[218],[],[],N,"n.da.hh.bt",L))){break ifs;}if((J=E(Q,P,B[219],[],[],N,"n.da.hi.bt",L))){break ifs;
+}if((J=E(Q,P,B[220],[],[],N,"n.o.p.bt",L))){break ifs;}if((J=E(Q,P,B[221],["dw.f.bt","h.i.dw.bt","h.i.dw.bt"],[0,1,1,2,2,0],N,"",L))){break ifs;
+}if((J=E(Q,P,B[222],["dw.f.bt","h.i.dw.bt","ce.dk.fn.bt","dw.f.hj.bt","be.bf.bt","ce.dk.hk.bt","n.da.hl.bt","dw.f.hl.bt","h.i.dw.bt","k.bm.hl.bt","be.bf.hm.bt","ce.dk.hn.bt"],[0,1,1,0,2,2,3,3,4,4,5,5,6,6,7,8,8,7,9,9,10,10,11,11],N,"",L))){break ifs;
+}if((J=E(Q,P,B[223],["h.i.dw.bt"],[0,0],N,"",L))){M.push(29);O.push("");break ifs;}}return J;}}),270:({scopes:"d.bo.he.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[224],["h.i.he.cd"],[0,0],N,"d.bo.he.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[225],[],[],N,"h.bc.ho.cd",L))){break ifs;}if((J=H[323].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[326].go(Q,P,K,M,O,L))){break ifs;}if((J=H[302].go(Q,P,K,M,O,L))){break ifs;}if((J=H[316].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),497:({scopes:"q.r.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[226],["h.i.q.g"],[0,0],N,"q.r.g",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[227],[],[],N,"be.bf.hp.g",L))){break ifs;}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),194:({scopes:"k.l.fl.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[228],["h.i.k.j.bp"],[0,0],N,"k.l.fl.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[252].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),84:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[229],["h.i.dw.bt"],[0,0],N,"dw.f.hq.hr.bt",L))){break ifs;}}return J;
+}}),334:({scopes:"k.bq.br.gi.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[230],["h.i.k.j.ch"],[0,0],N,"k.bq.br.gi.ch",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),143:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[231],[],[],N,"dp.dw.hs.cm",L))){break ifs;}}return J;}}),154:({scopes:"k.bq.br.fi.ff.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[232]:B[233]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.ff.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),503:({scopes:"q.r.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[234],["h.i.q.m"],[0,0],N,"q.r.m",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),69:({scopes:"k.bq.br.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[235],[],[],N,"k.bq.br.by.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[236],[],[],N,"n.o.p.bt",L))){break ifs;
+}}return J;}}),90:({scopes:"d.fn.ht.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[237],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,(G(Q,A[179],(P-1))?B[238]:null),[],[],N,"",L))){M.push(89);
+O.push(" w.f.fh.cm");break ifs;}}return J;}}),103:({scopes:"d.cu.fm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[239],["h.i.hu.j.cm"],[0,0],N,"d.cu.fm.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[240],["h.i.fm.cm"],[0,0],N,"",L))){M.push(101);O.push(" w.x.cu.fm.cm");break ifs;
+}if((J=E(Q,P,B[241],["h.i.hu.bl.cm"],[0,0],N,"",L))){M.push(102);O.push(" d.cu.fm.hu.cm");break ifs;}}return J;
+}}),478:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[242],[],[],N,"a.cz.cq.c",L))){M.push(475);O.push(" a.cz.cq.c");break ifs;
+}if((J=E(Q,P,B[243],[],[],N,"a.cz.hv.ev.c",L))){M.push(477);O.push(" a.cz.hv.ev.c");break ifs;}if((J=E(Q,P,B[244],["ce.dk.hw.c"],[0,0],N,"a.cz.c",L))){break ifs;
+}}return J;}}),531:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[530].go(Q,P,K,M,O,L))){break ifs;}if((J=H[526].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[523].go(Q,P,K,M,O,L))){break ifs;}if((J=H[525].go(Q,P,K,M,O,L))){break ifs;}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),421:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[245],["ce.cf.cr"],[0,0],N,"d.co.cp.eh.cr",L))){M.push(413);O.push(" d.co.cp.eh.cr");
+break ifs;}if((J=E(Q,P,B[246],["ce.cf.cr"],[0,0],N,"d.co.cp.fo.cr",L))){M.push(414);O.push(" d.co.cp.fo.cr");
+break ifs;}if((J=E(Q,P,B[247],["ce.cf.cr"],[0,0],N,"d.co.cp.gz.cr",L))){M.push(415);O.push(" d.co.cp.gz.cr");
+break ifs;}if((J=E(Q,P,B[248],["ce.cf.cr"],[0,0],N,"d.co.cp.hx.cr",L))){M.push(416);O.push(" d.co.cp.hx.cr");
+break ifs;}if((J=E(Q,P,B[249],["ce.cf.cr"],[0,0],N,"d.co.cp.cq.cr",L))){M.push(417);O.push(" d.co.cp.cq.cr");
+break ifs;}if((J=E(Q,P,B[250],["ce.cf.cr"],[0,0],N,"d.co.cp.cq.cr",L))){M.push(418);O.push(" d.co.cp.cq.cr");
+break ifs;}if((J=E(Q,P,B[251],["ce.cf.cr","ce.cf.cr"],[0,0,1,1],N,"d.co.cq.cr",L))){M.push(419);O.push(" d.co.cq.cr");
+break ifs;}if((J=E(Q,P,B[252],["ce.cf.cr"],[0,0],N,"d.co.cq.cr",L))){M.push(420);O.push(" d.co.cq.cr");
+break ifs;}}return J;}}),177:({scopes:"d.hy.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[253],[],[],N,"d.hy.bp",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),276:({scopes:"k.f.dn.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[254],["h.i.k.j.cd"],[0,0],N,"k.f.dn.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[314].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),295:({scopes:"k.bm.ca.cb.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[255],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}}return J;}}),318:({scopes:"k.cn.hz.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[256],["h.i.k.j.cd"],[0,0],N,"k.cn.hz.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),387:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[257],["a.cz.ee","w.x.cz.ee"],[0,0,1,1],N,"d.ia.ee",L))){M.push(382);
+O.push(" d.ia.ee");break ifs;}if((J=E(Q,P,B[258],["a.cz.ee","w.x.cz.ee"],[0,0,1,1],N,"d.ib.ee",L))){M.push(384);
+O.push(" d.ib.ee");break ifs;}if((J=E(Q,P,B[259],["a.b.ee"],[0,0],N,"d.ic.ee",L))){M.push(386);O.push(" d.ic.ee");
+break ifs;}}return J;}}),98:({scopes:"d.cu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[260],["h.i.ef.bl.cm","be.bf.id.cm"],[0,0,1,1],N,"d.cu.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[261],[],[],N,"",L))){M.push(97);O.push(" w.x.cu.cm");break ifs;}}return J;
+}}),155:({scopes:"k.bq.br.r.bs.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[262]:B[263]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.bs.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),385:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[264],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[387].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),275:({scopes:"d.bo.ie.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[265],["h.i.ie.cd"],[0,0],N,"d.bo.ie.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[305].go(Q,P,K,M,O,L))){break ifs;}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),94:({scopes:"w.x.cu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[266],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[132].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),211:({scopes:"k.bm.ca.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[267],["h.i.k.j.bp"],[0,0],N,"k.bm.ca.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),22:({scopes:"bh.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[268],["h.if.bj.ig.bt","bh.bt.bj.bu.ih.g","h.bk.bj.bl.bt","bh.bt","h.bk.bj.j.bt","bh.bt","h.if.bj.ii.bt"],[0,0,1,2,2,3,3,4,5,5,4,1,6,6],N,"",L))){break ifs;
+}if((J=E(Q,P,B[269],["h.if.bj.ig.bt"],[0,0],N,"",L))){M.push(24);O.push("");break ifs;}if((J=E(Q,P,(G(Q,A[206],(P-2))?B[270]:B[271]),["h.bk.bj.bl.bt","d.ij.bt"],[0,1,1,0],N,"bh.bt.bj.bu.g",L))){M.push(25);
+O.push(" bh.bt.bj.bu.g");break ifs;}}return J;}}),467:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[272],[],[],N,"",L))){M.push(466);O.push("");break ifs;}}return J;}}),36:({scopes:"q.r.gk.ft.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[273],["h.i.q.bt"],[0,0],N,"q.r.gk.ft.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[52].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),150:({scopes:"k.bq.br.fi.hb.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[274]:B[275]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.hb.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),75:({scopes:"k.bq.br.bt d.ha.bq.br.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[276],["h.i.k.j.bt"],[0,0],N,"k.bq.br.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),345:({scopes:"d.ik.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[277],[],[],N,"d.ik.ch",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),100:({scopes:"d.cu.fy.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[278],["h.i.ef.j.cm"],[0,0],N,"d.cu.fy.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[279],[],[],N,"",L))){M.push(99);O.push(" d.cu.fy.ef.cm");break ifs;}}return J;
+}}),320:({scopes:"k.bq.bx.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[280],["h.i.k.j.cd"],[0,0],N,"k.bq.bx.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),45:({scopes:"d.cu.bt d.cu.hu.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[281],[],[],N,"d.cu.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[282],["a.cz.bt","a.b.bt","dw.f.bt","h.i.dw.bt","ce.dk.gh.bt","dp.cu.il.bt","h.i.ev.bl.bt"],[0,0,1,1,2,3,3,2,4,4,5,5,6,6],N,"d.cu.eu.ev.bt",L))){M.push(42);
+O.push(" d.cu.eu.ev.bt d.ev.bt");break ifs;}if((J=E(Q,P,B[283],["a.cz.bt","a.b.bt","dw.f.bt","h.i.dw.bt","ce.dk.gh.bt","n.im.bt","be.bf.in.bt"],[0,0,1,1,2,3,3,2,4,4,5,5,6,6],N,"d.cu.eu.ev.bt",L))){break ifs;
+}if((J=E(Q,P,B[284],["dp.fn.bt","a.b.bt","dw.f.bt","h.i.dw.bt","ce.dk.gh.bt","n.im.bt","be.bf.in.bt"],[0,0,1,1,2,3,3,2,4,4,5,5,6,6],N,"d.cu.eu.io.bt",L))){break ifs;
+}if((J=E(Q,P,B[285],["a.b.bt","dw.f.bt","h.i.dw.bt"],[0,0,1,2,2,1],N,"d.cu.eu.ip.bt",L))){break ifs;}if((J=E(Q,P,B[286],["a.b.bt","dw.f.bt","h.i.dw.bt","ce.dk.gh.bt"],[0,0,1,2,2,1,3,3],N,"d.cu.eu.iq.bt",L))){M.push(43);
+O.push(" d.cu.eu.iq.bt");break ifs;}if((J=E(Q,P,B[287],["h.i.q.bt"],[0,0],N,"q.r.bt",L))){M.push(44);
+O.push(" q.r.bt");break ifs;}}return J;}}),224:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[288],[],[],N,"",L))){M.push(223);O.push("");break ifs;}}return J;}}),18:({scopes:"k.bq.br.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[289],["h.i.k.j.m"],[0,0],N,"k.bq.br.m",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[290],[],[],N,"n.o.p.m",L))){break ifs;}}return J;}}),173:({scopes:"k.bq.bx.fi.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[291],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),89:({scopes:"w.f.fh.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[292],["h.bc.ht.cm"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),96:({scopes:"d.cu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[293],["h.i.ef.j.cm","h.bk.cu.bl.cm","be.bf.ir.cm"],[0,0,1,1,2,2],N,"d.cu.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[294],[],[],N,"",L))){M.push(94);O.push(" w.x.cu.cm");break ifs;}if((J=E(Q,P,B[295],["h.i.ef.bl.cm"],[0,0],N,"",L))){M.push(95);
+O.push(" d.cu.ef.cm");break ifs;}}return J;}}),455:({scopes:"d.fn.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[296],["h.bk.fn.j.c"],[0,0],N,"d.fn.c",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[487].go(Q,P,K,M,O,L))){break ifs;}if((J=H[460].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[297],["a.b.c","w.x.cz.fn.c"],[0,0,1,1],N,"d.fn.gb.c",L))){break ifs;
+}if((J=E(Q,P,B[298],["a.b.gt.c"],[0,0],N,"d.i.fn.is.it.c",L))){M.push(452);O.push(" d.i.fn.is.it.c");
+break ifs;}if((J=E(Q,P,B[299],["a.b.gu.c"],[0,0],N,"d.i.fn.iu.iv.c",L))){M.push(453);O.push(" d.i.fn.iu.iv.c");
+break ifs;}if((J=E(Q,P,B[300],[],[],N,"d.fn.iw.c",L))){M.push(454);O.push(" d.fn.iw.c");break ifs;}}return J;
+}}),392:({scopes:"d.en.l",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[301],["h.i.en.l"],[0,0],N,"d.en.l",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[388].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),79:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[55].go(Q,P,K,M,O,L))){break ifs;}if((J=H[66].go(Q,P,K,M,O,L))){break ifs;}if((J=H[76].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[58].go(Q,P,K,M,O,L))){break ifs;}if((J=H[72].go(Q,P,K,M,O,L))){break ifs;}if((J=H[78].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),152:({scopes:"k.bq.br.fi.eo.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[302]:B[303]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.eo.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),261:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[304],["h.i.k.bl.bs"],[0,0],N,"k.l.bs",L))){M.push(259);O.push(" k.l.bs");
+break ifs;}if((J=E(Q,P,B[305],["h.i.k.bl.bs"],[0,0],N,"k.l.fd.bs",L))){M.push(260);O.push(" k.l.fd.bs");
+break ifs;}}return J;}}),383:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[306],["h.i.be.ee","be.bf.ix.ee"],[0,0,1,1],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[387].go(Q,P,K,M,O,L))){break ifs;}if((J=H[380].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),24:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[206],(P-2))?B[307]:null),["h.if.bj.ii.bt"],[0,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[308],["h.bk.bj.bl.bt"],[0,0],N,"bh.bt.bj.r.g",L))){M.push(23);O.push(" bh.bt.bj.r.g");
+break ifs;}}return J;}}),480:({scopes:"w.f.fh.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[309],[],[],N,"w.f.fh.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[310],[],[],N,"a.cz.cq.c",L))){M.push(479);O.push(" a.cz.cq.c");break ifs;}}return J;}}),529:({scopes:"d.iy.iz.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[233],(P-1))?B[311]:null),[],[],N,"d.iy.iz.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[312],["h.i.k.bl.g"],[0,0],N,"k.bq.br.g",L))){M.push(527);O.push(" k.bq.br.g d.ja.iz.g");
+break ifs;}if((J=E(Q,P,B[313],["h.i.k.bl.g"],[0,0],N,"k.bq.bx.g",L))){M.push(528);O.push(" k.bq.bx.g d.ja.iz.g");
+break ifs;}}return J;}}),326:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[314],["h.i.dw.cd"],[0,0],N,"dw.f.jb.cd",L))){break ifs;}if((J=E(Q,P,B[315],["h.i.dw.cd"],[0,0],N,"dw.f.jc.cd",L))){break ifs;
+}if((J=E(Q,P,B[316],["h.i.dw.cd"],[0,0],N,"dw.f.jd.cd",L))){break ifs;}if((J=E(Q,P,B[317],["h.i.dw.cd"],[0,0],N,"dw.f.je.cd",L))){M.push(325);
+O.push(" dw.f.je.cd");break ifs;}}return J;}}),390:({scopes:"d.en.jf.l",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[318],["h.i.en.l"],[0,0],N,"d.en.jf.l",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[388].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),324:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[319]:null),[],[],N,"dp.cu.jg.cd",L))){break ifs;
+}if((J=E(Q,P,B[320],[],[],N,"dp.cu.jg.cd",L))){break ifs;}}return J;}}),6:({scopes:"d.jh.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[321],[],[],N,"d.jh.ey",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[322],[],[],N,"dp.cz.jh.ey",L))){break ifs;
+}}return J;}}),395:({scopes:"bh.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[399].go(Q,P,K,M,O,L))){break ifs;}if((J=H[408].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),523:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[323],["h.i.k.bl.g"],[0,0],N,"k.bq.br.g",L))){M.push(522);O.push(" k.bq.br.g");
+break ifs;}}return J;}}),485:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[324],[],[],N,"a.cz.ji.ev.c",L))){break ifs;}}return J;}}),209:({scopes:"u.g.bj.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[325],[],[],N,"u.g.bj.bp",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[494].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),286:({scopes:"k.bm.ca.cm.cd bh.cm.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[326],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cm.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),465:({scopes:"d.jj.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[327],[],[],N,"d.jj.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[484].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[328],[],[],N,"",L))){M.push(464);O.push("");break ifs;}}return J;}}),236:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[329],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(235);O.push("");break ifs;
+}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),169:({scopes:"k.bq.bx.fi.ff.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[330],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.ff.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),459:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[460].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[331],[],[],N,"",L))){M.push(458);
+O.push("");break ifs;}if((J=H[451].go(Q,P,K,M,O,L))){break ifs;}if((J=H[484].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[463].go(Q,P,K,M,O,L))){break ifs;}if((J=H[449].go(Q,P,K,M,O,L))){break ifs;}if((J=H[468].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[487].go(Q,P,K,M,O,L))){break ifs;}if((J=H[490].go(Q,P,K,M,O,L))){break ifs;}if((J=H[439].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),47:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[332],[],[],N,"k.bm.ca.bt",L))){M.push(35);O.push(" k.bm.ca.bt");break ifs;
+}if((J=E(Q,P,B[333],["h.i.q.bt"],[0,0],N,"q.r.gk.ft.bt",L))){M.push(36);O.push(" q.r.gk.ft.bt");break ifs;
+}if((J=E(Q,P,B[334],["h.i.q.bt"],[0,0],N,"q.r.bt",L))){M.push(37);O.push(" q.r.bt");break ifs;}if((J=E(Q,P,B[335],["h.i.q.bt"],[0,0],N,"q.bu.ez.bt",L))){break ifs;
+}if((J=E(Q,P,B[336],["h.i.q.bt"],[0,0],N,"q.bu.bv.bt",L))){break ifs;}if((J=E(Q,P,B[337],["a.cz.fg.bt","w.x.cz.fg.bt","a.b.gt.bt"],[0,0,1,1,2,2],N,"d.fg.bt",L))){M.push(38);
+O.push(" d.fg.bt");break ifs;}if((J=E(Q,P,B[338],["a.b.jk.bt","a.cz.fn.bt","w.x.cz.fn.bt"],[0,0,1,1,2,2],N,"d.fn.bt",L))){M.push(40);
+O.push(" d.fn.bt");break ifs;}if((J=E(Q,P,B[339],[],[],N,"ce.cf.bt",L))){break ifs;}if((J=E(Q,P,B[340],["ce.cf.ci.gi.bt"],[0,0],N,"d.gi.bt",L))){M.push(41);
+O.push(" d.gi.bt");break ifs;}if((J=E(Q,P,B[341],["ce.cf.ex.bt","dp.fn.bt","dw.f.bt","h.i.dw.bt"],[0,0,1,1,2,3,3,2],N,"d.jl.bt",L))){break ifs;
+}if((J=E(Q,P,B[342],[],[],N,"ce.cf.ex.bt",L))){break ifs;}if((J=E(Q,P,B[343],["a.b.bt","a.cz.cu.bt","a.b.jm.bt","dp.cu.hs.bt","w.x.cu.bt","h.i.ef.bl.bt"],[0,0,1,1,2,2,3,3,4,4,5,5],N,"d.cu.bt",L))){M.push(45);
+O.push(" d.cu.bt d.cu.hu.bt");break ifs;}if((J=E(Q,P,B[344],[],[],N,"a.cz.bt",L))){break ifs;}if((J=E(Q,P,B[345],[],[],N,"a.b.bt",L))){break ifs;
+}if((J=H[49].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[346],["ce.dk.fn.bt","d.eq.jn.bt","dw.f.fn.bt","h.i.dw.bt","n.f.fn.bt"],[0,0,1,1,2,3,3,2,4,4],N,"",L))){break ifs;
+}if((J=H[81].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[347],["h.i.k.bt","ce.dk.ca.bt"],[0,0,1,1],N,"k.bm.ca.bt",L))){M.push(46);
+O.push(" k.bm.ca.bt");break ifs;}if((J=E(Q,P,B[348],[],[],N,"ce.dk.ga.bt",L))){break ifs;}if((J=E(Q,P,B[349],[],[],N,"a.b.jm.bt",L))){break ifs;
+}if((J=E(Q,P,B[350],[],[],N,"h.hd.jo.bt",L))){break ifs;}if((J=E(Q,P,B[351],[],[],N,"ce.dk.jp.bt",L))){break ifs;
+}if((J=E(Q,P,B[352],[],[],N,"ce.dk.jq.bt",L))){break ifs;}if((J=E(Q,P,B[353],[],[],N,"ce.dk.jr.bt",L))){break ifs;
+}if((J=E(Q,P,B[354],[],[],N,"ce.dk.fe.bt",L))){break ifs;}if((J=E(Q,P,B[355],[],[],N,"ce.dk.js.bt",L))){break ifs;
+}if((J=E(Q,P,B[356],[],[],N,"ce.dk.dm.bt",L))){break ifs;}if((J=E(Q,P,B[357],[],[],N,"ce.dk.k.bt",L))){break ifs;
+}if((J=E(Q,P,B[358],[],[],N,"ce.dk.gh.bt",L))){break ifs;}if((J=E(Q,P,B[359],["ce.dk.cz.bt","dp.fn.bt"],[0,0,1,1],N,"",L))){break ifs;
+}if((J=H[48].go(Q,P,K,M,O,L))){break ifs;}if((J=H[79].go(Q,P,K,M,O,L))){break ifs;}if((J=H[74].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[27].go(Q,P,K,M,O,L))){break ifs;}if((J=H[85].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,(G(Q,A[275],(P-1))?B[360]:null),["ce.dk.bt","dw.f.hj.bt"],[0,0,1,1],N,"",L))){break ifs;
+}if((J=H[28].go(Q,P,K,M,O,L))){break ifs;}if((J=H[26].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),332:({scopes:"d.s.jt.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[361],[],[],N,"d.s.jt.ch",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[362],[],[],N,"h.bc.ek.ch",L))){break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),284:({scopes:"k.bm.ca.bp.cd bh.bp.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[363],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.bp.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),412:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[364],[],[],N,"dp.fn.gz.ju.cr",L))){break ifs;}if((J=E(Q,P,B[365],[],[],N,"dp.fn.gz.jv.cr",L))){break ifs;
+}if((J=E(Q,P,B[366],[],[],N,"dp.cu.gz.jv.cr",L))){break ifs;}if((J=E(Q,P,B[367],[],[],N,"dp.fn.gz.jw.cr",L))){break ifs;
+}if((J=E(Q,P,B[368],[],[],N,"dp.cu.gz.jw.cr",L))){break ifs;}if((J=E(Q,P,B[369],[],[],N,"dp.fn.gz.jx.cr",L))){break ifs;
+}if((J=E(Q,P,B[370],[],[],N,"dp.cu.gz.jy.cr",L))){break ifs;}if((J=E(Q,P,B[371],[],[],N,"dp.fn.gz.jz.cr",L))){break ifs;
+}if((J=E(Q,P,B[372],[],[],N,"dp.cu.gz.jz.cr",L))){break ifs;}if((J=E(Q,P,B[373],[],[],N,"dp.fn.gz.ka.cr",L))){break ifs;
+}if((J=E(Q,P,B[374],[],[],N,"dp.fn.gz.kb.cr",L))){break ifs;}if((J=E(Q,P,B[375],[],[],N,"dp.cu.gz.gz.cr",L))){break ifs;
+}if((J=E(Q,P,B[376],[],[],N,"dp.fn.gz.v.cr",L))){break ifs;}if((J=E(Q,P,B[377],[],[],N,"dp.fn.kc.f.cr",L))){break ifs;
+}}return J;}}),171:({scopes:"k.bq.bx.fi.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[378],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),330:({scopes:"k.bq.br.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[379],["h.i.k.j.ch"],[0,0],N,"k.bq.br.ch",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[369].go(Q,P,K,M,O,L))){break ifs;}if((J=H[370].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),182:({scopes:"n.f.kd.ke.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[380],["h.i.n.bp"],[0,0],N,"n.f.kd.ke.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),230:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[381],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(229);O.push("");break ifs;
+}}return J;}}),410:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[382],[],[],N,"dp.fn.kf.cr",L))){break ifs;}if((J=E(Q,P,B[383],[],[],N,"dp.cu.kf.cr",L))){break ifs;
+}if((J=E(Q,P,B[384],[],[],N,"dp.n.kf.cr",L))){break ifs;}if((J=E(Q,P,B[385],[],[],N,"dp.dw.kf.cr",L))){break ifs;
+}if((J=E(Q,P,B[386],[],[],N,"dp.fn.kg.cr",L))){break ifs;}}return J;}}),138:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[387],["h.bc.ef.cm"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),519:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[388],["h.i.q.kh"],[0,0],N,"q.r.kh",L))){M.push(516);O.push(" q.r.kh");
+break ifs;}if((J=E(Q,P,B[389],["h.bk.bj.bp"],[0,0],N,"bh.bp.bj.g",L))){M.push(517);O.push(" bh.bp.bj.g");
+break ifs;}if((J=E(Q,P,B[390],["h.bk.bj.bp.ec"],[0,0],N,"bh.bp.ec.bj.g",L))){M.push(518);O.push(" bh.bp.ec.bj.g");
+break ifs;}}return J;}}),282:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[391],["a.cz.cu.cd","w.x.cu.cd","h.i.hu.cd"],[0,0,1,1,2,2],N,"d.cu.cd",L))){M.push(280);
+O.push(" d.cu.cd");break ifs;}if((J=E(Q,P,B[392],["w.x.cu.cd","h.i.hu.cd"],[0,0,1,1],N,"d.cu.cd",L))){M.push(281);
+O.push(" d.cu.cd");break ifs;}}return J;}}),10:({scopes:"q.r.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[393],["h.i.q.ey"],[0,0],N,"q.r.ey",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),161:({scopes:"k.bq.bx.r.fj.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[394]:B[395]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.fj.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),505:({scopes:"bh.m.bj.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[307],(P-8))?B[396]:null),["h.i.e.g"],[0,0],N,"bh.m.bj.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,((!G(Q,A[307],(P-8)))?B[397]:null),["h.i.e.g"],[0,0],N,"",L))){M.push(504);
+O.push("");break ifs;}}return J;}}),232:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[398],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(231);O.push("");break ifs;
+}}return J;}}),179:({scopes:"d.cu.ki.kj.bp dw.gg.cu.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[399],["h.i.ef.bp"],[0,0],N,"d.cu.ki.kj.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),207:({scopes:"k.bq.f.ei.em.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[400],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.em.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[401],[],[],N,"",L))){break ifs;}}return J;}}),431:({scopes:"bh.c.bj.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[402],["h.bk.bj.j.v"],[0,0],N,"bh.c.bj.v",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[438].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),55:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[403],["h.i.k.bl.bt"],[0,0],N,"k.l.ke.bt",L))){M.push(54);O.push(" k.l.ke.bt");
+break ifs;}}return J;}}),12:({scopes:"k.bq.br.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[404],["h.i.k.j.ey"],[0,0],N,"k.bq.br.ey",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[405],[],[],N,"n.o.p.ey",L))){break ifs;}}return J;}}),234:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[406],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(233);O.push("");break ifs;
+}}return J;}}),433:({scopes:"k.bq.br.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[407],["h.i.k.j.v"],[0,0],N,"k.bq.br.v",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),288:({scopes:"k.bm.ca.cr.cd bh.cr.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[408],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cr.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),463:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[409],[],[],N,"n.im.c",L))){break ifs;}if((J=E(Q,P,B[410],[],[],N,"dw.im.c",L))){break ifs;
+}if((J=E(Q,P,B[411],[],[],N,"n.da.c",L))){break ifs;}if((J=E(Q,P,B[412],["ce.dk.hw.c"],[0,0],N,"n.f.c",L))){break ifs;
+}}return J;}}),159:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[413],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.r.hb.cm",L))){M.push(145);
+O.push(" k.bq.br.r.hb.cm");break ifs;}if((J=E(Q,P,B[414],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.r.fj.cm",L))){M.push(146);
+O.push(" k.bq.br.r.fj.cm");break ifs;}if((J=E(Q,P,B[415],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.r.eo.cm",L))){M.push(147);
+O.push(" k.bq.br.r.eo.cm");break ifs;}if((J=E(Q,P,B[416],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.r.gm.cm",L))){M.push(148);
+O.push(" k.bq.br.r.gm.cm");break ifs;}if((J=E(Q,P,B[417],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.r.ff.cm",L))){M.push(149);
+O.push(" k.bq.br.r.ff.cm");break ifs;}if((J=E(Q,P,B[418],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.fi.hb.cm",L))){M.push(150);
+O.push(" k.bq.br.fi.hb.cm");break ifs;}if((J=E(Q,P,B[419],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.fi.fj.cm",L))){M.push(151);
+O.push(" k.bq.br.fi.fj.cm");break ifs;}if((J=E(Q,P,B[420],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.fi.eo.cm",L))){M.push(152);
+O.push(" k.bq.br.fi.eo.cm");break ifs;}if((J=E(Q,P,B[421],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.fi.gm.cm",L))){M.push(153);
+O.push(" k.bq.br.fi.gm.cm");break ifs;}if((J=E(Q,P,B[422],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.br.fi.ff.cm",L))){M.push(154);
+O.push(" k.bq.br.fi.ff.cm");break ifs;}if((J=E(Q,P,B[423],["h.i.k.bl.cm"],[0,0],N,"k.bq.br.r.bs.cm",L))){M.push(155);
+O.push(" k.bq.br.r.bs.cm");break ifs;}if((J=E(Q,P,B[424],["h.i.k.bl.cm"],[0,0],N,"k.bq.br.fi.bs.cm",L))){M.push(156);
+O.push(" k.bq.br.fi.bs.cm");break ifs;}if((J=E(Q,P,B[425],["h.i.k.bl.cm"],[0,0],N,"k.bq.br.r.cm",L))){M.push(157);
+O.push(" k.bq.br.r.cm");break ifs;}if((J=E(Q,P,B[426],["h.i.k.bl.cm"],[0,0],N,"k.bq.br.fi.cm",L))){M.push(158);
+O.push(" k.bq.br.fi.cm");break ifs;}}return J;}}),457:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[460].go(Q,P,K,M,O,L))){break ifs;}if((J=H[456].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[467].go(Q,P,K,M,O,L))){break ifs;}if((J=H[473].go(Q,P,K,M,O,L))){break ifs;}if((J=H[441].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[487].go(Q,P,K,M,O,L))){break ifs;}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),181:({scopes:"n.f.kd.kk.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[427],["h.i.n.bp"],[0,0],N,"n.f.kd.kk.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[428],[],[],N,"n.o.p.bp",L))){break ifs;}}return J;}}),14:({scopes:"k.bq.bx.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[429],["h.i.k.j.ey"],[0,0],N,"k.bq.bx.ey",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[430],[],[],N,"n.o.p.ey",L))){break ifs;}}return J;}}),278:({scopes:"d.bo.en.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[330],(P-1)))?B[431]:null),["h.i.en.cd"],[0,0],N,"d.bo.en.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),228:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[432],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(227);O.push("");break ifs;
+}}return J;}}),452:({scopes:"d.i.fn.is.it.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[433],[],[],N,"d.i.fn.is.it.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[481].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[460].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),2:({scopes:"d.kl.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[434],[],[],N,"d.kl.ey",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[11].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[435],[],[],N,"w.x.e.ey",L))){break ifs;}if((J=E(Q,P,B[436],["h.i.w.ey"],[0,0],N,"w.f.km.fn.ey",L))){break ifs;
+}if((J=E(Q,P,B[437],["h.i.w.ey"],[0,0],N,"w.f.km.iz.ey",L))){break ifs;}if((J=E(Q,P,B[438],[],[],N,"w.x.e.kn.ey",L))){break ifs;
+}if((J=E(Q,P,B[439],["h.i.w.ey"],[0,0],N,"w.f.km.ko.ey",L))){break ifs;}if((J=E(Q,P,B[440],["h.i.w.ey"],[0,0],N,"w.f.km.kp.ey",L))){break ifs;
+}if((J=E(Q,P,B[441],["h.i.w.ey","w.f.km.kr.ey","h.bc.dk.ey","k.bm.ks.ey","k.bq.br.ks.ey","h.i.k.bl.ey","h.i.k.j.ey"],[0,0,1,1,2,2,3,3,4,5,5,6,6,4],N,"d.kq.ey",L))){break ifs;
+}}return J;}}),343:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[442],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[344].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),110:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[443],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[130].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),372:({scopes:"d.cu.kt.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[444],["h.i.ef.ch"],[0,0],N,"d.cu.kt.ee",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),238:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[445],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(237);O.push("");break ifs;
+}}return J;}}),136:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[446],[],[],N,"",L))){break ifs;}}return J;}}),59:({scopes:"k.bq.bx.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[447],[],[],N,"k.bq.bx.by.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[448],[],[],N,"n.o.p.bt",L))){break ifs;
+}}return J;}}),226:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[449],["h.bk.bj.bp","bh.bp.bj.bh.ih"],[0,1,1,0],N,"bh.bp.bj.bh",L))){break ifs;
+}if((J=E(Q,P,B[450],["h.bk.bj.bp"],[0,0],N,"bh.bp.bj.bh",L))){M.push(225);O.push(" bh.bp.bj.bh");break ifs;
+}if((J=E(Q,P,B[451],["h.i.dw.bp"],[0,0],N,"dw.f.ku.kv.bp",L))){break ifs;}if((J=E(Q,P,B[452],["h.i.dw.bp"],[0,0],N,"dw.f.ku.fn.bp",L))){break ifs;
+}if((J=E(Q,P,B[453],["h.i.dw.bp"],[0,0],N,"dw.f.ku.hq.bp",L))){break ifs;}}return J;}}),257:({scopes:"q.r.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[454],["h.i.q.bs"],[0,0],N,"q.r.ch",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),366:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[455],["d.s.ch","ce.cf.ci.ch"],[0,1,1,0],N,"",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[342].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),8:({scopes:"d.kw.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[456],["h.hd.kx.ey"],[0,0],N,"d.kw.ey",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[457],[],[],N,"dp.n.kw.ey",L))){break ifs;}if((J=E(Q,P,B[458],[],[],N,"dp.n.ky.ey",L))){break ifs;
+}if((J=E(Q,P,B[459],[],[],N,"dp.n.kz.la.ey",L))){break ifs;}if((J=E(Q,P,B[460],[],[],N,"be.lb.kz.lc.ey",L))){break ifs;
+}if((J=E(Q,P,B[461],[],[],N,"n.da.ey",L))){break ifs;}if((J=E(Q,P,(G(Q,A[354],(P-1))?B[462]:B[463]),[],[],N,"ce.f.ld.ey",L))){break ifs;
+}if((J=E(Q,P,B[464],["h.i.n.ey"],[0,0],N,"n.f.kz.le.ey",L))){break ifs;}if((J=H[13].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[15].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[465],["dp.cu.lf.ey","h.bk.cu.ey"],[0,0,1,1],N,"",L))){M.push(7);
+O.push("");break ifs;}if((J=E(Q,P,B[466],[],[],N,"ce.f.lg.ey",L))){break ifs;}}return J;}}),516:({scopes:"q.r.kh",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[467],["h.i.q.kh"],[0,0],N,"q.r.kh",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),116:({scopes:"d.fa.lh.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[468],["h.i.lh.j.cm"],[0,0],N,"d.fa.lh.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,(G(Q,A[362],(P-1))?B[469]:null),[],[],N,"",L))){M.push(115);O.push(" d.fa.lh.li.cm");
+break ifs;}}return J;}}),525:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[470],["h.i.k.bl.g"],[0,0],N,"k.bq.bx.g",L))){M.push(524);O.push(" k.bq.bx.g");
+break ifs;}}return J;}}),240:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[471],["h.bk.bo.bp"],[0,0],N,"",L))){M.push(239);O.push("");break ifs;
+}}return J;}}),527:({scopes:"k.bq.br.g d.ja.iz.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[472],["h.i.k.j.g"],[0,0],N,"k.bq.br.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;}if((J=H[511].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),114:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[473],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),368:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[474],[],[],N,"ce.dk.lj.ch",L))){break ifs;}}return J;}}),73:({scopes:"k.cn.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[475],["h.i.k.j.bt"],[0,0],N,"k.cn.bt",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[476],[],[],N,"n.o.p.bt",L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),63:({scopes:"k.bq.f.bz.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[477],[],[],N,"k.bq.f.bz.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),297:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[478],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.bp.cd",L))){M.push(283);
+O.push(" k.bm.ca.cb.bp.cd bh.bp.bj.cd");break ifs;}if((J=E(Q,P,B[479],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.bp.cd",L))){M.push(284);
+O.push(" k.bm.ca.bp.cd bh.bp.bj.cd");break ifs;}if((J=E(Q,P,B[480],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.cm.cd",L))){M.push(285);
+O.push(" k.bm.ca.cb.cm.cd bh.cm.bj.cd");break ifs;}if((J=E(Q,P,B[481],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cm.cd",L))){M.push(286);
+O.push(" k.bm.ca.cm.cd bh.cm.bj.cd");break ifs;}if((J=E(Q,P,B[482],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.cr.cd",L))){M.push(287);
+O.push(" k.bm.ca.cb.cr.cd bh.cr.bj.cd");break ifs;}if((J=E(Q,P,B[483],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cr.cd",L))){M.push(288);
+O.push(" k.bm.ca.cr.cd bh.cr.bj.cd");break ifs;}if((J=E(Q,P,B[484],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.g.cd",L))){M.push(289);
+O.push(" k.bm.ca.cb.g.cd u.g.bj.cd");break ifs;}if((J=E(Q,P,B[485],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.g.cd",L))){M.push(290);
+O.push(" k.bm.ca.g.cd u.g.bj.cd");break ifs;}if((J=E(Q,P,B[486],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.ew.cd",L))){M.push(291);
+O.push(" k.bm.ca.cb.ew.cd u.g.ew.bj.cd");break ifs;}if((J=E(Q,P,B[487],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.ew.cd",L))){M.push(292);
+O.push(" k.bm.ca.ew.cd u.g.ew.bj.cd");break ifs;}if((J=E(Q,P,B[488],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.cc.cd",L))){M.push(293);
+O.push(" k.bm.ca.cb.cc.cd u.g.cc.bj.cd");break ifs;}if((J=E(Q,P,B[489],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cc.cd",L))){M.push(294);
+O.push(" k.bm.ca.cc.cd u.g.cc.bj.cd");break ifs;}if((J=E(Q,P,B[490],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cb.cd",L))){M.push(295);
+O.push(" k.bm.ca.cb.cd");break ifs;}if((J=E(Q,P,B[491],["h.i.k.cd","ce.dk.ca.cd","ce.cf.cg.cd"],[0,1,1,2,2,0],N,"k.bm.ca.cd",L))){M.push(296);
+O.push(" k.bm.ca.cd");break ifs;}}return J;}}),20:({scopes:"q.r.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[492],["h.i.q.m"],[0,0],N,"q.r.m",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),280:({scopes:"d.cu.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[493],["h.i.cu.cd"],[0,0],N,"d.cu.cd",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),4:({scopes:"d.lk.ci.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[494],["ce.cf.lk.ci.ey"],[0,0],N,"d.lk.ci.ey",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[13].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[495],["dp.cu.ll.ey","h.bk.cu.ey"],[0,0,1,1],N,"",L))){M.push(3);
+O.push("");break ifs;}}return J;}}),112:({scopes:"d.lm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[496],["h.i.hu.j.cm"],[0,0],N,"d.lm.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[497],[],[],N,"",L))){M.push(110);O.push("");break ifs;}if((J=E(Q,P,B[498],["h.i.hu.bl.cm"],[0,0],N,"",L))){M.push(111);
+O.push(" d.lm.hu.cm");break ifs;}}return J;}}),214:({scopes:"k.bm.bj.bp.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[499],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.bp.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),370:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[500],[],[],N,"n.f.ln.ch",L))){break ifs;}if((J=E(Q,P,B[501],[],[],N,"be.bf.ln.ch",L))){break ifs;
+}}return J;}}),134:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[502],["n.o.p.ff.lo.cm","n.o.p.ff.lp.cm","n.o.p.ff.x.cm"],[0,0,1,1,2,2],N,"",L))){break ifs;
+}}return J;}}),502:({scopes:"bh.ey.bj.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[503],["h.i.e.g","w.x.e.lq.g","h.i.e.g"],[0,0,1,1,2,2],N,"bh.ey.bj.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[504],["h.i.e.g"],[0,0],N,"",L))){M.push(501);
+O.push("");break ifs;}}return J;}}),57:({scopes:"k.l.kk.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[505],["h.i.k.j.bt"],[0,0],N,"k.l.kk.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[506],["h.i.lr.bt","h.i.lr.bt"],[0,0,1,1],N,"k.l.lr.bt",L))){break ifs;}if((J=E(Q,P,B[507],[],[],N,"n.o.p.ls.bt",L))){break ifs;
+}if((J=E(Q,P,B[508],[],[],N,"n.o.p.bt",L))){break ifs;}if((J=E(Q,P,B[509],["h.i.lt.bt"],[0,0],N,"k.l.lt.bt",L))){M.push(56);
+O.push(" k.l.lt.bt");break ifs;}if((J=E(Q,P,B[510],[],[],N,"ce.dk.l.bt",L))){break ifs;}}return J;}}),303:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[511],[],[],N,"ce.cf.cd",L))){break ifs;}if((J=E(Q,P,B[512],[],[],N,"a.b.cd",L))){break ifs;
+}}return J;}}),470:({scopes:"d.ki.lu.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[513],[],[],N,"d.ki.lu.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[439].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),220:({scopes:"k.bm.bj.cd.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[514],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.cd.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),28:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[515],["ce.f.lv.bt","dw.f.bt","dp.fn.bt","dp.fn.bt"],[0,0,1,1,2,2,3,3],N,"",L))){break ifs;
+}}return J;}}),307:({scopes:"d.bo.dv.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[516],["ce.cf.cd"],[0,0],N,"d.bo.dv.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),435:({scopes:"k.bq.bx.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[517],["h.i.k.j.v"],[0,0],N,"k.bq.bx.v",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),163:({scopes:"k.bq.bx.r.gm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[518]:B[519]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.gm.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),122:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[520],[],[],N,"dp.cz.cm",L))){break ifs;}}return J;}}),218:({scopes:"k.bm.bj.ey.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[521],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.ey.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[1].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),358:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[522],["d.s.ch","ce.cf.ci.cj.ch"],[0,1,1,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[523],["d.s.ch","ce.cf.ci.ck.ch"],[0,1,1,0],N,"",L))){M.push(356);
+O.push(" q.r.s.t");break ifs;}if((J=E(Q,P,B[524],[],[],N,"",L))){M.push(357);O.push("");break ifs;}}return J;
+}}),476:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[525],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),427:({scopes:"q.r.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[526],["h.i.q.v"],[0,0],N,"q.r.v",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),53:({scopes:"k.l.lt.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[527],["h.i.lt.bt"],[0,0],N,"k.l.lt.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),299:({scopes:"k.f.dn.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[528],["h.i.k.j.cd"],[0,0],N,"k.f.dn.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[314].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),347:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[529],["d.s.ch","ce.cf.ci.lw.ch","d.ja.lx.ch"],[0,1,1,2,2,0],N,"d.bk",L))){break ifs;
+}}return J;}}),360:({scopes:"q.r.s.t.cs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[530],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[344].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),474:({scopes:"a.cz.cq.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[531],[],[],N,"a.cz.cq.c",(function(){(L&&L());M.pop();O.pop();})))){}}return J;
+}}),216:({scopes:"k.bm.bj.ch.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[532],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.ch.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[327].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),222:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[533],[],[],N,"n.o.p.bp",L))){break ifs;}}return J;}}),175:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[159].go(Q,P,K,M,O,L))){break ifs;}if((J=H[174].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),381:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[534],["h.i.be.ee"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[387].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[380].go(Q,P,K,M,O,L))){break ifs;}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),165:({scopes:"k.bq.bx.fi.hb.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[535],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.hb.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),450:({scopes:"d.gd.jf.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[536],[],[],N,"d.gd.jf.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[537],[],[],N,"ce.dk.ly.lz.c",L))){break ifs;
+}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),472:({scopes:"d.ki.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[538],[],[],N,"d.ki.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[487].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[539],["w.x.cu.c"],[0,0],N,"d.ki.gb.c",L))){M.push(469);O.push(" d.ki.gb.c");break ifs;
+}if((J=E(Q,P,B[540],[],[],N,"d.ki.lu.c",L))){M.push(470);O.push(" d.ki.lu.c");break ifs;}if((J=H[492].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[541],[],[],N,"d.ki.iw.c",L))){M.push(471);O.push(" d.ki.iw.c");break ifs;}}return J;}}),71:({scopes:"k.bq.bx.bs.bt bh.bs.bj.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[542],["h.i.k.j.bt"],[0,0],N,"k.bq.bx.bs.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[543],[],[],N,"q.bu.bv.bs",L))){break ifs;}if((J=E(Q,P,B[544],[],[],N,"q.bu.bw.bs",L))){break ifs;
+}if((J=E(Q,P,B[545],[],[],N,"k.bq.bx.by.bs",L))){M.push(67);O.push(" k.bq.bx.by.bs");break ifs;}if((J=E(Q,P,B[546],[],[],N,"k.bq.f.bz.by.bs",L))){M.push(68);
+O.push(" k.bq.f.bz.by.bs");break ifs;}if((J=E(Q,P,B[547],[],[],N,"k.bq.br.by.bs",L))){M.push(69);O.push(" k.bq.br.by.bs");
+break ifs;}if((J=E(Q,P,B[548],["n.o.p.bt"],[0,0],N,"k.bq.bx.bs",L))){M.push(70);O.push(" k.bq.bx.bs");
+break ifs;}if((J=E(Q,P,B[549],[],[],N,"n.o.p.bt",L))){break ifs;}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),26:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[550],[],[],N,"n.im.bt",L))){break ifs;}if((J=E(Q,P,B[551],[],[],N,"dp.n.ma.bt",L))){break ifs;
+}if((J=E(Q,P,B[552],[],[],N,"dp.n.mb.bt",L))){break ifs;}if((J=E(Q,P,B[553],[],[],N,"n.f.bt",L))){break ifs;
+}}return J;}}),359:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[554],["d.s.ch","ce.cf.ci.cj.ch","n.da.s.ch"],[0,1,1,2,2,0],N,"",L))){M.push(358);
+O.push("");break ifs;}}return J;}}),308:({scopes:"d.bo.dy.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[555],["ce.cf.cd"],[0,0],N,"d.bo.dy.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),420:({scopes:"d.co.cq.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[556],["ce.cf.cr"],[0,0],N,"d.co.cq.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),121:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[557],[],[],N,"dp.cu.jg.cm",L))){break ifs;}}return J;}}),201:({scopes:"k.bq.f.ei.ej.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[558],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.ej.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),490:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[559],["h.i.k.bl.c"],[0,0],N,"k.bq.br.c",L))){M.push(488);O.push(" k.bq.br.c");
+break ifs;}if((J=E(Q,P,B[560],["h.i.k.bl.c"],[0,0],N,"k.bq.bx.c",L))){M.push(489);O.push(" k.bq.bx.c");
+break ifs;}}return J;}}),123:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[561],[],[],N,"n.f.ln.cm",L))){break ifs;}}return J;}}),448:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[419],(P-1))?(G(Q,A[125],(P-1))?B[562]:B[563]):(G(Q,A[125],(P-1))?B[564]:B[565])),[],[],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[566],["a.cz.c"],[0,0],N,"",L))){M.push(444);O.push("");break ifs;
+}if((J=E(Q,P,B[567],[],[],N,"",L))){M.push(446);O.push("");break ifs;}if((J=E(Q,P,B[568],[],[],N,"d.mc.c",L))){M.push(447);
+O.push(" d.mc.c");break ifs;}}return J;}}),422:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[569],[],[],N,"dp.fn.eh.cr",L))){break ifs;}if((J=E(Q,P,B[570],[],[],N,"dp.cu.eh.cr",L))){break ifs;
+}}return J;}}),446:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[162],(P-1))?B[571]:null),[],[],N,"",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[572],[],[],N,"",L))){M.push(445);
+O.push("");break ifs;}}return J;}}),363:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[573],["d.s.ch","ce.cf.ci.cj.ch","n.da.s.ch"],[0,1,1,2,2,0],N,"",L))){M.push(362);
+O.push("");break ifs;}}return J;}}),255:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[574],["h.i.lr.bp","h.i.lr.bp"],[0,0,1,1],N,"k.l.lr.bp",L))){break ifs;}if((J=E(Q,P,B[575],["h.i.lt.bp"],[0,0],N,"k.l.lt.bp",L))){M.push(253);
+O.push(" k.l.lt.bp");break ifs;}if((J=E(Q,P,B[576],["h.i.en.bp"],[0,0],N,"k.l.en.bp",L))){M.push(254);
+O.push(" k.l.en.bp");break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[577]:null),["h.i.q.bp"],[0,0],N,"q.bu.bv.bp",L))){break ifs;
+}}return J;}}),314:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[326].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[578],[],[],N,"ce.dk.jr.cd",L))){break ifs;
+}if((J=E(Q,P,B[579],[],[],N,"n.da.hi.cd",L))){break ifs;}if((J=E(Q,P,B[580],[],[],N,"n.da.hh.cd",L))){break ifs;
+}if((J=E(Q,P,B[581],[],[],N,"n.da.f.cd",L))){break ifs;}if((J=E(Q,P,B[582],[],[],N,"n.da.md.cd",L))){break ifs;
+}}return J;}}),517:({scopes:"bh.bp.bj.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[583],["h.bk.bj.bp"],[0,0],N,"bh.bp.bj.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[584],["h.i.q.bp"],[0,0],N,"q.bu.bv.bp",L))){break ifs;}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),424:({scopes:"d.e.s.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[585],["h.i.e.v"],[0,0],N,"d.e.s.v",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[586],[],[],N,"w.f.km.v",L))){break ifs;}if((J=H[434].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[436].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),500:({scopes:"d.e.y.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[587],["h.i.e.g"],[0,0],N,"d.e.y.g",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[588],["w.x.e.z.g"],[0,0],N,"d.e.y.z.g",L))){M.push(498);O.push(" d.e.y.z.g");break ifs;
+}if((J=E(Q,P,B[589],[],[],N,"n.f.hg.g",L))){M.push(499);O.push(" n.f.hg.g");break ifs;}if((J=E(Q,P,B[590],[],[],N,"be.bf.hp.g",L))){break ifs;
+}}return J;}}),125:({scopes:"q.r.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[591]:null),[],[],N,"q.r.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[174].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),355:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[592],["d.s.ch","ce.cf.ci.cj.ch","n.da.s.ch"],[0,1,1,2,2,0],N,"",L))){M.push(354);
+O.push("");break ifs;}}return J;}}),119:({scopes:"d.fa.fb.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[593],["h.i.fb.j.cm"],[0,0],N,"d.fa.fb.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[442],(P-1)))?B[594]:null),[],[],N,"",L))){M.push(117);
+O.push(" d.fa.fb.ga.cm");break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[444],(P-1)))?B[595]:null),[],[],N,"",L))){M.push(118);
+O.push(" d.fa.fb.fc.cm");break ifs;}}return J;}}),512:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[596],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[22].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),349:({scopes:"q.r.s.cl",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[597],[],[],N,"q.r.s.cl",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[344].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),148:({scopes:"k.bq.br.r.gm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[598]:B[599]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.gm.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),306:({scopes:"d.bo.du.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[600],["ce.cf.cd"],[0,0],N,"d.bo.du.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),199:({scopes:"k.bq.f.ei.ej.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[601],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.ej.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[244].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),1:({scopes:"bh.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[602],[],[],N,"d.kl.ey",L))){M.push(2);O.push(" d.kl.ey");break ifs;}if((J=H[11].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[603],["ce.cf.lk.ci.ey","h.i.ce.ey"],[0,1,1,0],N,"d.lk.ci.ey",L))){M.push(4);O.push(" d.lk.ci.ey");
+break ifs;}if((J=E(Q,P,B[604],["ce.cf.lk.me.ey","h.i.ce.ey","dp.n.me.ey"],[0,1,1,0,2,2],N,"d.lk.me.ey",L))){M.push(5);
+O.push(" d.lk.me.ey");break ifs;}if((J=E(Q,P,B[605],["h.bk.ka.ey"],[0,0],N,"d.ka.ey",L))){M.push(9);O.push(" d.ka.ey");
+break ifs;}}return J;}}),85:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[83].go(Q,P,K,M,O,L))){break ifs;}if((J=H[84].go(Q,P,K,M,O,L))){break ifs;}if((J=H[82].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),267:({scopes:"k.f.bq.gx.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[606],["h.i.k.j.bs"],[0,0],N,"k.f.bq.gx.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[263].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),351:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[607],["d.s.ch","ce.cf.ci.cj.ch","n.da.s.ch"],[0,1,1,2,2,0],N,"",L))){M.push(350);
+O.push("");break ifs;}}return J;}}),229:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[608],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[230].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),438:({scopes:"bh.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[609],["ce.f.mf.c","a.b.mf.c","h.hd.c"],[0,0,1,1,2,2],N,"d.mf.c",L))){break ifs;
+}if((J=E(Q,P,B[610],["ce.f.ci.c","a.b.ci.c","h.hd.c"],[0,0,1,1,2,2],N,"d.ci.c",L))){break ifs;}if((J=H[460].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[441].go(Q,P,K,M,O,L))){break ifs;}if((J=H[456].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),129:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[611],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[612],[],[],N,"",L))){M.push(127);
+O.push("");break ifs;}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[613]:null),[],[],N,"",L))){M.push(128);O.push("");
+break ifs;}}return J;}}),41:({scopes:"d.gi.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[614],[],[],N,"d.gi.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[47].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),496:({scopes:"d.e.s.v.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[615],["h.i.e.g"],[0,0],N,"d.e.s.v.g",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[526].go(Q,P,K,M,O,L))){break ifs;}if((J=H[523].go(Q,P,K,M,O,L))){break ifs;}if((J=H[525].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),66:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[616],["h.i.k.bl.bt"],[0,0],N,"k.bq.br.bs.bt",L))){M.push(65);O.push(" k.bq.br.bs.bt bh.bs.bj.bt");
+break ifs;}}return J;}}),353:({scopes:"q.r.s.cl.cs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[617],[],[],N,"q.r.s.cl.cs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[344].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),108:({scopes:"d.eq.hu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[618],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[139].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),290:({scopes:"k.bm.ca.g.cd u.g.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[619],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.g.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[494].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),312:({scopes:"d.bo.eb.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[620],["ce.cf.cd"],[0,0],N,"d.bo.eb.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),418:({scopes:"d.co.cp.cq.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[621],["ce.cf.cr"],[0,0],N,"d.co.cp.cq.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),16:({scopes:"bh.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[622],["dp.fn.m","dp.n.m","ce.dk.m"],[0,0,1,1,2,2],N,"d.fn.m",L))){break ifs;
+}if((J=E(Q,P,B[623],["dp.fn.m","dp.n.m","w.x.cu.m","ce.dk.m","a.cz.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7],N,"d.cu.mg.m",L))){break ifs;
+}if((J=E(Q,P,B[624],["dp.fn.m","dp.n.m","w.x.cu.m","ce.dk.m"],[0,0,1,1,2,2,3,3],N,"d.cu.m",L))){break ifs;
+}if((J=E(Q,P,B[625],["dp.fn.m","w.x.cu.m","ce.dk.m","a.cz.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6],N,"d.cu.m",L))){break ifs;
+}if((J=E(Q,P,B[626],["w.x.cu.m","ce.dk.m","a.cz.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,0,1,1,2,2,3,3,4,4,5,5],N,"d.cu.m",L))){break ifs;
+}if((J=E(Q,P,B[627],["a.cz.cu.m","w.x.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,0,1,1,2,2,3,3,4,4],N,"d.cu.m",L))){break ifs;
+}if((J=E(Q,P,B[628],["w.x.cu.m","a.cz.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,0,1,1,2,2,3,3,4,4],N,"d.cu.mh.m",L))){break ifs;
+}if((J=E(Q,P,B[629],["k.bq.bx.m","h.i.k.bl.m","w.x.cu.m","h.i.k.j.m","k.bq.br.m","h.i.k.bl.m","w.x.cu.m","h.i.k.j.m","w.x.cu.m","h.i.ef.bl.m","dw.gg.cu.m","h.i.ef.j.m"],[0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,8,8,9,9,10,10,11,11],N,"d.cu.mh.m",L))){break ifs;
+}if((J=E(Q,P,B[630],["ce.dk.lv.m","w.x.cz.kv.m"],[0,0,1,1],N,"d.fn.kv.ed",L))){break ifs;}if((J=E(Q,P,B[631],[],[],N,"w.x.cz.hv.m.mi",L))){break ifs;
+}if((J=E(Q,P,B[632],[],[],N,"dp.cu.m.mi",L))){break ifs;}if((J=E(Q,P,B[633],[],[],N,"n.da.m",L))){break ifs;
+}if((J=E(Q,P,B[634],["h.i.k.bl.m"],[0,0],N,"k.bq.bx.m",L))){M.push(17);O.push(" k.bq.bx.m");break ifs;
+}if((J=E(Q,P,B[635],["h.i.k.bl.m"],[0,0],N,"k.bq.br.m",L))){M.push(18);O.push(" k.bq.br.m");break ifs;
+}if((J=E(Q,P,B[636],["h.i.q.m"],[0,0],N,"q.r.gk.m",L))){M.push(19);O.push(" q.r.gk.m");break ifs;}if((J=E(Q,P,B[637],["h.i.q.m"],[0,0],N,"q.r.m",L))){M.push(20);
+O.push(" q.r.m");break ifs;}if((J=E(Q,P,B[638],["h.i.q.m"],[0,0],N,"q.bu.ez.m",L))){break ifs;}if((J=E(Q,P,B[639],["h.i.q.g.m"],[0,0],N,"q.r.g.m",L))){break ifs;
+}if((J=E(Q,P,B[640],[],[],N,"a.cz.m",L))){break ifs;}if((J=E(Q,P,B[641],[],[],N,"a.b.m",L))){break ifs;
+}if((J=E(Q,P,B[642],[],[],N,"ce.cf.m",L))){break ifs;}if((J=E(Q,P,B[643],[],[],N,"ce.dk.m",L))){break ifs;
+}if((J=E(Q,P,B[644],[],[],N,"n.im.mj.mk.m",L))){break ifs;}if((J=E(Q,P,B[645],[],[],N,"n.im.mj.ml.m",L))){break ifs;
+}if((J=E(Q,P,B[646],[],[],N,"n.im.mm.m",L))){break ifs;}if((J=E(Q,P,B[647],[],[],N,"dw.im.m",L))){break ifs;
+}if((J=E(Q,P,B[648],[],[],N,"ce.f.m",L))){break ifs;}if((J=E(Q,P,B[649],[],[],N,"dp.fn.m",L))){break ifs;
+}if((J=E(Q,P,B[650],[],[],N,"dp.cu.m",L))){break ifs;}if((J=E(Q,P,B[651],[],[],N,"dp.cu.mn.m",L))){break ifs;
+}if((J=E(Q,P,(G(Q,A[454],(P-1))?B[652]:null),[],[],N,"dp.n.m",L))){break ifs;}if((J=E(Q,P,(G(Q,A[454],(P-1))?B[653]:null),[],[],N,"dp.n.mn.m",L))){break ifs;
+}if((J=E(Q,P,B[654],[],[],N,"dp.n.mn.m",L))){break ifs;}if((J=E(Q,P,B[655],[],[],N,"dp.cu.mo.m",L))){break ifs;
+}if((J=E(Q,P,((!G(Q,A[491],(P-1)))?B[656]:B[657]),[],[],N,"ce.dk.m",L))){break ifs;}if((J=E(Q,P,B[658],[],[],N,"n.im.m",L))){break ifs;
+}if((J=E(Q,P,(((G(Q,A[238],(P-0))||G(Q,A[495],(P-1)))||G(Q,A[496],(P-6)))?B[659]:null),["h.i.k.bl.m"],[0,0],N,"k.l.m",L))){M.push(21);
+O.push(" k.l.m");break ifs;}if((J=E(Q,P,B[660],[],[],N,"h.hd.mp.m",L))){break ifs;}if((J=E(Q,P,B[661],[],[],N,"d.mq.hv.mr.m",L))){break ifs;
+}if((J=E(Q,P,B[662],[],[],N,"d.mq.ki.ms.m",L))){break ifs;}if((J=E(Q,P,B[663],[],[],N,"d.mt.mu.m",L))){break ifs;
+}if((J=E(Q,P,B[664],[],[],N,"d.mt.mv.m",L))){break ifs;}if((J=E(Q,P,B[665],[],[],N,"d.mt.mw.m",L))){break ifs;
+}}return J;}}),249:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[666],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[250].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),203:({scopes:"k.bq.f.ei.em.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[667],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.em.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[668],[],[],N,"n.o.p.bp",L))){break ifs;}if((J=H[248].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),341:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[669],[],[],N,"d.r.ch",L))){M.push(340);O.push(" d.r.ch");break ifs;}}return J;
+}}),43:({scopes:"d.cu.eu.iq.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[670],[],[],N,"d.cu.eu.iq.bt",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[51].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),492:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[671],["a.b.c"],[0,0],N,"d.mx.c",L))){M.push(491);O.push(" d.mx.c");break ifs;
+}}return J;}}),377:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[672],[],[],N,"d.r.ee",L))){M.push(376);O.push(" d.r.ee");break ifs;}}return J;
+}}),106:({scopes:"d.eq.cm d.eq.hu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[673],["h.i.hu.j.cm"],[0,0],N,"d.eq.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[139].go(Q,P,K,M,O,L))){break ifs;}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),400:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[674],[],[],N,"h.bc.ek.bu.cr",L))){break ifs;}if((J=E(Q,P,B[675],[],[],N,"ce.dk.cr",L))){break ifs;
+}if((J=E(Q,P,(((G(Q,A[238],(P-0))||G(Q,A[508],(P-2)))||G(Q,A[509],(P-4)))?B[676]:null),["ce.cf.cr"],[0,0],N,"",L))){break ifs;
+}if((J=E(Q,P,B[677],[],[],N,"h.bc.gc.hj.cr",L))){break ifs;}if((J=E(Q,P,B[678],[],[],N,"h.bk.en.cr",L))){break ifs;
+}if((J=E(Q,P,B[679],[],[],N,"ce.cf.cr",L))){break ifs;}if((J=E(Q,P,B[680],[],[],N,"ce.cf.jm.cr",L))){break ifs;
+}if((J=E(Q,P,B[681],[],[],N,"n.f.my.cr",L))){break ifs;}if((J=E(Q,P,B[682],[],[],N,"n.im.mj.cr",L))){break ifs;
+}if((J=E(Q,P,B[683],[],[],N,"n.im.mm.cr",L))){break ifs;}if((J=E(Q,P,B[684],[],[],N,"n.f.mz.cr",L))){break ifs;
+}if((J=E(Q,P,((G(Q,A[518],(P-8))||G(Q,A[519],(P-11)))?B[685]:null),[],[],N,"n.f.na.cr",L))){break ifs;
+}if((J=E(Q,P,B[686],[],[],N,"n.f.nb.cr",L))){break ifs;}if((J=E(Q,P,B[687],[],[],N,"n.f.nc.cr",L))){break ifs;
+}if((J=E(Q,P,B[688],[],[],N,"dw.im.cr",L))){break ifs;}if((J=E(Q,P,B[689],[],[],N,"dp.cu.nd.cr",L))){break ifs;
+}if((J=E(Q,P,B[690],[],[],N,"dp.fn.nd.cr",L))){break ifs;}if((J=E(Q,P,B[691],[],[],N,"n.da.cr",L))){break ifs;
+}if((J=E(Q,P,(G(Q,A[527],(P-4))?B[692]:null),["dw.f.cr"],[0,0],N,"",L))){break ifs;}}return J;}}),205:({scopes:"k.bq.f.ei.em.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[693],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.em.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[694],[],[],N,"n.o.p.bp",L))){break ifs;}if((J=H[228].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),263:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[695],["h.i.k.j.bs"],[0,0],N,"k.cn.bs",L))){break ifs;}}return J;}}),51:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[79].go(Q,P,K,M,O,L))){break ifs;}if((J=H[48].go(Q,P,K,M,O,L))){break ifs;}if((J=H[74].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[85].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[696],[],[],N,"ce.dk.ga.bt",L))){break ifs;}if((J=E(Q,P,B[697],[],[],N,"ce.dk.gh.bt",L))){break ifs;
+}if((J=E(Q,P,B[698],[],[],N,"a.b.jm.bt",L))){break ifs;}if((J=E(Q,P,B[699],["dp.cu.il.bt","h.i.ev.bl.bt"],[0,0,1,1],N,"d.ev.bt",L))){M.push(50);
+O.push(" d.ev.bt");break ifs;}if((J=H[28].go(Q,P,K,M,O,L))){break ifs;}if((J=H[26].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),375:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[700],[],[],N,"d.ne.ee",L))){M.push(374);O.push(" d.ne.ee");break ifs;
+}}return J;}}),510:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[519].go(Q,P,K,M,O,L))){break ifs;}if((J=H[513].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[521].go(Q,P,K,M,O,L))){break ifs;}if((J=H[515].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),87:({scopes:"d.fn.nf.cm w.x.cz.fn.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[701],["h.bk.fn.bl.cm"],[0,0],N,"d.fn.nf.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[131].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),140:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[702],[],[],N,"dw.im.cm",L))){break ifs;}}return J;}}),398:({scopes:"d.cu.gs.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[703],["ce.cf.gq.cr","w.x.cu.gr.cr"],[0,0,1,1],N,"d.cu.gs.cr",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[704],["ce.cf.ng.cr","dw.gg.gr.cr"],[0,0,1,1],N,"",L))){break ifs;
+}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),253:({scopes:"k.l.lt.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[705],["h.i.lt.bp"],[0,0],N,"k.l.lt.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),488:({scopes:"k.bq.br.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[706],["h.i.k.j.c"],[0,0],N,"k.bq.br.c",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[707],[],[],N,"n.o.p.c",L))){break ifs;}}return J;}}),127:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[708],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[142].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[143].go(Q,P,K,M,O,L))){break ifs;}if((J=H[137].go(Q,P,K,M,O,L))){break ifs;}if((J=H[136].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),68:({scopes:"k.bq.f.bz.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[709],[],[],N,"k.bq.f.bz.by.bs",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[710],[],[],N,"n.o.p.bt",L))){break ifs;}}return J;}}),37:({scopes:"q.r.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[711],["h.i.q.bt"],[0,0],N,"q.r.bt",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),5:({scopes:"d.lk.me.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[712],["ce.cf.lk.me.ey"],[0,0],N,"d.lk.me.ey",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[1].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),514:({scopes:"bh.cm.bj.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[713],[],[],N,"bh.cm.bj.g",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),259:({scopes:"k.l.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[714],["h.i.k.j.bs"],[0,0],N,"k.l.bs",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[263].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[715],[],[],N,"n.o.p.nh.bs",L))){break ifs;
+}}return J;}}),406:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[716],["h.bk.ev.cr"],[0,0],N,"d.fz.ev.cr",L))){M.push(403);O.push(" d.fz.ev.cr");
+break ifs;}if((J=E(Q,P,(G(Q,A[541],(P-12))?(G(Q,A[542],(P-4))?B[717]:B[718]):(G(Q,A[542],(P-4))?B[719]:null)),["h.i.k.cr"],[0,0],N,"k.bq.br.ni.cr",L))){M.push(404);
+O.push(" k.bq.br.ni.cr");break ifs;}if((J=E(Q,P,B[720],["h.i.k.cr"],[0,0],N,"k.bq.br.cr",L))){M.push(405);
+O.push(" k.bq.br.cr");break ifs;}if((J=E(Q,P,B[721],["h.i.gb.cr","h.i.gb.cr"],[0,0,1,1],N,"d.gb.cr",L))){break ifs;
+}if((J=E(Q,P,B[722],["h.i.fz.cr","dp.fn.nd.cr","a.cz.nj.cr","k.bm.fz.cr","h.i.fz.cr","ce.dk.cr","dp.fn.nd.cr"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6],N,"d.fz.cr",L))){break ifs;
+}}return J;}}),49:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[723],["ce.dk.fn.bt","d.eq.hv.bt","dw.f.hj.bt","h.i.dw.bt"],[0,0,1,1,2,3,3,2],N,"",L))){break ifs;
+}}return J;}}),77:({scopes:"k.bq.bx.bt d.ha.bq.bx.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[724],["h.i.k.j.bt"],[0,0],N,"k.bq.bx.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[725],[],[],N,"n.o.p.bt",L))){break ifs;}}return J;}}),404:({scopes:"k.bq.br.ni.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[726],["h.i.k.cr"],[0,0],N,"k.bq.br.ni.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[727],[],[],N,"n.o.p.cr",L))){break ifs;}}return J;}}),142:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[728],[],[],N,"dp.cu.hs.cm",L))){break ifs;}}return J;}}),195:({scopes:"k.l.fl.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[729],["h.i.k.j.bp"],[0,0],N,"k.l.fl.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[246].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),91:({scopes:"d.fn.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[730],["h.i.ht.j.cm","h.bk.fn.bl.cm","be.bf.ir.cm"],[0,0,1,1,2,2],N,"d.fn.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[731],[],[],N,"",L))){M.push(88);O.push(" w.x.cz.fn.cm");break ifs;
+}if((J=E(Q,P,B[732],["h.i.ht.bl.cm"],[0,0],N,"",L))){M.push(90);O.push(" d.fn.ht.cm");break ifs;}}return J;
+}}),185:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[733],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),339:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[734],[],[],N,"dw.f.nk.ch",L))){break ifs;}}return J;}}),437:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[735],["w.f.km.bb.v","w.f.km.v","h.bc.bb.v","w.f.km.bd.v"],[0,0,1,2,2,1,3,3],N,"",L))){break ifs;
+}if((J=H[434].go(Q,P,K,M,O,L))){break ifs;}if((J=H[436].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),292:({scopes:"k.bm.ca.ew.cd u.g.ew.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[736],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.ew.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if(false){break ifs;}}return J;}}),269:({scopes:"bh.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[274].go(Q,P,K,M,O,L))){break ifs;}if((J=H[317].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[304].go(Q,P,K,M,O,L))){break ifs;}if((J=H[279].go(Q,P,K,M,O,L))){break ifs;}if((J=H[313].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[282].go(Q,P,K,M,O,L))){break ifs;}if((J=H[323].go(Q,P,K,M,O,L))){break ifs;}if((J=H[326].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[302].go(Q,P,K,M,O,L))){break ifs;}if((J=H[297].go(Q,P,K,M,O,L))){break ifs;}if((J=H[298].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[319].go(Q,P,K,M,O,L))){break ifs;}if((J=H[316].go(Q,P,K,M,O,L))){break ifs;}if((J=H[303].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[324].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),494:({scopes:"u.g.nl",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[737],["h.i.e.g","w.x.e.g"],[0,0,1,1],N,"d.e.gv.g",L))){M.push(495);O.push(" d.e.gv.g");
+break ifs;}if((J=E(Q,P,B[738],["h.i.e.g","w.x.e.v.g"],[0,0,1,1],N,"d.e.s.v.g",L))){M.push(496);O.push(" d.e.s.v.g");
+break ifs;}if((J=E(Q,P,B[739],["h.i.q.g"],[0,0],N,"q.r.g",L))){M.push(497);O.push(" q.r.g");break ifs;
+}if((J=E(Q,P,B[740],["h.i.e.g"],[0,0],N,"d.e.y.g",L))){M.push(500);O.push(" d.e.y.g");break ifs;}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[741],["h.i.e.g","w.x.e.lq.g"],[0,0,1,1],N,"bh.ey.bj.g",L))){M.push(502);O.push(" bh.ey.bj.g");
+break ifs;}if((J=E(Q,P,B[742],["h.i.e.g","w.x.e.gn.g"],[0,0,1,1],N,"bh.m.bj.g",L))){M.push(505);O.push(" bh.m.bj.g");
+break ifs;}if((J=E(Q,P,B[743],["h.i.e.g","w.x.e.fa.gv.g"],[0,0,1,1],N,"d.e.fa.gv.g",L))){M.push(506);
+O.push(" d.e.fa.gv.g");break ifs;}if((J=E(Q,P,B[744],["h.i.e.bl.g","w.x.e.r.gv.g"],[0,0,1,1],N,"d.e.r.gv.g",L))){M.push(507);
+O.push(" d.e.r.gv.g");break ifs;}if((J=E(Q,P,B[745],["h.i.e.bl.g","w.x.e.fy.gv.g"],[0,0,1,1],N,"d.e.fy.gv.g",L))){M.push(508);
+O.push(" d.e.fy.gv.g");break ifs;}if((J=E(Q,P,B[746],["h.i.e.bl.g","w.x.e.f.g"],[0,0,1,1],N,"d.e.f.g",L))){M.push(509);
+O.push(" d.e.f.g");break ifs;}if((J=H[511].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[747],[],[],N,"be.bf.nm.g",L))){break ifs;
+}if((J=E(Q,P,B[748],[],[],N,"be.bf.nn.g",L))){break ifs;}}return J;}}),197:({scopes:"k.bq.f.ei.ej.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[749],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.ej.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[250].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),483:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[750],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),183:({scopes:"k.bq.bx.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[751],["h.i.k.j.bp"],[0,0],N,"k.bq.bx.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[752],[],[],N,"n.o.p.bp",L))){break ifs;}}return J;}}),146:({scopes:"k.bq.br.r.fj.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[753]:B[754]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.fj.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),271:({scopes:"d.bo.hf.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[755],[],[],N,"d.bo.hf.cd",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),56:({scopes:"k.l.lt.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[756],["h.i.lt.bt"],[0,0],N,"k.l.lt.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[757],[],[],N,"n.o.p.bt",L))){break ifs;}}return J;}}),442:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[758],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),453:({scopes:"d.i.fn.iu.iv.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[759],[],[],N,"d.i.fn.iu.iv.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[481].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[460].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),408:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[402].go(Q,P,K,M,O,L))){break ifs;}if((J=H[406].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[400].go(Q,P,K,M,O,L))){break ifs;}if((J=H[411].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),167:({scopes:"k.bq.bx.fi.eo.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[760],["h.i.k.j.cm","be.bf.fk.cm"],[0,0,1,1],N,"k.bq.bx.fi.eo.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),39:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[761],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[762],["dp.fn.gu.bt"],[0,0],N,"",L))){break ifs;
+}}return J;}}),95:({scopes:"d.cu.ef.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[763],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[139].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[764],["dw.gg.cu.cm","h.bc.ef.cm"],[0,0,1,1],N,"",L))){break ifs;}}return J;}}),102:({scopes:"d.cu.fm.hu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[765],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[139].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),310:({scopes:"d.bo.gl.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[766],[],[],N,"d.bo.gl.cd",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[273].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),187:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[767],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[230].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),357:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[768],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),479:({scopes:"a.cz.cq.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[769],[],[],N,"a.cz.cq.c",(function(){(L&&L());M.pop();O.pop();})))){}}return J;
+}}),251:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[770],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[252].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),379:({scopes:"d.cu.ed.eg.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[771],[],[],N,"d.cu.ed.eg.ee",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),157:({scopes:"k.bq.br.r.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[30],(P-3))?B[772]:B[773]),["h.i.k.j.cm","d.ep.br.cm"],[0,1,1,0],N,"k.bq.br.r.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),34:({scopes:"d.bj.m bh.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[774],["h.bk.bj.j.bt","ce.dk.ca.bt","h.i.k.bt"],[0,1,1,2,2,0],N,"d.bj.m",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[16].go(Q,P,K,M,O,L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),83:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[775],["h.i.dw.bt"],[0,0],N,"dw.f.hq.bt",L))){break ifs;}}return J;}}),469:({scopes:"d.ki.gb.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[776],[],[],N,"d.ki.gb.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[482].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),131:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[137].go(Q,P,K,M,O,L))){break ifs;}if((J=H[136].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),274:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,((!G(Q,A[574],(P-1)))?B[777]:null),["h.i.q.cd"],[0,0],N,"q.bu.bv.cd",L))){break ifs;
+}}return J;}}),508:({scopes:"d.e.fy.gv.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[778],["h.i.e.j.g"],[0,0],N,"d.e.fy.gv.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),498:({scopes:"d.e.y.z.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[779],[],[],N,"d.e.y.z.g",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[780],[],[],N,"k.bq.br.z.no.g",L))){break ifs;
+}}return J;}}),402:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[781],["h.i.q.cr"],[0,0],N,"q.bu.bw.cr",L))){break ifs;}if((J=E(Q,P,B[782],["h.i.q.cr"],[0,0],N,"q.r.cr",L))){M.push(401);
+O.push(" q.r.cr");break ifs;}}return J;}}),440:({scopes:"d.gd.ge.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[783],["h.i.gf.j.c"],[0,0],N,"d.gd.ge.c",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[784],["n.f.ga.c","ce.dk.gh.c"],[0,0,1,1],N,"",L))){break ifs;}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[785],[],[],N,"h.np.hj.c",L))){break ifs;}}return J;}}),193:({scopes:"k.l.fl.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[786],["h.i.k.j.bp"],[0,0],N,"k.l.fl.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[232].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),144:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[388].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),333:({scopes:"d.s.nq.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[787],[],[],N,"d.s.nq.ch",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[788],[],[],N,"h.bc.ek.ch",L))){break ifs;
+}}return J;}}),81:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[789],["dp.cu.il.bt","h.i.ev.bl.bt"],[0,0,1,1],N,"d.ev.bt",L))){M.push(80);
+O.push(" d.ev.bt");break ifs;}if((J=E(Q,P,B[790],[],[],N,"dp.cu.ev.bt",L))){break ifs;}if((J=E(Q,P,B[791],[],[],N,"dp.cu.ly.bt",L))){break ifs;
+}if((J=E(Q,P,B[792],[],[],N,"dp.cu.nr.bt",L))){break ifs;}if((J=E(Q,P,B[793],[],[],N,"dp.cu.ns.bt",L))){break ifs;
+}if((J=E(Q,P,B[794],[],[],N,"dp.cu.nt.bt",L))){break ifs;}if((J=E(Q,P,B[795],[],[],N,"dp.cu.nu.bt",L))){break ifs;
+}if((J=E(Q,P,B[796],[],[],N,"dp.cu.nv.bt",L))){break ifs;}if((J=E(Q,P,B[797],[],[],N,"dp.cu.nw.bt",L))){break ifs;
+}if((J=E(Q,P,B[798],[],[],N,"dp.cu.nx.bt",L))){break ifs;}if((J=E(Q,P,B[799],[],[],N,"dp.cu.ny.bt",L))){break ifs;
+}if((J=E(Q,P,B[800],[],[],N,"dp.cu.nz.bt",L))){break ifs;}if((J=E(Q,P,B[801],[],[],N,"dp.cu.oa.bt",L))){break ifs;
+}if((J=E(Q,P,B[802],[],[],N,"dp.cu.ob.bt",L))){break ifs;}if((J=E(Q,P,B[803],[],[],N,"dp.cu.oc.bt",L))){break ifs;
+}if((J=E(Q,P,B[804],[],[],N,"dp.cu.od.bt",L))){break ifs;}if((J=E(Q,P,B[805],[],[],N,"dp.cu.oe.bt",L))){break ifs;
+}if((J=E(Q,P,B[806],[],[],N,"dp.cu.of.bt",L))){break ifs;}if((J=E(Q,P,B[807],[],[],N,"dp.cu.og.bt",L))){break ifs;
+}if((J=E(Q,P,B[808],[],[],N,"dp.cu.oh.bt",L))){break ifs;}if((J=E(Q,P,B[809],[],[],N,"dp.cu.oi.bt",L))){break ifs;
+}if((J=E(Q,P,B[810],[],[],N,"dp.cu.oj.bt",L))){break ifs;}if((J=E(Q,P,B[811],[],[],N,"dp.cu.ok.bt",L))){break ifs;
+}if((J=E(Q,P,B[812],[],[],N,"dp.cu.ol.bt",L))){break ifs;}if((J=E(Q,P,B[813],[],[],N,"dp.cu.om.bt",L))){break ifs;
+}if((J=E(Q,P,B[814],[],[],N,"dp.cu.on.bt",L))){break ifs;}if((J=E(Q,P,B[815],[],[],N,"dp.cu.oo.bt",L))){break ifs;
+}if((J=E(Q,P,B[816],[],[],N,"dp.cu.op.bt",L))){break ifs;}if((J=E(Q,P,B[817],[],[],N,"dp.cu.oq.bt",L))){break ifs;
+}if((J=E(Q,P,B[818],[],[],N,"dp.cu.or.bt",L))){break ifs;}if((J=E(Q,P,B[819],[],[],N,"dp.cu.os.bt",L))){break ifs;
+}if((J=E(Q,P,B[820],[],[],N,"dp.cu.ot.bt",L))){break ifs;}if((J=E(Q,P,B[821],[],[],N,"dp.cu.ou.bt",L))){break ifs;
+}if((J=E(Q,P,B[822],[],[],N,"dp.cu.ov.bt",L))){break ifs;}if((J=E(Q,P,B[823],[],[],N,"dp.cu.ow.bt",L))){break ifs;
+}if((J=E(Q,P,B[824],[],[],N,"dp.cu.ox.bt",L))){break ifs;}if((J=E(Q,P,B[825],[],[],N,"dp.cu.oy.bt",L))){break ifs;
+}if((J=E(Q,P,B[826],[],[],N,"dp.cu.oz.bt",L))){break ifs;}if((J=E(Q,P,B[827],[],[],N,"dp.cu.pa.bt",L))){break ifs;
+}if((J=E(Q,P,B[828],[],[],N,"dp.cu.pb.bt",L))){break ifs;}if((J=E(Q,P,B[829],[],[],N,"dp.cu.pc.bt",L))){break ifs;
+}if((J=E(Q,P,B[830],[],[],N,"dp.cu.pd.bt",L))){break ifs;}if((J=E(Q,P,B[831],[],[],N,"dp.cu.pe.bt",L))){break ifs;
+}if((J=E(Q,P,B[832],[],[],N,"dp.cu.pf.bt",L))){break ifs;}if((J=E(Q,P,B[833],[],[],N,"dp.cu.pg.bt",L))){break ifs;
+}if((J=E(Q,P,B[834],[],[],N,"dp.cu.ph.bt",L))){break ifs;}if((J=E(Q,P,B[835],[],[],N,"dp.cu.pi.bt",L))){break ifs;
+}if((J=E(Q,P,B[836],[],[],N,"dp.cu.pj.bt",L))){break ifs;}if((J=E(Q,P,B[837],[],[],N,"dp.cu.pk.bt",L))){break ifs;
+}if((J=E(Q,P,B[838],[],[],N,"dp.cu.pl.bt",L))){break ifs;}if((J=E(Q,P,B[839],[],[],N,"dp.cu.pm.bt",L))){break ifs;
+}if((J=E(Q,P,B[840],[],[],N,"dp.cu.g.bt",L))){break ifs;}if((J=E(Q,P,B[841],[],[],N,"dp.cu.pn.bt",L))){break ifs;
+}if((J=E(Q,P,B[842],[],[],N,"dp.cu.po.bt",L))){break ifs;}if((J=E(Q,P,B[843],[],[],N,"dp.cu.pp.bt",L))){break ifs;
+}if((J=E(Q,P,B[844],[],[],N,"dp.cu.pq.bt",L))){break ifs;}if((J=E(Q,P,B[845],[],[],N,"dp.cu.pr.bt",L))){break ifs;
+}if((J=E(Q,P,B[846],[],[],N,"dp.cu.ps.bt",L))){break ifs;}if((J=E(Q,P,B[847],[],[],N,"dp.cu.pt.bt",L))){break ifs;
+}if((J=E(Q,P,B[848],[],[],N,"dp.cu.pu.bt",L))){break ifs;}if((J=E(Q,P,B[849],[],[],N,"dp.cu.pv.bt",L))){break ifs;
+}if((J=E(Q,P,B[850],[],[],N,"dp.cu.fg.bt",L))){break ifs;}if((J=E(Q,P,B[851],[],[],N,"dp.cu.pw.bt",L))){break ifs;
+}if((J=E(Q,P,B[852],[],[],N,"dp.cu.mh.bt",L))){break ifs;}if((J=E(Q,P,B[853],[],[],N,"dp.cu.px.bt",L))){break ifs;
+}if((J=E(Q,P,B[854],[],[],N,"dp.cu.py.bt",L))){break ifs;}if((J=E(Q,P,B[855],[],[],N,"dp.cu.pz.bt",L))){break ifs;
+}if((J=E(Q,P,B[856],[],[],N,"dp.cu.qa.bt",L))){break ifs;}if((J=E(Q,P,B[857],[],[],N,"dp.cu.fx.bt",L))){break ifs;
+}if((J=E(Q,P,B[858],[],[],N,"dp.cu.qb.bt",L))){break ifs;}if((J=E(Q,P,B[859],[],[],N,"dp.cu.qc.bt",L))){break ifs;
+}if((J=E(Q,P,B[860],[],[],N,"dp.cu.dn.bt",L))){break ifs;}if((J=E(Q,P,B[861],[],[],N,"dp.cu.qd.bt",L))){break ifs;
+}if((J=E(Q,P,B[862],[],[],N,"dp.cu.qe.bt",L))){break ifs;}if((J=E(Q,P,B[863],[],[],N,"dp.cu.qf.bt",L))){break ifs;
+}if((J=E(Q,P,B[864],[],[],N,"dp.cu.qg.bt",L))){break ifs;}if((J=E(Q,P,B[865],[],[],N,"dp.cu.qh.bt",L))){break ifs;
+}if((J=E(Q,P,B[866],[],[],N,"dp.cu.qi.bt",L))){break ifs;}if((J=E(Q,P,B[867],[],[],N,"dp.cu.qj.bt",L))){break ifs;
+}if((J=E(Q,P,B[868],[],[],N,"dp.cu.qk.bt",L))){break ifs;}if((J=E(Q,P,B[869],[],[],N,"dp.cu.ql.bt",L))){break ifs;
+}if((J=E(Q,P,B[870],[],[],N,"dp.cu.qm.bt",L))){break ifs;}if((J=E(Q,P,B[871],[],[],N,"dp.cu.qn.bt",L))){break ifs;
+}if((J=E(Q,P,B[872],[],[],N,"dp.cu.qo.bt",L))){break ifs;}if((J=E(Q,P,B[873],[],[],N,"dp.cu.qp.bt",L))){break ifs;
+}if((J=E(Q,P,B[874],[],[],N,"dp.cu.qq.bt",L))){break ifs;}if((J=E(Q,P,B[875],[],[],N,"dp.cu.qr.bt",L))){break ifs;
+}if((J=E(Q,P,B[876],[],[],N,"dp.cu.qs.bt",L))){break ifs;}if((J=E(Q,P,B[877],[],[],N,"dp.cu.qt.bt",L))){break ifs;
+}if((J=E(Q,P,B[878],[],[],N,"dp.cu.qu.bt",L))){break ifs;}if((J=E(Q,P,B[879],[],[],N,"dp.cu.qv.bt",L))){break ifs;
+}if((J=E(Q,P,B[880],[],[],N,"dp.cu.qw.bt",L))){break ifs;}if((J=E(Q,P,B[881],[],[],N,"dp.cu.qx.bt",L))){break ifs;
+}if((J=E(Q,P,B[882],[],[],N,"dp.cu.qy.bt",L))){break ifs;}if((J=E(Q,P,B[883],[],[],N,"dp.cu.qz.bt",L))){break ifs;
+}if((J=E(Q,P,B[884],[],[],N,"dp.cu.ra.bt",L))){break ifs;}if((J=E(Q,P,B[885],[],[],N,"dp.cu.rb.bt",L))){break ifs;
+}if((J=E(Q,P,B[886],[],[],N,"dp.cu.rc.bt",L))){break ifs;}if((J=E(Q,P,B[887],[],[],N,"dp.cu.rd.bt",L))){break ifs;
+}if((J=E(Q,P,B[888],[],[],N,"dp.cu.re.bt",L))){break ifs;}if((J=E(Q,P,B[889],[],[],N,"dp.cu.rf.bt",L))){break ifs;
+}if((J=E(Q,P,B[890],[],[],N,"dp.cu.rg.bt",L))){break ifs;}if((J=E(Q,P,B[891],[],[],N,"dp.cu.rh.bt",L))){break ifs;
+}if((J=E(Q,P,B[892],[],[],N,"dp.cu.ri.bt",L))){break ifs;}if((J=E(Q,P,B[893],[],[],N,"dp.cu.rj.bt",L))){break ifs;
+}if((J=E(Q,P,B[894],[],[],N,"dp.cu.rk.bt",L))){break ifs;}if((J=E(Q,P,B[895],[],[],N,"dp.cu.rl.bt",L))){break ifs;
+}if((J=E(Q,P,B[896],[],[],N,"dp.cu.rm.bt",L))){break ifs;}if((J=E(Q,P,B[897],[],[],N,"dp.cu.rn.bt",L))){break ifs;
+}if((J=E(Q,P,B[898],[],[],N,"dp.cu.ro.bt",L))){break ifs;}if((J=E(Q,P,B[899],[],[],N,"dp.cu.rp.bt",L))){break ifs;
+}if((J=E(Q,P,B[900],[],[],N,"dp.cu.rq.bt",L))){break ifs;}if((J=E(Q,P,B[901],[],[],N,"dp.cu.rr.bt",L))){break ifs;
+}if((J=E(Q,P,B[902],[],[],N,"dp.cu.rs.bt",L))){break ifs;}if((J=E(Q,P,B[903],[],[],N,"dp.cu.rt.bt",L))){break ifs;
+}if((J=E(Q,P,B[904],[],[],N,"dp.cu.ru.bt",L))){break ifs;}if((J=E(Q,P,B[905],[],[],N,"dp.cu.rv.bt",L))){break ifs;
+}if((J=E(Q,P,B[906],[],[],N,"dp.cu.rw.bt",L))){break ifs;}if((J=E(Q,P,B[907],[],[],N,"dp.cu.rx.bt",L))){break ifs;
+}if((J=E(Q,P,B[908],[],[],N,"dp.cu.ry.bt",L))){break ifs;}if((J=E(Q,P,B[909],[],[],N,"dp.cu.rz.bt",L))){break ifs;
+}if((J=E(Q,P,B[910],[],[],N,"dp.cu.sa.bt",L))){break ifs;}if((J=E(Q,P,B[911],[],[],N,"dp.cu.sb.bt",L))){break ifs;
+}if((J=E(Q,P,B[912],[],[],N,"dp.cu.sc.bt",L))){break ifs;}if((J=E(Q,P,B[913],[],[],N,"dp.cu.sd.bt",L))){break ifs;
+}if((J=E(Q,P,B[914],[],[],N,"dp.cu.se.bt",L))){break ifs;}if((J=E(Q,P,B[915],[],[],N,"dp.cu.sf.bt",L))){break ifs;
+}if((J=E(Q,P,B[916],[],[],N,"dp.cu.sg.bt",L))){break ifs;}if((J=E(Q,P,B[917],[],[],N,"dp.cu.sh.bt",L))){break ifs;
+}if((J=E(Q,P,B[918],[],[],N,"dp.cu.si.bt",L))){break ifs;}if((J=E(Q,P,B[919],[],[],N,"dp.cu.sj.bt",L))){break ifs;
+}if((J=E(Q,P,B[920],[],[],N,"dp.cu.sk.bt",L))){break ifs;}if((J=E(Q,P,B[921],[],[],N,"dp.cu.sl.bt",L))){break ifs;
+}if((J=E(Q,P,B[922],[],[],N,"dp.cu.sm.bt",L))){break ifs;}if((J=E(Q,P,B[923],[],[],N,"dp.cu.sn.bt",L))){break ifs;
+}if((J=E(Q,P,B[924],[],[],N,"dp.cu.so.bt",L))){break ifs;}if((J=E(Q,P,B[925],[],[],N,"dp.cu.sp.bt",L))){break ifs;
+}if((J=E(Q,P,B[926],[],[],N,"dp.cu.sq.bt",L))){break ifs;}if((J=E(Q,P,B[927],[],[],N,"dp.cu.sr.bt",L))){break ifs;
+}if((J=E(Q,P,B[928],[],[],N,"dp.cu.k.bt",L))){break ifs;}if((J=E(Q,P,B[929],[],[],N,"dp.cu.ss.bt",L))){break ifs;
+}if((J=E(Q,P,B[930],[],[],N,"dp.cu.st.bt",L))){break ifs;}if((J=E(Q,P,B[931],[],[],N,"dp.cu.su.bt",L))){break ifs;
+}if((J=E(Q,P,B[932],[],[],N,"dp.cu.sv.bt",L))){break ifs;}if((J=E(Q,P,B[933],[],[],N,"dp.cu.sw.bt",L))){break ifs;
+}if((J=E(Q,P,B[934],[],[],N,"dp.cu.u.bt",L))){break ifs;}if((J=E(Q,P,B[935],[],[],N,"dp.cu.sx.bt",L))){break ifs;
+}if((J=E(Q,P,B[936],[],[],N,"dp.cu.sy.bt",L))){break ifs;}if((J=E(Q,P,B[937],[],[],N,"dp.cu.cz.bt",L))){break ifs;
+}if((J=E(Q,P,B[938],[],[],N,"dp.cu.sz.bt",L))){break ifs;}if((J=E(Q,P,B[939],[],[],N,"dp.cu.ll.bt",L))){break ifs;
+}if((J=E(Q,P,B[940],[],[],N,"dp.cu.ta.bt",L))){break ifs;}if((J=E(Q,P,B[941],[],[],N,"dp.cu.tb.bt",L))){break ifs;
+}if((J=E(Q,P,B[942],[],[],N,"dp.cu.tc.bt",L))){break ifs;}if((J=E(Q,P,B[943],[],[],N,"dp.cu.td.bt",L))){break ifs;
+}if((J=E(Q,P,B[944],[],[],N,"dp.cu.te.bt",L))){break ifs;}if((J=E(Q,P,B[945],[],[],N,"dp.cu.tf.bt",L))){break ifs;
+}if((J=E(Q,P,B[946],[],[],N,"dp.cu.tg.bt",L))){break ifs;}if((J=E(Q,P,B[947],[],[],N,"dp.cu.v.bt",L))){break ifs;
+}if((J=E(Q,P,B[948],[],[],N,"dp.cu.th.bt",L))){break ifs;}if((J=E(Q,P,B[949],[],[],N,"dp.cu.ti.bt",L))){break ifs;
+}if((J=E(Q,P,B[950],[],[],N,"dp.cu.tj.bt",L))){break ifs;}if((J=E(Q,P,B[951],[],[],N,"dp.cu.tk.bt",L))){break ifs;
+}if((J=E(Q,P,B[952],[],[],N,"dp.cu.di.bt",L))){break ifs;}if((J=E(Q,P,B[953],[],[],N,"dp.fn.jg.bt",L))){break ifs;
+}if((J=E(Q,P,B[954],[],[],N,"dp.cu.il.bt",L))){break ifs;}}return J;}}),391:({scopes:"d.en.jf.tl.l",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[955],[],[],N,"d.en.jf.tl.l",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[388].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),191:({scopes:"k.l.tm.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[956],["k.l.tm.bp","h.i.k.bp"],[0,1,1,0],N,"",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),328:({scopes:"q.r.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[957],["h.i.q.ch"],[0,0],N,"q.r.ch",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),247:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[958],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[248].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),335:({scopes:"k.bq.f.gj.gi.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[959],["h.i.k.j.ch"],[0,0],N,"k.bq.f.gj.gi.ch",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),504:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[960],["h.i.e.g","w.x.e.gn.g"],[0,0,1,1],N,"",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[961],["h.i.q.m"],[0,0],N,"q.bu.ez.m",L))){break ifs;}if((J=E(Q,P,B[962],["h.i.q.m"],[0,0],N,"q.r.m",L))){M.push(503);
+O.push(" q.r.m");break ifs;}if((J=H[513].go(Q,P,K,M,O,L))){break ifs;}if((J=H[16].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),265:({scopes:"k.bq.f.bz.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[963],["h.i.k.j.bs"],[0,0],N,"k.bq.f.bz.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[262].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),414:({scopes:"d.co.cp.fo.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[964],["ce.cf.cr"],[0,0],N,"d.co.cp.fo.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[407].go(Q,P,K,M,O,L))){break ifs;}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),104:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[965],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[130].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),521:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[966],["bh.tn.bj.g","dp.cu.nd.tn"],[0,1,1,0],N,"",L))){M.push(520);O.push("");
+break ifs;}}return J;}}),393:({scopes:"n.f.lt.to.l",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[967],["h.i.lt.l"],[0,0],N,"n.f.lt.to.l",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[394].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[968],["n.o.p.tq.l","n.o.p.tq.l"],[0,0,1,1],N,"n.f.lt.tp.l",L))){break ifs;
+}}return J;}}),31:({scopes:"d.bj.g u.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[969],["h.bk.bj.j.bt","ce.dk.ca.bt","h.i.k.bt"],[0,1,1,2,2,0],N,"d.bj.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[494].go(Q,P,K,M,O,L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),322:({scopes:"k.bq.bx.es.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[970],["h.i.k.j.cd"],[0,0],N,"k.bq.bx.es.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[971],[],[],N,"n.o.p.tr.cd",L))){break ifs;}if((J=E(Q,P,B[972],[],[],N,"n.o.p.hh.cd",L))){break ifs;
+}if((J=E(Q,P,B[973],[],[],N,"n.o.p.hi.cd",L))){break ifs;}if((J=E(Q,P,B[974],[],[],N,"n.o.p.ts.cd",L))){break ifs;
+}}return J;}}),316:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[756],(P-1)))?B[975]:null),[],[],N,"ce.dk.tt.cd",L))){break ifs;
+}if((J=E(Q,P,B[976],[],[],N,"ce.dk.tu.cd",L))){break ifs;}if((J=E(Q,P,B[977],["ce.dk.gy.cd","h.i.gy.cd"],[0,0,1,1],N,"d.fa.gy.cd",L))){M.push(315);
+O.push(" d.fa.gy.cd");break ifs;}}return J;}}),133:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[978],["n.o.p.hi.cm","n.o.p.hh.cm","n.o.p.tv.cm","n.o.p.tw.cm","n.o.p.tx.cm","n.o.p.ty.cm","n.o.p.tz.cm","n.o.p.ua.cm","n.o.p.ub.cm","n.o.p.uc.cm","n.o.p.ud.cm","n.o.p.ue.cm","n.o.p.uf.cm"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12],N,"",L))){break ifs;
+}}return J;}}),416:({scopes:"d.co.cp.hx.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[979],["ce.cf.cr"],[0,0],N,"d.co.cp.hx.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[409].go(Q,P,K,M,O,L))){break ifs;}if((J=H[410].go(Q,P,K,M,O,L))){break ifs;}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),444:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[980],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[981],[],[],N,"",L))){M.push(442);
+O.push("");break ifs;}if((J=E(Q,P,B[982],[],[],N,"",L))){M.push(443);O.push("");break ifs;}}return J;
+}}),189:({scopes:"k.cn.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[983],["h.i.k.j.bp"],[0,0],N,"k.cn.bp",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[250].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),468:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[984],[],[],N,"ce.cf.ug.c",L))){break ifs;}if((J=E(Q,P,B[985],[],[],N,"ce.cf.c",L))){break ifs;
+}if((J=E(Q,P,B[986],[],[],N,"ce.cf.c",L))){break ifs;}if((J=E(Q,P,B[987],[],[],N,"ce.dk.c",L))){break ifs;
+}if((J=E(Q,P,B[988],[],[],N,"ce.dk.dm.c",L))){break ifs;}if((J=E(Q,P,B[989],[],[],N,"ce.dk.gh.c",L))){break ifs;
+}if((J=E(Q,P,B[990],[],[],N,"ce.dk.jq.c",L))){break ifs;}if((J=E(Q,P,B[991],[],[],N,"ce.dk.jr.c",L))){break ifs;
+}if((J=E(Q,P,B[992],[],[],N,"ce.dk.fe.c",L))){break ifs;}if((J=E(Q,P,(G(Q,A[769],(P-1))?B[993]:null),[],[],N,"ce.dk.hw.c",L))){break ifs;
+}if((J=E(Q,P,B[994],[],[],N,"h.hd.c",L))){break ifs;}}return J;}}),70:({scopes:"k.bq.bx.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[995],["n.o.p.bt"],[0,0],N,"k.bq.bx.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),231:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[996],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[232].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),388:({scopes:"bh.l.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[997],[],[],N,"ce.cf.uh.l",L))){break ifs;}if((J=E(Q,P,B[998],[],[],N,"ce.f.ui.l",L))){break ifs;
+}if((J=E(Q,P,B[999],[],[],N,"ce.dk.uj.l",L))){break ifs;}if((J=E(Q,P,B[1000],[],[],N,"ce.dk.uk.l",L))){break ifs;
+}if((J=E(Q,P,B[1001],[],[],N,"q.r.l",L))){M.push(389);O.push(" q.r.l");break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[1002]:null),[],[],N,"q.bu.bv.l",L))){break ifs;
+}if((J=E(Q,P,B[1003],[],[],N,"ce.f.ul.l",L))){break ifs;}if((J=E(Q,P,B[1004],[],[],N,"ce.f.ui.um.l",L))){break ifs;
+}if((J=E(Q,P,B[1005],["h.i.en.l","h.i.en.jf.l","d.jf.un.l","d.jf.uo.l","d.jf.up.l","d.jf.uq.l"],[0,0,1,2,2,3,3,4,4,5,5,1],N,"d.en.jf.l",L))){M.push(390);
+O.push(" d.en.jf.l");break ifs;}if((J=E(Q,P,B[1006],["h.i.en.l","h.i.en.jf.tl.l","w.x.bk.ui.l"],[0,0,1,2,2,1],N,"d.en.jf.tl.l",L))){M.push(391);
+O.push(" d.en.jf.tl.l");break ifs;}if((J=E(Q,P,B[1007],["h.i.en.l","h.i.en.ur.l","w.x.bk.en.l","h.i.en.ur.l","h.i.en.us.l"],[0,0,1,1,2,2,3,3,4,4],N,"d.en.l",L))){M.push(392);
+O.push(" d.en.l");break ifs;}if((J=H[394].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),323:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1008],[],[],N,"n.o.p.cd",L))){break ifs;}if((J=E(Q,P,B[1009],["h.i.k.bl.cd"],[0,0],N,"k.bq.bx.cd",L))){M.push(320);
+O.push(" k.bq.bx.cd");break ifs;}if((J=E(Q,P,B[1010],["h.i.k.bl.cd"],[0,0],N,"k.bq.br.cd",L))){M.push(321);
+O.push(" k.bq.br.cd");break ifs;}if((J=E(Q,P,B[1011],["h.i.k.bl.cd"],[0,0],N,"k.bq.bx.es.cd",L))){M.push(322);
+O.push(" k.bq.bx.es.cd");break ifs;}}return J;}}),93:({scopes:"d.fn.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1012],["h.i.ht.bl.cm","be.bf.ut.cm"],[0,0,1,1],N,"d.fn.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[1013],[],[],N,"",L))){M.push(92);O.push(" w.x.cz.fn.cm");break ifs;
+}}return J;}}),212:({scopes:"k.bm.bj.g.bp u.g.bj.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1014],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.g.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[494].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),466:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1015],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[1016],["n.f.jj.c"],[0,0],N,"d.jj.c",L))){M.push(465);
+O.push(" d.jj.c");break ifs;}}return J;}}),72:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1017],["h.i.k.bl.bt"],[0,0],N,"k.bq.bx.bs.bt",L))){M.push(71);O.push(" k.bq.bx.bs.bt bh.bs.bj.bt");
+break ifs;}}return J;}}),520:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1018],["bh.tn.bj.g","dp.cu.nd.tn"],[0,1,1,0],N,"",(function(){(L&&L());
+M.pop();O.pop();})))){}}return J;}}),394:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1019],[],[],N,"n.o.lt.l",L))){break ifs;}if((J=E(Q,P,B[1020],[],[],N,"n.o.p.tq.l",L))){break ifs;
+}if((J=E(Q,P,B[1021],["h.i.lt.l","ce.dk.uu.l"],[0,0,1,1],N,"n.f.lt.to.l",L))){M.push(393);O.push(" n.f.lt.to.l");
+break ifs;}}return J;}}),180:({scopes:"d.cu.ki.kj.bp dw.gg.cu.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1022],[],[],N,"d.cu.ki.kj.bp",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),11:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1023],["h.i.q.ey"],[0,0],N,"q.r.ey",L))){M.push(10);O.push(" q.r.ey");
+break ifs;}}return J;}}),384:({scopes:"d.ib.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[125],(P-1))?B[1024]:B[1025]),[],[],N,"d.ib.ee",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[375].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1026],["h.i.bo.ee"],[0,0],N,"",L))){M.push(383);
+O.push("");break ifs;}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),210:({scopes:"u.uv",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1027],["k.bm.uw.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[1028],[],[],N,"u.g.bj.bp",L))){M.push(209);O.push(" u.g.bj.bp");break ifs;}}return J;
+}}),294:({scopes:"k.bm.ca.cc.cd u.g.cc.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1029],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cc.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if(false){break ifs;}}return J;}}),327:({scopes:"bh.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[359].go(Q,P,K,M,O,L))){break ifs;}if((J=H[351].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[365].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1030],["h.i.q.ch"],[0,0],N,"q.r.ch",L))){M.push(328);
+O.push(" q.r.ch");break ifs;}if((J=E(Q,P,B[1031],[],[],N,"be.bf.ux.ch",L))){break ifs;}if((J=E(Q,P,B[1032],["h.i.q.ch"],[0,0],N,"q.bu.ez.ee",L))){M.push(329);
+O.push(" q.bu.ez.ee");break ifs;}if((J=E(Q,P,B[1033],[],[],N,"ce.cf.ch",L))){break ifs;}if((J=E(Q,P,B[1034],[],[],N,"a.cz.ch",L))){break ifs;
+}if((J=E(Q,P,B[1035],[],[],N,"a.b.ch",L))){break ifs;}if((J=E(Q,P,B[1036],[],[],N,"n.f.dw.uy.ch",L))){break ifs;
+}if((J=E(Q,P,B[1037],[],[],N,"dw.f.ku.hq.uy.ch",L))){break ifs;}if((J=E(Q,P,B[1038],[],[],N,"dw.f.ku.jn.uy.ch",L))){break ifs;
+}if((J=E(Q,P,B[1039],[],[],N,"n.im.ch",L))){break ifs;}if((J=H[368].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1040],[],[],N,"n.da.ch",L))){break ifs;
+}if((J=E(Q,P,B[1041],["h.i.k.bl.ch"],[0,0],N,"k.bq.br.ch",L))){M.push(330);O.push(" k.bq.br.ch");break ifs;
+}if((J=E(Q,P,B[1042],["h.i.k.bl.ch"],[0,0],N,"k.bq.bx.ch",L))){M.push(331);O.push(" k.bq.bx.ch");break ifs;
+}if((J=E(Q,P,B[1043],["ce.cf.ci.uz.ch","w.x.cu.s.ch","h.i.ef.ch","dw.gg.s.ch","h.bc.ef.ch","h.i.ef.ch"],[0,0,1,1,2,2,3,4,4,3,5,5],N,"d.s.jt.ch",L))){M.push(332);
+O.push(" d.s.jt.ch");break ifs;}if((J=E(Q,P,B[1044],["ce.cf.ci.va.ch"],[0,0],N,"d.s.nq.ch",L))){M.push(333);
+O.push(" d.s.nq.ch");break ifs;}if((J=E(Q,P,B[1045],["ce.cf.ci.gi.ch"],[0,0],N,"d.s.ch.gi",L))){M.push(336);
+O.push(" d.s.ch.gi");break ifs;}if((J=H[347].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1046],["ce.cf.ci.ch"],[0,0],N,"d.s.ch",L))){M.push(337);
+O.push(" d.s.ch");break ifs;}if((J=E(Q,P,B[1047],[],[],N,"dp.cz.vb.ch",L))){break ifs;}if((J=E(Q,P,B[1048],[],[],N,"dp.cz.vc.ch",L))){break ifs;
+}if((J=E(Q,P,B[1049],[],[],N,"dp.cz.vd.ch",L))){break ifs;}if((J=E(Q,P,B[1050],[],[],N,"dp.n.uy.ch",L))){break ifs;
+}if((J=E(Q,P,B[1051],[],[],N,"dp.cz.uy.ch",L))){break ifs;}if((J=H[341].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,((!((G(Q,A[812],(P-3))||G(Q,A[813],(P-4)))||G(Q,A[496],(P-6))))?(G(Q,A[814],(P-1))?((!G(Q,A[815],(P-2)))?(G(Q,A[816],(P-1))?B[1052]:B[1053]):B[1054]):((!G(Q,A[815],(P-2)))?(G(Q,A[816],(P-1))?B[1055]:B[1056]):B[1057])):((!G(Q,A[815],(P-2)))?(G(Q,A[816],(P-1))?B[1058]:B[1059]):B[1060])),["h.if.cu.ig.ch","w.x.cu.ch"],[0,0,1,1],N,"d.cu.ch",L))){M.push(338);
+O.push(" d.cu.ch");break ifs;}}return J;}}),153:({scopes:"k.bq.br.fi.gm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[1061]:B[1062]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.gm.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),178:({scopes:"d.ve.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1063],[],[],N,"d.ve.bp",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),9:({scopes:"d.ka.ey",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1064],["h.bk.ka.ey"],[0,0],N,"d.ka.ey",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[11].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,((!G(Q,A[821],(P-1)))?B[1065]:null),[],[],N,"d.jh.ey",L))){M.push(6);
+O.push(" d.jh.ey");break ifs;}if((J=E(Q,P,B[1066],["h.bc.gc.ey"],[0,0],N,"d.kw.ey",L))){M.push(8);O.push(" d.kw.ey");
+break ifs;}}return J;}}),283:({scopes:"k.bm.ca.cb.bp.cd bh.bp.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1067],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.bp.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),296:({scopes:"k.bm.ca.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1068],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}}return J;}}),151:({scopes:"k.bq.br.fi.fj.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[1069]:B[1070]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.fj.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),76:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1071],["h.i.k.bl.bt"],[0,0],N,"k.bq.br.bt",L))){M.push(75);O.push(" k.bq.br.bt d.ha.bq.br.bt");
+break ifs;}}return J;}}),454:({scopes:"d.fn.iw.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1072],[],[],N,"d.fn.iw.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[457].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),23:({scopes:"bh.bt.bj.r.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1073],["h.bk.bj.j.bt","bh.bt"],[0,1,1,0],N,"bh.bt.bj.r.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[47].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),233:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1074],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[234].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),285:({scopes:"k.bm.ca.cb.cm.cd bh.cm.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1075],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.cm.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),477:({scopes:"a.cz.hv.ev.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1076],[],[],N,"a.cz.hv.ev.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[1077],[],[],N,"",L))){M.push(476);
+O.push("");break ifs;}}return J;}}),530:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1078],["w.f.km.iz.g","h.bc.gc.g"],[0,0,1,1],N,"d.iy.iz.g",L))){M.push(529);
+O.push(" d.iy.iz.g");break ifs;}}return J;}}),337:({scopes:"d.s.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1079],[],[],N,"d.s.ch",(function(){(L&&L());M.pop();O.pop();})))){}if((J=E(Q,P,B[1080],[],[],N,"h.bc.ek.ch",L))){break ifs;
+}}return J;}}),221:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1081],["h.bc.dw.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[1082],[],[],N,"dw.f.r.bp",L))){break ifs;}if((J=E(Q,P,B[1083],[],[],N,"h.bc.dw.bp",L))){break ifs;
+}}return J;}}),273:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1084],[],[],N,"d.bo.hc.cd",L))){M.push(272);O.push(" d.bo.hc.cd");break ifs;
+}}return J;}}),287:({scopes:"k.bm.ca.cb.cr.cd bh.cr.bj.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1085],["h.i.k.cd","ce.cf.cg.cd"],[0,1,1,0],N,"k.bm.ca.cb.cr.cd",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),331:({scopes:"k.bq.bx.ch",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1086],["h.i.k.j.ch"],[0,0],N,"k.bq.bx.ch",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[369].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),342:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[363].go(Q,P,K,M,O,L))){break ifs;}if((J=H[355].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[367].go(Q,P,K,M,O,L))){break ifs;}if((J=H[368].go(Q,P,K,M,O,L))){break ifs;}if((J=H[339].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[1087],["h.if.dp.cu.ig.ch","dp.cu.vf.ch"],[0,0,1,1],N,"",L))){break ifs;}if((J=E(Q,P,(((G(Q,A[812],(P-3))||G(Q,A[813],(P-4)))||G(Q,A[496],(P-6)))?((!G(Q,A[814],(P-1)))?B[1088]:B[1089]):((!G(Q,A[814],(P-1)))?B[1090]:B[1091])),["h.if.eq.ig.ch","dp.cu.er.ch","h.i.ef.ch"],[0,0,1,1,2,2],N,"d.eq.ch",L))){break ifs;
+}if((J=E(Q,P,((!((G(Q,A[812],(P-3))||G(Q,A[813],(P-4)))||G(Q,A[496],(P-6))))?(G(Q,A[814],(P-1))?B[1092]:null):null),["dw.f.ch","h.i.ef.ch"],[0,0,1,1],N,"d.vg.ch",L))){break ifs;
+}if((J=H[341].go(Q,P,K,M,O,L))){break ifs;}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),506:({scopes:"d.e.fa.gv.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1093],["h.i.e.g"],[0,0],N,"d.e.fa.gv.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[531].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),460:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1094],["h.i.q.c"],[0,0],N,"q.r.ih.c",L))){break ifs;}if(false){break ifs;
+}if((J=H[462].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),19:({scopes:"q.r.gk.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1095],["h.i.q.m"],[0,0],N,"q.r.gk.m",(function(){(L&&L());M.pop();O.pop();
+})))){}}return J;}}),29:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1096],["h.i.dw.bt"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[27].go(Q,P,K,M,O,L))){break ifs;}if((J=H[82].go(Q,P,K,M,O,L))){break ifs;}if((J=H[49].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[48].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1097],[],[],N,"ce.dk.hk.bt",L))){break ifs;}if((J=E(Q,P,B[1098],[],[],N,"ce.dk.hn.bt",L))){break ifs;
+}}return J;}}),46:({scopes:"k.bm.ca.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1099],["ce.dk.ca.bt","h.i.k.bt"],[0,0,1,1],N,"k.bm.ca.bt",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),367:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1100],["d.s.ch","ce.cf.ci.ch"],[0,1,1,0],N,"",L))){M.push(366);O.push("");
+break ifs;}}return J;}}),481:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1101],[],[],N,"w.f.fh.c",L))){M.push(480);O.push(" w.f.fh.c");break ifs;
+}if((J=E(Q,P,B[1102],["ce.dk.hw.c"],[0,0],N,"w.f.fh.c",L))){break ifs;}}return J;}}),458:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1103],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),172:({scopes:"k.bq.bx.r.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[1104]:B[1105]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),99:({scopes:"d.cu.fy.ef.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1106],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[139].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[1107],["dw.gg.cu.cm","h.bc.ef.cm"],[0,0,1,1],N,"",L))){break ifs;}}return J;}}),158:({scopes:"k.bq.br.fi.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[148],(P-1))?B[1108]:B[1109]),["h.i.k.j.cm","d.ep.br.cm","be.bf.fk.cm"],[0,1,1,0,2,2],N,"k.bq.br.fi.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),86:({scopes:"bh.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1110],["h.i.q.cm"],[0,0],N,"q.bu.bv.cm",L))){break ifs;}if((J=E(Q,P,B[1111],[],[],N,"n.da.md.vh.vi.cm",L))){break ifs;
+}if((J=E(Q,P,B[1112],[],[],N,"n.da.md.vi.cm",L))){break ifs;}if((J=E(Q,P,B[1113],[],[],N,"n.da.md.vh.hh.cm",L))){break ifs;
+}if((J=E(Q,P,B[1114],[],[],N,"n.da.md.hh.cm",L))){break ifs;}if((J=E(Q,P,(G(Q,A[850],(P-1))?B[1115]:B[1116]),[],[],N,"n.da.vj.cm",L))){break ifs;
+}if((J=E(Q,P,B[1117],[],[],N,"n.da.vk.cm",L))){break ifs;}if((J=E(Q,P,(G(Q,A[854],(P-1))?B[1118]:null),[],[],N,"n.da.vk.cm",L))){break ifs;
+}if((J=E(Q,P,B[1119],[],[],N,"n.da.vk.cm",L))){break ifs;}if((J=E(Q,P,B[1120],[],[],N,"n.da.md.vh.vl.cm",L))){break ifs;
+}if((J=E(Q,P,B[1121],[],[],N,"n.da.md.vl.cm",L))){break ifs;}if((J=E(Q,P,B[1122],["a.b.hq.cm"],[0,0],N,"",L))){break ifs;
+}if((J=E(Q,P,B[1123],["ce.cf.ci.cm","ce.cf.ci.vm.cm"],[0,0,1,1],N,"",L))){break ifs;}if((J=E(Q,P,B[1124],[],[],N,"ce.cf.vn.cm",L))){break ifs;
+}if((J=E(Q,P,B[1125],[],[],N,"ce.cf.vn.cm",L))){break ifs;}if((J=E(Q,P,B[1126],[],[],N,"ce.dk.fe.cm",L))){break ifs;
+}if((J=E(Q,P,B[1127],["ce.f.cm"],[0,0],N,"",L))){break ifs;}if((J=E(Q,P,B[1128],[],[],N,"ce.dk.dm.cm",L))){break ifs;
+}if((J=E(Q,P,B[1129],[],[],N,"ce.dk.gh.vo.cm",L))){break ifs;}if((J=E(Q,P,B[1130],[],[],N,"ce.dk.jr.cm",L))){break ifs;
+}if((J=E(Q,P,B[1131],[],[],N,"ce.dk.gh.cm",L))){break ifs;}if((J=E(Q,P,B[1132],["a.cz.fn.cm"],[0,0],N,"d.fn.nf.cm",L))){M.push(87);
+O.push(" d.fn.nf.cm w.x.cz.fn.cm");break ifs;}if((J=E(Q,P,B[1133],["a.cz.fn.cm"],[0,0],N,"d.fn.cm",L))){M.push(91);
+O.push(" d.fn.cm");break ifs;}if((J=E(Q,P,B[1134],["a.cz.fn.cm"],[0,0],N,"d.fn.cm",L))){M.push(93);O.push(" d.fn.cm");
+break ifs;}if((J=E(Q,P,B[1135],["a.cz.cu.cm"],[0,0],N,"d.cu.cm",L))){M.push(96);O.push(" d.cu.cm");break ifs;
+}if((J=E(Q,P,B[1136],["a.cz.cu.cm"],[0,0],N,"d.cu.cm",L))){M.push(98);O.push(" d.cu.cm");break ifs;}if((J=E(Q,P,B[1137],["a.cz.cu.fy.cm"],[0,0],N,"d.cu.fy.cm",L))){M.push(100);
+O.push(" d.cu.fy.cm");break ifs;}if((J=E(Q,P,B[1138],[],[],N,"d.cu.fm.cm",L))){M.push(103);O.push(" d.cu.fm.cm");
+break ifs;}if((J=E(Q,P,B[1139],[],[],N,"d.cu.fm.cm",L))){M.push(105);O.push(" d.cu.fm.cm w.x.cu.fm.cm");
+break ifs;}if((J=E(Q,P,(G(Q,A[419],(P-1))?B[1140]:null),["h.i.hu.bl.cm"],[0,0],N,"d.eq.cm",L))){M.push(106);
+O.push(" d.eq.cm d.eq.hu.cm");break ifs;}if((J=E(Q,P,B[1141],[],[],N,"d.eq.cm",L))){M.push(109);O.push(" d.eq.cm");
+break ifs;}if((J=E(Q,P,B[1142],[],[],N,"d.lm.cm",L))){M.push(112);O.push(" d.lm.cm");break ifs;}if((J=E(Q,P,(G(Q,A[419],(P-1))?B[1143]:null),["h.i.hu.bl.cm"],[0,0],N,"d.lm.cm",L))){M.push(113);
+O.push(" d.lm.cm d.lm.hu.cm");break ifs;}if((J=E(Q,P,B[1144],["a.cz.cu.cm"],[0,0],N,"",L))){break ifs;
+}if((J=E(Q,P,B[1145],["a.cz.fn.cm"],[0,0],N,"",L))){break ifs;}if((J=H[141].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[140].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1146],[],[],N,"n.im.cm",L))){break ifs;}if((J=H[174].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[159].go(Q,P,K,M,O,L))){break ifs;}if((J=H[130].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1147],[],[],N,"",L))){M.push(114);
+O.push("");break ifs;}if((J=E(Q,P,B[1148],["h.i.lh.bl.cm","d.vp.cm","h.i.lh.j.cm"],[0,0,1,2,2,1],N,"",L))){break ifs;
+}if((J=E(Q,P,B[1149],["h.i.lh.bl.cm"],[0,0],N,"d.fa.lh.cm",L))){M.push(116);O.push(" d.fa.lh.cm");break ifs;
+}if((J=E(Q,P,B[1150],["h.i.vq.bl.cm","d.vr.cm","h.i.vq.j.cm"],[0,0,1,2,2,1],N,"d.fa.vq.cm",L))){break ifs;
+}if((J=E(Q,P,B[1151],["h.i.fb.bl.cm","d.vs.cm","h.i.fb.j.cm"],[0,0,1,2,2,1],N,"d.fa.fb.cm",L))){break ifs;
+}if((J=E(Q,P,B[1152],["h.i.fb.bl.cm"],[0,0],N,"d.fa.fb.cm",L))){M.push(119);O.push(" d.fa.fb.cm");break ifs;
+}}return J;}}),430:({scopes:"bh.bi.bj.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1153],["h.bk.bj.j.v"],[0,0],N,"bh.bi.bj.v",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1154],[],[],N,"ce.f.vt.v",L))){break ifs;}}return J;}}),281:({scopes:"d.cu.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1155],["h.i.cu.cd"],[0,0],N,"d.cu.cd",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),373:({scopes:"d.cu.kt.mg.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1156],["h.i.ef.ch"],[0,0],N,"d.cu.kt.mg.ee",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),80:({scopes:"d.ev.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1157],["h.i.ev.j.bt"],[0,0],N,"d.ev.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[47].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),225:({scopes:"bh.bp.bj.bh",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1158],["h.bk.bj.bp"],[0,0],N,"bh.bp.bj.bh",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[236].go(Q,P,K,M,O,L))){break ifs;}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),409:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1159],[],[],N,"dp.fn.hx.cr",L))){break ifs;}if((J=E(Q,P,B[1160],[],[],N,"dp.cu.hx.cr",L))){break ifs;
+}if((J=E(Q,P,B[1161],[],[],N,"dp.n.hx.cr",L))){break ifs;}if((J=E(Q,P,B[1162],[],[],N,"dp.dw.hx.cr",L))){break ifs;
+}}return J;}}),117:({scopes:"d.fa.fb.ga.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1163],["h.bc.vu.fb.cm"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),277:({scopes:"d.bo.vv.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1164],["h.i.vv.cd"],[0,0],N,"d.bo.vv.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),74:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1165],["h.i.k.bl.bt"],[0,0],N,"k.cn.bt",L))){M.push(73);O.push(" k.cn.bt");
+break ifs;}}return J;}}),432:({scopes:"k.bm.bn.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1166],["h.i.k.j.v"],[0,0],N,"k.bm.bn.v",(function(){(L&&L());M.pop();
+O.pop();})))){}}return J;}}),170:({scopes:"k.bq.bx.r.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[1167]:B[1168]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),160:({scopes:"k.bq.bx.r.hb.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[1169]:B[1170]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.hb.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),319:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1171],["h.i.k.bl.cd"],[0,0],N,"k.cn.hz.cd",L))){M.push(318);O.push(" k.cn.hz.cd");
+break ifs;}if((J=E(Q,P,B[1172],[],[],N,"ce.dk.vw.cd",L))){break ifs;}}return J;}}),456:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1173],[],[],N,"d.fn.c",L))){M.push(455);O.push(" d.fn.c");break ifs;
+}}return J;}}),97:({scopes:"w.x.cu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1174],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[132].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),88:({scopes:"w.x.cz.fn.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1175],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[131].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),33:({scopes:"d.bj.bs bh.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1176],["h.bk.bj.j.bt","ce.dk.ca.bt","h.i.k.bt"],[0,1,1,2,2,0],N,"d.bj.bs",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[256].go(Q,P,K,M,O,L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),258:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1177],["h.i.q.bs"],[0,0],N,"q.bu.bw.bs",L))){break ifs;}if((J=E(Q,P,B[1178],["h.i.q.bs"],[0,0],N,"q.bu.bv.bs",L))){break ifs;
+}if((J=E(Q,P,B[1179],["h.i.q.bs"],[0,0],N,"q.r.ch",L))){M.push(257);O.push(" q.r.ch");break ifs;}}return J;
+}}),344:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1180],[],[],N,"",L))){M.push(343);O.push("");break ifs;}}return J;}}),386:({scopes:"d.ic.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[125],(P-1))?B[1181]:B[1182]),[],[],N,"d.ic.ee",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[1183],[],[],N,"",L))){M.push(385);O.push("");break ifs;}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),462:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1184],["h.i.q.c"],[0,0],N,"q.r.c",L))){M.push(461);O.push(" q.r.c");
+break ifs;}if((J=E(Q,P,B[1185],["q.bu.ez.c","h.i.q.c"],[0,1,1,0],N,"",L))){break ifs;}}return J;}}),317:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1186],[],[],N,"ce.f.cd",L))){break ifs;}if((J=E(Q,P,B[1187],[],[],N,"ce.dk.vx.cd",L))){break ifs;
+}}return J;}}),48:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1188],[],[],N,"n.da.bt",L))){break ifs;}}return J;}}),54:({scopes:"k.l.ke.bt",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1189],["h.i.k.j.bt"],[0,0],N,"k.l.ke.bt",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1190],[],[],N,"n.o.p.ls.bt",L))){break ifs;}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[1191],["h.i.lr.bt","h.i.lr.bt"],[0,0,1,1],N,"k.l.lr.bt",L))){break ifs;}if((J=E(Q,P,B[1192],["h.i.lt.bt"],[0,0],N,"k.l.lt.bt",L))){M.push(53);
+O.push(" k.l.lt.bt");break ifs;}if((J=E(Q,P,B[1193],[],[],N,"ce.dk.l.bt",L))){break ifs;}}return J;}}),206:({scopes:"k.bq.f.ei.em.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1194],["h.i.k.j.bp"],[0,0],N,"k.bq.f.ei.em.bp",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[1195],[],[],N,"n.o.p.bp",L))){break ifs;}if((J=H[234].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),486:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1196],[],[],N,"a.cz.ji.c",L))){break ifs;}}return J;}}),164:({scopes:"k.bq.bx.r.ff.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[1197]:B[1198]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.ff.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[134].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),471:({scopes:"d.ki.iw.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1199],[],[],N,"d.ki.iw.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),451:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1200],["ce.cf.ly.c"],[0,0],N,"d.gd.jf.c",L))){M.push(450);O.push(" d.gd.jf.c");
+break ifs;}}return J;}}),374:({scopes:"d.ne.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1201],[],[],N,"d.ne.ee",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[375].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),215:({scopes:"k.bm.ca.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1202],["h.i.k.j.bp"],[0,0],N,"k.bm.ca.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),515:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1203],[],[],N,"bh.cm.bj.g",L))){M.push(514);O.push(" bh.cm.bj.g");break ifs;
+}}return J;}}),60:({scopes:"k.bq.f.bz.by.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1204],[],[],N,"k.bq.f.bz.by.bs",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[1205],[],[],N,"n.o.p.bt",L))){break ifs;}}return J;}}),279:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1206],["h.i.ie.cd"],[0,0],N,"d.bo.ie.cd",L))){M.push(275);O.push(" d.bo.ie.cd");
+break ifs;}if((J=E(Q,P,B[1207],["h.i.k.bl.cd"],[0,0],N,"k.f.dn.cd",L))){M.push(276);O.push(" k.f.dn.cd");
+break ifs;}if((J=E(Q,P,B[1208],["h.i.vv.cd"],[0,0],N,"d.bo.vv.cd",L))){M.push(277);O.push(" d.bo.vv.cd");
+break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[1209]:null),["h.i.en.cd"],[0,0],N,"d.bo.en.cd",L))){M.push(278);
+O.push(" d.bo.en.cd");break ifs;}}return J;}}),436:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1210],["h.i.k.bl.v"],[0,0],N,"k.bq.bx.v",L))){M.push(435);O.push(" k.bq.bx.v");
+break ifs;}}return J;}}),217:({scopes:"k.bm.bj.vy.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1211],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.vy.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[371].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),27:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1212],[],[],N,"d.eq.bt",L))){break ifs;}}return J;}}),473:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1213],[],[],N,"d.ki.c",L))){M.push(472);O.push(" d.ki.c");break ifs;
+}}return J;}}),405:({scopes:"k.bq.br.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1214],["h.i.k.cr"],[0,0],N,"k.bq.br.cr",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1215],[],[],N,"n.o.p.cr",L))){break ifs;}}return J;}}),58:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1216],["h.i.k.bl.bt"],[0,0],N,"k.l.kk.bt",L))){M.push(57);O.push(" k.l.kk.bt");
+break ifs;}}return J;}}),397:({scopes:"d.cu.gp.cr",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1217],["ce.cf.gq.cr","w.x.cu.gr.cr"],[0,0,1,1],N,"d.cu.gp.cr",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[395].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),237:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1218],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[238].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),365:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1219],["d.s.ch","ce.cf.ci.ch"],[0,1,1,0],N,"",L))){M.push(364);O.push("");
+break ifs;}}return J;}}),526:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1220],[],[],N,"w.f.km.g",L))){break ifs;}}return J;}}),25:({scopes:"bh.bt.bj.bu.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1221],["h.bk.bj.j.bt","bh.bt"],[0,1,1,0],N,"bh.bt.bj.bu.g",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[47].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),235:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1222],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[236].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),325:({scopes:"dw.f.je.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1223],["h.i.dw.cd"],[0,0],N,"dw.f.je.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1224],[],[],N,"ce.dk.vz.cd",L))){break ifs;}if((J=E(Q,P,B[1225],["h.bk.ev.cd","h.bk.ev.cd"],[0,0,1,1],N,"",L))){break ifs;
+}}return J;}}),109:({scopes:"d.eq.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1226],["h.i.hu.j.cm"],[0,0],N,"d.eq.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1227],[],[],N,"",L))){M.push(107);O.push("");break ifs;}if((J=E(Q,P,B[1228],["h.i.hu.bl.cm"],[0,0],N,"",L))){M.push(108);
+O.push(" d.eq.hu.cm");break ifs;}}return J;}}),491:({scopes:"d.mx.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1229],[],[],N,"d.mx.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),411:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1230],[],[],N,"dp.fn.wa.wb.cr",L))){break ifs;}if((J=E(Q,P,B[1231],[],[],N,"dp.fn.wa.pa.cr",L))){break ifs;
+}if((J=E(Q,P,B[1232],[],[],N,"dp.fn.wa.nc.cr",L))){break ifs;}if((J=E(Q,P,B[1233],[],[],N,"dp.fn.wa.wc.cr",L))){break ifs;
+}if((J=E(Q,P,B[1234],[],[],N,"dp.cu.wa.pa.cr",L))){break ifs;}if((J=E(Q,P,B[1235],[],[],N,"dp.cu.wa.wb.cr",L))){break ifs;
+}if((J=E(Q,P,B[1236],[],[],N,"dp.cu.wa.k.cr",L))){break ifs;}if((J=E(Q,P,B[1237],[],[],N,"dp.cu.wa.wd.cr",L))){break ifs;
+}if((J=E(Q,P,B[1238],[],[],N,"dp.cu.wa.we.cr",L))){break ifs;}if((J=E(Q,P,B[1239],[],[],N,"dp.cu.wa.wf.cr",L))){break ifs;
+}if((J=E(Q,P,B[1240],[],[],N,"dp.cu.wa.nc.cr",L))){break ifs;}if((J=E(Q,P,B[1241],[],[],N,"dp.cu.wa.jw.cr",L))){break ifs;
+}if((J=E(Q,P,B[1242],[],[],N,"dp.cu.wa.wc.cr",L))){break ifs;}}return J;}}),464:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1243],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[457].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),115:({scopes:"d.fa.lh.li.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1244],["h.bc.lh.cm"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),137:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1245],[],[],N,"be.bf.x.cm",L))){break ifs;}}return J;}}),227:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1246],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[228].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),361:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1247],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[342].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),62:({scopes:"k.bq.br.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1248],["n.o.p.bt"],[0,0],N,"k.bq.br.bs",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),111:({scopes:"d.lm.hu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1249],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),135:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[142].go(Q,P,K,M,O,L))){break ifs;}if((J=H[143].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[120].go(Q,P,K,M,O,L))){break ifs;}if((J=H[121].go(Q,P,K,M,O,L))){break ifs;}if((J=H[122].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[136].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),7:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1250],["h.bk.cu.ey"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[15].go(Q,P,K,M,O,L))){break ifs;}if((J=H[13].go(Q,P,K,M,O,L))){break ifs;}if((J=E(Q,P,B[1251],[],[],N,"n.f.kz.le.ey",L))){break ifs;
+}if((J=E(Q,P,B[1252],[],[],N,"n.f.kz.wg.ey",L))){break ifs;}if((J=E(Q,P,B[1253],[],[],N,"dw.gg.lf.ey",L))){break ifs;
+}}return J;}}),434:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1254],["h.i.k.bl.v"],[0,0],N,"k.bq.br.v",L))){M.push(433);O.push(" k.bq.br.v");
+break ifs;}}return J;}}),113:({scopes:"d.lm.cm d.lm.hu.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1255],["h.i.hu.j.cm"],[0,0],N,"d.lm.cm",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[86].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),245:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1256],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[246].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),13:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1257],["h.i.k.bl.ey"],[0,0],N,"k.bq.br.ey",L))){M.push(12);O.push(" k.bq.br.ey");
+break ifs;}}return J;}}),300:({scopes:"k.cn.bz.cd",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1258],["h.i.k.j.cd"],[0,0],N,"k.cn.bz.cd",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1259],[],[],N,"n.o.p.cd",L))){break ifs;}if((J=H[269].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),223:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1260],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[176].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),239:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1261],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[255].go(Q,P,K,M,O,L))){break ifs;}if((J=H[240].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),428:({scopes:"d.e.ba.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1262],["h.i.e.v","d.bo.gw.v","w.x.e.bb.v","w.x.e.v","h.bc.bb.v","w.x.e.bd.v","h.i.e.v"],[0,1,1,0,2,2,3,4,4,3,5,5,6,6],N,"d.e.ba.v",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[437].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),528:({scopes:"k.bq.bx.g d.ja.iz.g",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1263],["h.i.k.j.g"],[0,0],N,"k.bq.bx.g",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;}if((J=H[511].go(Q,P,K,M,O,L))){break ifs;}}return J;
+}}),501:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1264],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[510].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[1].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),174:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,((!G(Q,A[943],(P-1)))?B[1265]:null),["h.i.k.bl.cm","h.i.k.j.cm","d.ep.bx.cm"],[0,0,1,2,2,1],N,"k.bq.bx.fi.cm",L))){break ifs;
+}if((J=E(Q,P,B[1266],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.r.hb.cm",L))){M.push(160);O.push(" k.bq.bx.r.hb.cm");
+break ifs;}if((J=E(Q,P,B[1267],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.r.fj.cm",L))){M.push(161);
+O.push(" k.bq.bx.r.fj.cm");break ifs;}if((J=E(Q,P,B[1268],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.r.eo.cm",L))){M.push(162);
+O.push(" k.bq.bx.r.eo.cm");break ifs;}if((J=E(Q,P,B[1269],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.r.gm.cm",L))){M.push(163);
+O.push(" k.bq.bx.r.gm.cm");break ifs;}if((J=E(Q,P,B[1270],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.r.ff.cm",L))){M.push(164);
+O.push(" k.bq.bx.r.ff.cm");break ifs;}if((J=E(Q,P,B[1271],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.fi.hb.cm",L))){M.push(165);
+O.push(" k.bq.bx.fi.hb.cm");break ifs;}if((J=E(Q,P,B[1272],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.fi.fj.cm",L))){M.push(166);
+O.push(" k.bq.bx.fi.fj.cm");break ifs;}if((J=E(Q,P,B[1273],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.fi.eo.cm",L))){M.push(167);
+O.push(" k.bq.bx.fi.eo.cm");break ifs;}if((J=E(Q,P,B[1274],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.fi.gm.cm",L))){M.push(168);
+O.push(" k.bq.bx.fi.gm.cm");break ifs;}if((J=E(Q,P,B[1275],["a.cz.k.cm","h.i.k.bl.cm"],[0,0,1,1],N,"k.bq.bx.fi.ff.cm",L))){M.push(169);
+O.push(" k.bq.bx.fi.ff.cm");break ifs;}if((J=E(Q,P,B[1276],["h.i.k.bl.cm"],[0,0],N,"k.bq.bx.r.cm",L))){M.push(170);
+O.push(" k.bq.bx.r.cm");break ifs;}if((J=E(Q,P,B[1277],["h.i.k.bl.cm"],[0,0],N,"k.bq.bx.fi.cm",L))){M.push(171);
+O.push(" k.bq.bx.fi.cm");break ifs;}if((J=E(Q,P,B[1278],["h.i.k.bl.cm"],[0,0],N,"k.bq.bx.r.cm",L))){M.push(172);
+O.push(" k.bq.bx.r.cm");break ifs;}if((J=E(Q,P,B[1279],["h.i.k.bl.cm"],[0,0],N,"k.bq.bx.fi.cm",L))){M.push(173);
+O.push(" k.bq.bx.fi.cm");break ifs;}}return J;}}),162:({scopes:"k.bq.bx.r.eo.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[304],(P-3))?B[1280]:B[1281]),["h.i.k.j.cm","d.ep.bx.cm"],[0,1,1,0],N,"k.bq.bx.r.eo.cm",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=H[123].go(Q,P,K,M,O,L))){break ifs;}if((J=H[133].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[144].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),382:({scopes:"d.ia.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,(G(Q,A[125],(P-1))?B[1282]:B[1283]),[],[],N,"d.ia.ee",(function(){(L&&L());
+M.pop();O.pop();})))){}if((J=E(Q,P,B[1284],["h.i.bo.ee"],[0,0],N,"",L))){M.push(381);O.push("");break ifs;
+}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),3:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1285],["h.bk.cu.ey"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[1286],[],[],N,"dw.gg.ll.ey",L))){break ifs;}if((J=H[15].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[13].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),449:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1287],["ce.cf.lv.c"],[0,0],N,"",L))){M.push(448);O.push("");break ifs;
+}}return J;}}),302:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1288],["h.i.k.bl.cd"],[0,0],N,"k.f.dn.cd",L))){M.push(299);O.push(" k.f.dn.cd");
+break ifs;}if((J=E(Q,P,B[1289],["h.i.k.bl.cd"],[0,0],N,"k.cn.bz.cd",L))){M.push(300);O.push(" k.cn.bz.cd");
+break ifs;}if((J=E(Q,P,B[1290],["h.i.k.bl.cd"],[0,0],N,"k.cn.es.cd",L))){M.push(301);O.push(" k.cn.es.cd");
+break ifs;}}return J;}}),371:({scopes:"bh.ee",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=H[387].go(Q,P,K,M,O,L))){break ifs;}if((J=H[327].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[1291],[],[],N,"a.b.ee",L))){break ifs;}if((J=E(Q,P,B[1292],[],[],N,"a.b.ee",L))){break ifs;
+}if((J=E(Q,P,B[1293],[],[],N,"ce.cf.ee",L))){break ifs;}if((J=E(Q,P,B[1294],[],[],N,"ce.cf.ee",L))){break ifs;
+}if((J=E(Q,P,B[1295],[],[],N,"dw.f.ku.wh.ee",L))){break ifs;}if((J=E(Q,P,B[1296],[],[],N,"dw.im.ee",L))){break ifs;
+}if((J=E(Q,P,B[1297],[],[],N,"a.cz.wi.ee",L))){break ifs;}if((J=E(Q,P,B[1298],[],[],N,"ce.dk.wj.ee",L))){break ifs;
+}if((J=E(Q,P,B[1299],[],[],N,"ce.dk.ee",L))){break ifs;}if((J=E(Q,P,B[1300],[],[],N,"a.cz.ee",L))){break ifs;
+}if((J=E(Q,P,B[1301],[],[],N,"a.b.ee",L))){break ifs;}if((J=E(Q,P,((!((G(Q,A[973],(P-1))||G(Q,A[812],(P-3)))||G(Q,A[813],(P-4))))?B[1302]:B[1303]),["w.x.cu.ee","h.i.ef.ch"],[0,0,1,1],N,"d.cu.kt.ee",L))){M.push(372);
+O.push(" d.cu.kt.ee");break ifs;}if((J=E(Q,P,((!((G(Q,A[973],(P-1))||G(Q,A[812],(P-3)))||G(Q,A[813],(P-4))))?B[1304]:B[1305]),["w.x.cu.ee","h.i.ef.ch"],[0,0,1,1],N,"d.cu.kt.mg.ee",L))){M.push(373);
+O.push(" d.cu.kt.mg.ee");break ifs;}}return J;}}),348:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1306],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[M[0]].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),17:({scopes:"k.bq.bx.m",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1307],["h.i.k.j.m"],[0,0],N,"k.bq.bx.m",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=E(Q,P,B[1308],[],[],N,"n.o.p.m",L))){break ifs;}}return J;}}),304:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1309],[],[],N,"ce.dk.lh.cd",L))){break ifs;}}return J;}}),219:({scopes:"k.bm.bj.m.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1310],["h.i.k.j.bp"],[0,0],N,"k.bm.bj.m.bp",(function(){(L&&L());M.pop();
+O.pop();})))){}if((J=H[224].go(Q,P,K,M,O,L))){break ifs;}if((J=H[16].go(Q,P,K,M,O,L))){break ifs;}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;
+}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),346:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1311],[],[],N,"d.ik.ch",L))){M.push(345);O.push(" d.ik.ch");break ifs;
+}}return J;}}),447:({scopes:"d.mc.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1312],[],[],N,"d.mc.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[457].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),64:({scopes:"k.bq.bx.bs",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1313],[],[],N,"k.bq.bx.bs",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[30].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),475:({scopes:"a.cz.cq.c",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1314],[],[],N,"a.cz.cq.c",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[478].go(Q,P,K,M,O,L))){break ifs;
+}if((J=E(Q,P,B[1315],[],[],N,"a.cz.cq.c",L))){M.push(474);O.push(" a.cz.cq.c");break ifs;}}return J;}}),243:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1316],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[226].go(Q,P,K,M,O,L))){break ifs;}if((J=H[222].go(Q,P,K,M,O,L))){break ifs;}if((J=H[244].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),369:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1317],[],[],N,"n.o.p.ch",L))){break ifs;}if((J=E(Q,P,B[1318],[],[],N,"be.bf.wk.ch",L))){break ifs;
+}}return J;}}),445:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1319],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[459].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),101:({scopes:"w.x.cu.fm.cm",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1320],[],[],N,"",(function(){(L&&L());M.pop();O.pop();})))){}if((J=H[130].go(Q,P,K,M,O,L))){break ifs;
+}}return J;}}),426:({scopes:"d.e.y.z.v",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1321],["h.i.e.v"],[0,0],N,"d.e.y.z.v",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=E(Q,P,B[1322],["h.i.e.v","w.x.e.w.v","d.w.v"],[0,0,1,1,2,2],N,"",L))){M.push(425);O.push("");
+break ifs;}}return J;}}),298:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1323],["ce.dk.wl.cd","k.bq.bx.wl.cd","h.i.k.bl.cd","h.i.k.j.cd"],[0,0,1,2,2,3,3,1],N,"d.wl.cd",L))){break ifs;
+}if((J=E(Q,P,B[1324],["ce.dk.wl.cd","k.bq.br.wl.cd","h.i.k.bl.cd","h.i.k.j.cd"],[0,0,1,2,2,3,3,1],N,"d.wl.cd",L))){break ifs;
+}if((J=E(Q,P,B[1325],["ce.dk.wl.cd","k.bm.wl.cd"],[0,0,1,1],N,"d.wl.cd",L))){break ifs;}}return J;}}),241:({scopes:"",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1326],["h.bk.bo.bp"],[0,0],N,"",(function(){(L&&L());M.pop();O.pop();
+})))){}if((J=H[242].go(Q,P,K,M,O,L))){break ifs;}}return J;}}),176:({scopes:"bh.bp",go:function(Q,P,K,M,O,L){var N=function(R,S){K(R,(O.join("")+(S&&" "+S)).substring(1));
+};var J=false;ifs:{if((J=E(Q,P,B[1327],["ce.cf.fn.bp","w.x.cz.fn.bp","w.f.fh.bp","h.bc.ht.bp","dw.f.hv.bp","h.i.dw.bp"],[0,0,1,2,3,3,2,4,5,5,4,1],N,"d.fn.bp",L))){break ifs;
+}if((J=E(Q,P,B[1328],["ce.cf.wm.bp","w.x.cz.wm.bp","w.f.fh.wm.wn.bp","h.bc.ht.bp","w.f.fh.wm.wo.bp","h.bc.ht.bp","w.f.fh.wm.wp.bp","h.bc.ht.bp"],[0,0,1,2,3,3,2,4,5,5,4,6,7,7,6,1],N,"d.wm.bp",L))){break ifs;
+}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[1329]:null),[],[],N,"be.lb.bp",L))){break ifs;}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[1330]:null),[],[],N,"ce.cf.bp",L))){break ifs;
+}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[1331]:null),[],[],N,"ce.cf.wq.bp",L))){break ifs;}if((J=E(Q,P,(G(Q,A[989],(P-1))?B[1332]:null),[],[],N,"d.wr.bp.wq",L))){break ifs;
+}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[1333]:null),[],[],N,"ce.dk.fe.bp",L))){break ifs;}if((J=E(Q,P,((!G(Q,A[454],(P-1)))?B[1334]:B[1335]),[],[],N,"ce.cf.ws.bp",L))){break ifs;
+}if((J=E(Q,P,B[1336],[],[],N,"n.im.bp",L))){break ifs;}if((J=E(Q,P,B[1337],[],[],N,"dw.im.bp",L))){break ifs;
+}if((J=E(Q,P,B[1338],[],[],N,"ce.f.wt.bp",L))){break ifs;}if((J=E(Q,P,B[1339],["ce.f.wt.bp"],[0,0],N,"d.hy.bp",L))){M.push(177);
+O.push(" d.hy.bp");break ifs;}if((J=E(Q,P,B[1340],["h.i.dw.bp"],[0,0],N,"dw.f.ku.kv.bp",L))){break ifs;
+}if((J=E(Q,P,B[1341],["h.i.dw.bp"],[0,0],N,"dw.f.ku.fn.bp",L))){break ifs;}if((J=E(Q,P,B[1342],["h.i.dw.bp"],[0,0],N,"dw.f.ku.hq.bp",L))){break ifs;
+}if((J=E(Q,P,B[1343],["h.i.dw.bp"],[0,0],N,"dw.f.ku.hq.wu.bp",L))){break ifs;}if((J=E(Q,P,B[1344],["dw.f.n.bp"],[0,0],N,"d.ve.bp",L))){M.push(178);
+O.push(" d.ve.bp");break ifs;}if((J=E(Q,P,B[1345],[],[],N,"dp.fn.bp",L))){break ifs;}if((J=E(Q,P,B[1346],[],[],N,"dw.f.n.bp",L))){break ifs;
+}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[1347]:null),["ce.cf.wv.bp","w.x.cu.bp","h.i.ef.bp"],[0,0,1,1,2,2],N,"d.cu.ki.kj.bp",L))){M.push(179);
+O.push(" d.cu.ki.kj.bp dw.gg.cu.bp");break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[1348]:null),["ce.cf.wv.bp","w.x.cu.bp"],[0,0,1,1],N,"d.cu.ki.kj.bp",L))){M.push(180);
+O.push(" d.cu.ki.kj.bp dw.gg.cu.bp");break ifs;}if((J=E(Q,P,((G(Q,A[238],(P-0))||G(Q,A[239],(P-1)))?B[1349]:null),["ce.cf.wv.bp","w.x.cu.bp"],[0,0,1,1],N,"d.cu.ki.ww.bp",L))){break ifs;
+}if((J=E(Q,P,B[1350],[],[],N,"n.da.bp",L))){break ifs;}if((J=E(Q,P,B[1351],["h.i.n.bp"],[0,0],N,"n.f.kd.kk.bp",L))){M.push(181);
+O.push(" n.f.kd.kk.bp");break ifs;}if((J=E(Q,P,B[1352],["h.i.n.bp"],[0,0],N,"n.f.kd.ke.bp",L))){M.push(182);
+O.push(" n.f.kd.ke.bp");break ifs;}if((J=E(Q,P,B[1353],[],[],N,"ce.dk.gh.vo.bp",L))){break ifs;}if((J=E(Q,P,B[1354],["h.i.k.bl.bp"],[0,0],N,"k.bq.bx.bp",L))){M.push(183);
+O.push(" k.bq.bx.bp");break ifs;}if((J=E(Q,P,B[1355],["h.i.k.bl.bp"],[0,0],N,"k.bq.br.bp",L))){M.push(184);
+O.push(" k.bq.br.bp");break ifs;}if((J=E(Q,P,B[1356],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(185);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,B[1357],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(186);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,B[1358],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(187);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,B[1359],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(188);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,B[1360],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(189);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,B[1361],["h.i.k.bl.bp"],[0,0],N,"k.cn.bp",L))){M.push(190);
+O.push(" k.cn.bp");break ifs;}if((J=E(Q,P,(((((((G(Q,A[1017],(P-1))||G(Q,A[1018],(P-4)))||G(Q,A[1019],(P-5)))||G(Q,A[1020],(P-6)))||G(Q,A[1021],(P-7)))||G(Q,A[1022],(P-8)))||G(Q,A[1023],(P-14)))?((((G(Q,A[1024],(P-3))||G(Q,A[1025],(P-5)))||G(Q,A[1026],(P-6)))||G(Q,A[1027],(P-7)))?B[1362]:B[1363]):((((G(Q,A[1024],(P-3))||G(Q,A[1025],(P-5)))||G(Q,A[1026],(P-6)))||G(Q,A[1027],(P-7)))?B[1364]:B[1365])),["k.l.tm.bp","h.i.k.bp"],[0,1,1,0],N,"",L))){M.push(191);
+O.push(" k.l.tm.bp");break ifs;}if((J=E(Q,P,B[1366],["h.i.k.bl.bp"],[0,0],N,"k.l.fl.bp",L))){M.push(192);
+O.push(" k.l.fl.bp");break ifs;}if((J=E(Q,P,B[1367],["h.i.k.bl.bp"],[0,0],N,"k.l.fl.bp",L))){M.push(193);
+O.push(" k.l.fl.bp");break ifs;}if((J=E(Q,P,B[1368],["h.i.k.bl.bp"],[0,0],N,"k.l.fl.bp",L))){M.push(194);
+O.push(" k.l.fl.bp");break ifs;}if((J=E(Q,P,B[1369],["h.i.k.bl.bp"],[0,0],N,"k.l.fl.bp",L))){M.push(195);
+O.push(" k.l.fl.bp");break ifs;}if((J=E(Q,P,B[1370],["h.i.k.bl.bp"],[0,0],N,"k.l.fl.bp",L))){M.push(196);
+O.push(" k.l.fl.bp");break ifs;}if((J=E(Q,P,B[1371],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.ej.bp",L))){M.push(197);
+O.push(" k.bq.f.ei.ej.bp");break ifs;}if((J=E(Q,P,B[1372],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.ej.bp",L))){M.push(198);
+O.push(" k.bq.f.ei.ej.bp");break ifs;}if((J=E(Q,P,B[1373],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.ej.bp",L))){M.push(199);
+O.push(" k.bq.f.ei.ej.bp");break ifs;}if((J=E(Q,P,B[1374],["h.i.k.bl.bp"],[0,0],N,"k.bq.br.bp.et",L))){M.push(200);
+O.push(" k.bq.br.bp.et");break ifs;}if((J=E(Q,P,B[1375],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.ej.bp",L))){M.push(201);
+O.push(" k.bq.f.ei.ej.bp");break ifs;}if((J=E(Q,P,B[1376],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.f.bp",L))){M.push(202);
+O.push(" k.bq.f.ei.f.bp");break ifs;}if((J=E(Q,P,B[1377],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.em.bp",L))){M.push(203);
+O.push(" k.bq.f.ei.em.bp");break ifs;}if((J=E(Q,P,B[1378],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.em.bp",L))){M.push(204);
+O.push(" k.bq.f.ei.em.bp");break ifs;}if((J=E(Q,P,B[1379],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.em.bp",L))){M.push(205);
+O.push(" k.bq.f.ei.em.bp");break ifs;}if((J=E(Q,P,B[1380],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.em.bp",L))){M.push(206);
+O.push(" k.bq.f.ei.em.bp");break ifs;}if((J=E(Q,P,B[1381],["h.i.k.bl.bp"],[0,0],N,"k.bq.f.ei.em.bp",L))){M.push(207);
+O.push(" k.bq.f.ei.em.bp");break ifs;}if((J=E(Q,P,((!G(Q,A[444],(P-1)))?B[1382]:null),["h.i.n.bp"],[0,0],N,"n.f.kd.bp",L))){break ifs;
+}if((J=E(Q,P,B[1383],["h.i.n.bp"],[0,0],N,"n.f.kd.bp.wx",L))){break ifs;}if((J=E(Q,P,B[1384],["h.i.q.bp"],[0,0],N,"q.r.gk.bp",L))){M.push(208);
+O.push(" q.r.gk.bp");break ifs;}if((J=E(Q,P,B[1385],["h.i.q.bp"],[0,0],N,"q.bu.bv.bp",L))){break ifs;
+}if((J=E(Q,P,((!G(Q,A[814],(P-1)))?B[1386]:null),[],[],N,"n.da.bp",L))){break ifs;}if((J=E(Q,P,B[1387],["k.bm.uw.bp"],[0,0],N,"",L))){M.push(210);
+O.push(" u.uv");break ifs;}if((J=E(Q,P,B[1388],["h.i.k.bl.bp"],[0,0],N,"k.bm.ca.bp",L))){M.push(211);
+O.push(" k.bm.ca.bp");break ifs;}if((J=E(Q,P,B[1389],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.g.bp",L))){M.push(212);
+O.push(" k.bm.bj.g.bp u.g.bj.bp");break ifs;}if((J=E(Q,P,B[1390],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.bs.bp",L))){M.push(213);
+O.push(" k.bm.bj.bs.bp u.bs.bj.bp");break ifs;}if((J=E(Q,P,B[1391],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.bp.bp",L))){M.push(214);
+O.push(" k.bm.bj.bp.bp");break ifs;}if((J=E(Q,P,B[1392],["h.i.k.bl.bp"],[0,0],N,"k.bm.ca.bp",L))){M.push(215);
+O.push(" k.bm.ca.bp");break ifs;}if((J=E(Q,P,B[1393],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.ch.bp",L))){M.push(216);
+O.push(" k.bm.bj.ch.bp");break ifs;}if((J=E(Q,P,B[1394],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.vy.bp",L))){M.push(217);
+O.push(" k.bm.bj.vy.bp");break ifs;}if((J=E(Q,P,B[1395],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.ey.bp",L))){M.push(218);
+O.push(" k.bm.bj.ey.bp");break ifs;}if((J=E(Q,P,B[1396],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.m.bp",L))){M.push(219);
+O.push(" k.bm.bj.m.bp");break ifs;}if((J=E(Q,P,B[1397],["h.i.k.bl.bp"],[0,0],N,"k.bm.bj.cd.bp",L))){M.push(220);
+O.push(" k.bm.bj.cd.bp");break ifs;}if((J=E(Q,P,(((G(Q,A[989],(P-1))||G(Q,A[1062],(P-2)))||G(Q,A[1063],(P-3)))?B[1398]:null),["h.bc.dw.bp"],[0,0],N,"",L))){M.push(221);
+O.push("");break ifs;}if((J=E(Q,P,B[1399],[],[],N,"h.bc.gc",L))){break ifs;}if((J=E(Q,P,B[1400],[],[],N,"ce.dk.gh.vo.bp",L))){break ifs;
+}if((J=E(Q,P,(G(Q,A[1065],(P-1))?B[1401]:B[1402]),[],[],N,"ce.dk.dm.bp",L))){break ifs;}if((J=E(Q,P,(G(Q,A[1065],(P-1))?B[1403]:B[1404]),[],[],N,"ce.dk.fe.bp",L))){break ifs;
+}if((J=E(Q,P,B[1405],[],[],N,"ce.dk.jr.bp",L))){break ifs;}if((J=E(Q,P,B[1406],[],[],N,"ce.dk.gh.bp",L))){break ifs;
+}if((J=E(Q,P,B[1407],[],[],N,"ce.dk.f.bp",L))){break ifs;}if((J=E(Q,P,B[1408],[],[],N,"h.bc.f.bp",L))){break ifs;
+}if((J=E(Q,P,B[1409],[],[],N,"h.bc.mp.bp",L))){break ifs;}if((J=E(Q,P,B[1410],[],[],N,"h.bc.hv.bp",L))){break ifs;
+}if((J=E(Q,P,B[1411],[],[],N,"h.bc.ki.bp",L))){break ifs;}if((J=E(Q,P,B[1412],[],[],N,"h.bk.bo.bp",L))){break ifs;
+}if((J=E(Q,P,B[1413],[],[],N,"h.bk.ev.bp",L))){break ifs;}if((J=E(Q,P,B[1414],[],[],N,"h.bk.cu.bp",L))){break ifs;
+}}return J;}})};var I=function(U,K,O){var M=K.split("/");var L=[];for(var P=0;P<M.length;P++){var Q=H[M[P]].scopes;
+L.push(Q&&" "+Q);}var S=0;var R=U.length;var T=0;var J=function(){if(S>T){O(U.substring(T,S),L.join("").substring(1));
+T=S;}};while(S<R){var N=H[M[M.length-1]].go(U,S,O,M,L,J);if(N){S+=N[0];T+=N[0];}else{S++;}}J();return M.join("/");
+};var D=(function(J){return(((/(?:^| )q(?=\.| |$)|(?:^| )wy\.wz\.xa\.bs(?=\.| |$)/.test(J)&&" t1")||"")+((/(?:^| )wz\.xa\.bs(?=\.| |$)/.test(J)&&" t2")||"")+((/(?:^| )ce(?=\.| |$)|(?:^| )a(?=\.| |$)/.test(J)&&" t3")||"")+((/(?:^| )n\.da(?=\.| |$)/.test(J)&&" t4")||"")+((/(?:^| )n(?=\.| |$)/.test(J)&&" t5")||"")+((/(?:^| )n\.im(?=\.| |$)/.test(J)&&" t6")||"")+((/(?:^| )dw\.im(?=\.| |$)|(?:^| )dw\.f(?=\.| |$)/.test(J)&&" t7")||"")+((/(?:^| )n\.o\.p(?=\.| |$)|(?:^| )k(?=\.| |$).*?(?:^| )bh(?=\.| |$)/.test(J)&&" t8")||"")+((/(?:^| )d\.s(?=\.| |$)/.test(J)&&" t9")||"")+((/(?:^| )ce\.cf\.ci(?=\.| |$)/.test(J)&&" t10")||"")+((/(?:^| )w\.x\.cu(?=\.| |$)|(?:^| )dp\.cu\.gv(?=\.| |$)/.test(J)&&" t11")||"")+((/(?:^| )w\.x\.cz(?=\.| |$)/.test(J)&&" t12")||"")+((/(?:^| )w\.f\.is(?=\.| |$)/.test(J)&&" t13")||"")+((/(?:^| )dw\.gg(?=\.| |$)/.test(J)&&" t14")||"")+((/(?:^| )a\.cz\.ki(?=\.| |$)/.test(J)&&" t15")||"")+((/(?:^| )d\.bk(?=\.| |$).*?(?:^| )w\.x\.bk(?=\.| |$)|(?:^| )gd\.bk(?=\.| |$).*?(?:^| )w\.x\.bk(?=\.| |$)/.test(J)&&" t16")||"")+((/(?:^| )dp\.cu(?=\.| |$)/.test(J)&&" t17")||"")+((/(?:^| )dp\.fn(?=\.| |$)|(?:^| )dp\.cz(?=\.| |$)/.test(J)&&" t18")||"")+((/(?:^| )dp\.n(?=\.| |$)/.test(J)&&" t19")||"")+((/(?:^| )dp\.dw(?=\.| |$)/.test(J)&&" t20")||"")+((/(?:^| )ce\.dk\.m(?=\.| |$)/.test(J)&&" t21")||"")+((/(?:^| )be(?=\.| |$)/.test(J)&&" t22")||"")+((/(?:^| )be\.lb\.ii(?=\.| |$)/.test(J)&&" t23")||"")+((/(?:^| )u(?=\.| |$).*?(?:^| )bh(?=\.| |$)|(?:^| )k\.bm(?=\.| |$)/.test(J)&&" t24")||"")+((/(?:^| )u(?=\.| |$).*?(?:^| )bh(?=\.| |$).*?(?:^| )k\.bm(?=\.| |$)|(?:^| )u(?=\.| |$).*?(?:^| )bh(?=\.| |$).*?(?:^| )u(?=\.| |$).*?(?:^| )bh(?=\.| |$)/.test(J)&&" t25")||"")+((/(?:^| )d\.e\.s\.v(?=\.| |$)/.test(J)&&" t26")||"")+((/(?:^| )d\.e\.y\.z(?=\.| |$)|(?:^| )d\.e\.y\.z(?=\.| |$).*?(?:^| )w(?=\.| |$)|(?:^| )d\.e\.y\.z(?=\.| |$).*?(?:^| )k(?=\.| |$)|(?:^| )d\.e\.s\.v(?=\.| |$)|(?:^| )d\.e\.s\.v(?=\.| |$).*?(?:^| )w(?=\.| |$)|(?:^| )d\.e\.s\.v(?=\.| |$).*?(?:^| )k(?=\.| |$)/.test(J)&&" t27")||"")+((/(?:^| )k\.bq\.xb\.z\.xc(?=\.| |$)/.test(J)&&" t28")||"")+((/(?:^| )d\.e(?=\.| |$)|(?:^| )gd\.e(?=\.| |$)/.test(J)&&" t29")||"")+((/(?:^| )w\.x\.e(?=\.| |$)/.test(J)&&" t30")||"")+((/(?:^| )w\.f\.kr(?=\.| |$)/.test(J)&&" t31")||"")+((/(?:^| )fv\.xd(?=\.| |$)/.test(J)&&" t32")||"")+((/(?:^| )fv\.xe(?=\.| |$)/.test(J)&&" t33")||"")+((/(?:^| )fv\.lh(?=\.| |$)/.test(J)&&" t34")||"")+((/(?:^| )k(?=\.| |$)/.test(J)&&" t35")||"")).substring(1);
+});return{parseLine:I,initialState:"494",getClassesForScope:D};}());
diff --git a/infrastructure/ace/www/lang_js.js b/infrastructure/ace/www/lang_js.js
new file mode 100644
index 0000000..4bbc5b4
--- /dev/null
+++ b/infrastructure/ace/www/lang_js.js
@@ -0,0 +1,102 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+grammars = (window.grammars || {}); grammars["source.js"] = (function() {
+ var rxTest = function(str, rx, startIndex) {
+ rx.lastIndex = startIndex; var rslt = rx.exec(str); return !!(rslt && rslt[0]);
+ };
+ var tokenizeMatch = function(str, startIndex, rxResult, captureNames, captureGroups, captureLocators, captureStructure, tokenFunc, extraScopes) {
+ extraScopes = (extraScopes && " "+extraScopes);
+ // each entry of scopeState is undefined or a scope starting with a " ", so that
+ // that when the array is joined on '' it is either an empty string or series of
+ // space-separated scopes starting with an extra space
+ var scopeState = new Array(captureNames.length+1);
+ var idx = startIndex;
+ var fullLen = rxResult[0].length;
+ for(var k=0;k<captureStructure.length;k++) {
+ var c = captureStructure[k];
+ var g = captureGroups[c];
+ if (g < 0) continue;
+ var isOpen = (scopeState[c] === undefined);
+ var newIndex = startIndex + fullLen;
+ var locators = captureLocators[c];
+ for(var j=0;j<locators.length;j++) newIndex -= (rxResult[locators[j]]||'').length;
+ if (isOpen) {
+ newIndex -= (rxResult[g]||'').length;
+ }
+ if (newIndex > idx) {
+ tokenFunc(str.substring(idx, newIndex), (extraScopes+scopeState.join('')).substring(1));
+ }
+ idx = newIndex;
+ if (isOpen) {
+ scopeState[c] = " "+captureNames[c];
+ }
+ else {
+ delete scopeState[c];
+ }
+ }
+ if (idx < startIndex + fullLen) {
+ tokenFunc(str.substring(idx, startIndex+fullLen), (extraScopes+scopeState.join('')).substring(1));
+ }
+ };
+ var tryMatch = function(str, startIndex, rx, fgn, captureNames, captureGroups, captureLocators, captureStructure, tokenFunc, extraScopes, optOnBeforeTokenize) {
+ rx.lastIndex = startIndex;
+ var rxResult = rx.exec(str);
+ if (! rxResult) return false; // shouldn't happen
+ if (rxResult[fgn]) return false; // failure group
+ optOnBeforeTokenize && optOnBeforeTokenize();
+ tokenizeMatch(str, startIndex, rxResult, captureNames, captureGroups, captureLocators, captureStructure, tokenFunc, extraScopes);
+ return [rxResult[0].length];
+ };
+ var tryMatch2 = function(str, startIndex, postlob, captureNames, captureStructure, tokenFunc, extraScopes, optOnBeforeTokenize) {
+ return(postlob ? tryMatch(str,startIndex,postlob[0],postlob[1],captureNames,postlob[2],postlob[3],captureStructure,tokenFunc,extraScopes,optOnBeforeTokenize) : false);
+ }
+ var rxs = [/(?=\n)|"|([\s\S])/g,/\\(x[0-9a-fA-F]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]|37[0-7]?|[4-7][0-7]?|.)|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\s*(=)(\s*)))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*(function)?(\s*(\()((.*?)(\))))))))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.(prototype)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*))))|([\s\S])/g,/([a-zA-Z_\?\.\$][\w\?\.\$]*)(\.([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*(=)(\s*(function)(\s*(\()((.*?)(\)))))))|([\s\S])/g,/([a-zA-Z_\?\$][\w\?\$]*)(\s*(=)(\s*(function)(\s*(\()((.*?)(\))))))|([\s\S])/g,/\b(function)(\s+([a-zA-Z_\$]\w*)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/\b([a-zA-Z_\?\.\$][\w\?\.\$]*)(\s*:\s*\b(function)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/(?:((')((.*?)(')))|((")((.*?)("))))(\s*:\s*\b(function)?(\s*(\()((.*?)(\)))))|([\s\S])/g,/(new)(\s+(\w+(?:\.\w*)?))|([\s\S])/g,/\b(console)\b|([\s\S])/g,/\.(warn|info|log|error|time|timeEnd|assert)\b|([\s\S])/g,/\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?))\b|([\s\S])/g,/'|([\s\S])/g,/"|([\s\S])/g,/\/\*\*(?!\/)|([\s\S])/g,/\/\*|([\s\S])/g,/(\/\/)(.*(?=\n)\n?)|([\s\S])/g,/(<!\-\-|\-\->)|([\s\S])/g,/\b(boolean|byte|char|class|double|enum|float|function|int|interface|long|short|var|void)\b|([\s\S])/g,/\b(const|export|extends|final|implements|native|private|protected|public|static|synchronized|throws|transient|volatile)\b|([\s\S])/g,/\b(break|case|catch|continue|default|do|else|finally|for|goto|if|import|package|return|switch|throw|try|while)\b|([\s\S])/g,/\b(delete|in|instanceof|new|typeof|with)\b|([\s\S])/g,/\btrue\b|([\s\S])/g,/\bfalse\b|([\s\S])/g,/\bnull\b|([\s\S])/g,/\b(super|this)\b|([\s\S])/g,/\b(debugger)\b|([\s\S])/g,/\b(Anchor|Applet|Area|Array|Boolean|Button|Checkbox|Date|document|event|FileUpload|Form|Frame|Function|Hidden|History|Image|JavaArray|JavaClass|JavaObject|JavaPackage|java|Layer|Link|Location|Math|MimeType|Number|navigator|netscape|Object|Option|Packages|Password|Plugin|Radio|RegExp|Reset|Select|String|Style|Submit|screen|sun|Text|Textarea|window|XMLHttpRequest)\b|([\s\S])/g,/\b(s(h(ift|ow(Mod(elessDialog|alDialog)|Help))|croll(X|By(Pages|Lines)?|Y|To)?|t(op|rike)|i(n|zeToContent|debar|gnText)|ort|u(p|b(str(ing)?)?)|pli(ce|t)|e(nd|t(Re(sizable|questHeader)|M(i(nutes|lliseconds)|onth)|Seconds|Ho(tKeys|urs)|Year|Cursor|Time(out)?|Interval|ZOptions|Date|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(ome|andleEvent)|navigate|c(har(CodeAt|At)|o(s|n(cat|textual|firm)|mpile)|eil|lear(Timeout|Interval)?|a(ptureEvents|ll)|reate(StyleSheet|Popup|EventObject))|t(o(GMTString|S(tring|ource)|U(TCString|pperCase)|Lo(caleString|werCase))|est|a(n|int(Enabled)?))|i(s(NaN|Finite)|ndexOf|talics)|d(isableExternalCapture|ump|etachEvent)|u(n(shift|taint|escape|watch)|pdateCommands)|j(oin|avaEnabled)|p(o(p|w)|ush|lugins.refresh|a(ddings|rse(Int|Float)?)|r(int|ompt|eference))|e(scape|nableExternalCapture|val|lementFromPoint|x(p|ec(Script|Command)?))|valueOf|UTC|queryCommand(State|Indeterm|Enabled|Value)|f(i(nd|le(ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(nt(size|color)|rward)|loor|romCharCode)|watch|l(ink|o(ad|g)|astIndexOf)|a(sin|nchor|cos|t(tachEvent|ob|an(2)?)|pply|lert|b(s|ort))|r(ou(nd|teEvents)|e(size(By|To)|calc|turnValue|place|verse|l(oad|ease(Capture|Events)))|andom)|g(o|et(ResponseHeader|M(i(nutes|lliseconds)|onth)|Se(conds|lection)|Hours|Year|Time(zoneOffset)?|Da(y|te)|UTC(M(i(nutes|lliseconds)|onth)|Seconds|Hours|Da(y|te)|FullYear)|FullYear|A(ttention|llResponseHeaders)))|m(in|ove(B(y|elow)|To(Absolute)?|Above)|ergeAttributes|a(tch|rgins|x))|b(toa|ig|o(ld|rderWidths)|link|ack))\b(?=\()|([\s\S])/g,/\b(s(ub(stringData|mit)|plitText|e(t(NamedItem|Attribute(Node)?)|lect))|has(ChildNodes|Feature)|namedItem|c(l(ick|o(se|neNode))|reate(C(omment|DATASection|aption)|T(Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(ntityReference|lement)|Attribute))|tabIndex|i(nsert(Row|Before|Cell|Data)|tem)|open|delete(Row|C(ell|aption)|T(Head|Foot)|Data)|focus|write(ln)?|a(dd|ppend(Child|Data))|re(set|place(Child|Data)|move(NamedItem|Child|Attribute(Node)?)?)|get(NamedItem|Element(sBy(Name|TagName)|ById)|Attribute(Node)?)|blur)\b(?=\()|([\s\S])/g,/\.|/g,/(s(ystemLanguage|cr(ipts|ollbars|een(X|Y|Top|Left))|t(yle(Sheets)?|atus(Text|bar)?)|ibling(Below|Above)|ource|uffixes|e(curity(Policy)?|l(ection|f)))|h(istory|ost(name)?|as(h|Focus))|y|X(MLDocument|SLDocument)|n(ext|ame(space(s|URI)|Prop))|M(IN_VALUE|AX_VALUE)|c(haracterSet|o(n(structor|trollers)|okieEnabled|lorDepth|mp(onents|lete))|urrent|puClass|l(i(p(boardData)?|entInformation)|osed|asses)|alle(e|r)|rypto)|t(o(olbar|p)|ext(Transform|Indent|Decoration|Align)|ags)|SQRT(1_2|2)|i(n(ner(Height|Width)|put)|ds|gnoreCase)|zIndex|o(scpu|n(readystatechange|Line)|uter(Height|Width)|p(sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(i(splay|alog(Height|Top|Width|Left|Arguments)|rectories)|e(scription|fault(Status|Ch(ecked|arset)|View)))|u(ser(Profile|Language|Agent)|n(iqueID|defined)|pdateInterval)|_content|p(ixelDepth|ort|ersonalbar|kcs11|l(ugins|atform)|a(thname|dding(Right|Bottom|Top|Left)|rent(Window|Layer)?|ge(X(Offset)?|Y(Offset)?))|r(o(to(col|type)|duct(Sub)?|mpter)|e(vious|fix)))|e(n(coding|abledPlugin)|x(ternal|pando)|mbeds)|v(isibility|endor(Sub)?|Linkcolor)|URLUnencoded|P(I|OSITIVE_INFINITY)|f(ilename|o(nt(Size|Family|Weight)|rmName)|rame(s|Element)|gColor)|E|whiteSpace|l(i(stStyleType|n(eHeight|kColor))|o(ca(tion(bar)?|lName)|wsrc)|e(ngth|ft(Context)?)|a(st(M(odified|atch)|Index|Paren)|yer(s|X)|nguage))|a(pp(MinorVersion|Name|Co(deName|re)|Version)|vail(Height|Top|Width|Left)|ll|r(ity|guments)|Linkcolor|bove)|r(ight(Context)?|e(sponse(XML|Text)|adyState))|global|x|m(imeTypes|ultiline|enubar|argin(Right|Bottom|Top|Left))|L(N(10|2)|OG(10E|2E))|b(o(ttom|rder(RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(Color|Image)))\b|([\s\S])/g,/(s(hape|ystemId|c(heme|ope|rolling)|ta(ndby|rt)|ize|ummary|pecified|e(ctionRowIndex|lected(Index)?)|rc)|h(space|t(tpEquiv|mlFor)|e(ight|aders)|ref(lang)?)|n(o(Resize|tation(s|Name)|Shade|Href|de(Name|Type|Value)|Wrap)|extSibling|ame)|c(h(ildNodes|Off|ecked|arset)?|ite|o(ntent|o(kie|rds)|de(Base|Type)?|l(s|Span|or)|mpact)|ell(s|Spacing|Padding)|l(ear|assName)|aption)|t(ype|Bodies|itle|Head|ext|a(rget|gName)|Foot)|i(sMap|ndex|d|m(plementation|ages))|o(ptions|wnerDocument|bject)|d(i(sabled|r)|o(c(type|umentElement)|main)|e(clare|f(er|ault(Selected|Checked|Value)))|at(eTime|a))|useMap|p(ublicId|arentNode|r(o(file|mpt)|eviousSibling))|e(n(ctype|tities)|vent|lements)|v(space|ersion|alue(Type)?|Link|Align)|URL|f(irstChild|orm(s)?|ace|rame(Border)?)|width|l(ink(s)?|o(ngDesc|wSrc)|a(stChild|ng|bel))|a(nchors|c(ce(ssKey|pt(Charset)?)|tion)|ttributes|pplets|l(t|ign)|r(chive|eas)|xis|Link|bbr)|r(ow(s|Span|Index)|ules|e(v|ferrer|l|adOnly))|m(ultiple|e(thod|dia)|a(rgin(Height|Width)|xLength))|b(o(dy|rder)|ackground|gColor))\b|([\s\S])/g,/\b(ELEMENT_NODE|ATTRIBUTE_NODE|TEXT_NODE|CDATA_SECTION_NODE|ENTITY_REFERENCE_NODE|ENTITY_NODE|PROCESSING_INSTRUCTION_NODE|COMMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_FRAGMENT_NODE|NOTATION_NODE|INDEX_SIZE_ERR|DOMSTRING_SIZE_ERR|HIERARCHY_REQUEST_ERR|WRONG_DOCUMENT_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR|NOT_SUPPORTED_ERR|INUSE_ATTRIBUTE_ERR)\b|([\s\S])/g,/\bon(R(ow(s(inserted|delete)|e(nter|xit))|e(s(ize(start|end)?|et)|adystatechange))|Mouse(o(ut|ver)|down|up|move)|B(efore(cut|deactivate|u(nload|pdate)|p(aste|rint)|editfocus|activate)|lur)|S(croll|top|ubmit|elect(start|ionchange)?)|H(over|elp)|C(hange|ont(extmenu|rolselect)|ut|ellchange|l(ick|ose))|D(eactivate|ata(setc(hanged|omplete)|available)|r(op|ag(start|over|drop|en(ter|d)|leave)?)|blclick)|Unload|P(aste|ropertychange)|Error(update)?|Key(down|up|press)|Focus|Load|A(ctivate|fter(update|print)|bort))\b|([\s\S])/g,/\(|/g,/!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?:|\*=|\/=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|void)\b|([\s\S])/g,/!|\$|%|&|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?:|\*=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|void)\b|([\s\S])/g,/\b(Infinity|NaN|undefined)\b|([\s\S])/g,/^[\s\S]|/g,/[=\(:]|/g,/return|/g,/\s*(\/)((?![\/\*\+\{\}\?]))|([\s\S])/g,/;|([\s\S])/g,/,[ \|\t]*|([\s\S])/g,/\.|([\s\S])/g,/\{|\}|([\s\S])/g,/\(|\)|([\s\S])/g,/\[|\]|([\s\S])/g,/(?=\n)|(\/)([igm]*)|([\s\S])/g,/\\.|([\s\S])/g,/\*\/|([\s\S])/g,/(?=\n)|'|([\s\S])/g,/\\(x[0-9a-fA-F]{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)|([\s\S])/g];
+ var exs = [[rxs[0],1,[0],[[]]],[rxs[1],2,[],[]],[rxs[2],7,[1,3,5],[[2],[4],[6]]],[rxs[3],15,[1,3,5,7,9,11,13,14],[[2],[4],[6],[8],[10],[12],[14],[]]],[rxs[4],9,[1,3,5,7],[[2],[4],[6],[8]]],[rxs[5],13,[1,3,5,7,9,11,12],[[2],[4],[6],[8],[10],[12],[]]],[rxs[6],11,[1,3,5,7,9,10],[[2],[4],[6],[8],[10],[]]],[rxs[7],9,[1,3,5,7,8],[[2],[4],[6],[8],[]]],[rxs[8],9,[1,3,5,7,8],[[2],[4],[6],[8],[]]],[rxs[9],18,[1,2,4,5,6,7,9,10,12,14,16,17],[[11],[3,11],[5,11],[11],[11],[8,11],[10,11],[11],[13],[15],[17],[]]],[rxs[10],4,[1,3],[[2],[]]],[rxs[11],2,[],[]],[rxs[12],2,[],[]],[rxs[13],6,[],[]],[rxs[14],1,[0],[[]]],[rxs[15],1,[0],[[]]],[rxs[16],1,[0],[[]]],[rxs[17],1,[0],[[]]],[rxs[18],3,[1],[[2]]],[rxs[19],2,[1],[[]]],[rxs[20],2,[],[]],[rxs[21],2,[],[]],[rxs[22],2,[],[]],[rxs[23],2,[],[]],[rxs[24],1,[],[]],[rxs[25],1,[],[]],[rxs[26],1,[],[]],[rxs[27],2,[],[]],[rxs[28],2,[],[]],[rxs[29],2,[],[]],[rxs[30],90,[],[]],[rxs[31],31,[],[]],[rxs[33],101,[],[]],[rxs[34],65,[],[]],[rxs[35],2,[],[]],[rxs[36],32,[],[]],[rxs[38],2,[],[]],[rxs[39],2,[],[]],[rxs[40],2,[],[]],[rxs[44],3,[1],[[2]]],[rxs[45],1,[],[]],[rxs[46],1,[],[]],[rxs[47],1,[],[]],[rxs[48],1,[],[]],[rxs[49],1,[],[]],[rxs[50],1,[],[]],[rxs[51],3,[1],[[2]]],[rxs[52],1,[],[]],[rxs[53],1,[0],[[]]],[rxs[53],1,[0],[[]]],[rxs[54],1,[0],[[]]],[rxs[55],2,[],[]]];
+ var frames = {3: ({ scopes:"string.quoted.double.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[0],["punctuation.definition.string.end.js"],[0,0],tokenFunc,"string.quoted.double.js",(function() {(optOnMatch&&optOnMatch());frameStack.pop();scopeStack.pop();})))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[1],[],[],tokenFunc,"constant.character.escape.js",optOnMatch))) {} else { return false; } return matchResult;} }),1: ({ scopes:"source.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[2],["support.class.js","support.constant.js","keyword.operator.js"],[0,0,1,1,2,2],tokenFunc,"meta.class.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[3],["support.class.js","support.constant.js","entity.name.function.js","keyword.operator.js","storage.type.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7],tokenFunc,"meta.function.prototype.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[4],["support.class.js","support.constant.js","entity.name.function.js","keyword.operator.js"],[0,0,1,1,2,2,3,3],tokenFunc,"meta.function.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[5],["support.class.js","entity.name.function.js","keyword.operator.js","storage.type.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,0,1,1,2,2,3,3,4,4,5,5,6,6],tokenFunc,"meta.function.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[6],["entity.name.function.js","keyword.operator.js","storage.type.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,0,1,1,2,2,3,3,4,4,5,5],tokenFunc,"meta.function.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[7],["storage.type.function.js","entity.name.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,0,1,1,2,2,3,3,4,4],tokenFunc,"meta.function.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[8],["entity.name.function.js","storage.type.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,0,1,1,2,2,3,3,4,4],tokenFunc,"meta.function.json.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[9],["string.quoted.single.js","punctuation.definition.string.begin.js","entity.name.function.js","punctuation.definition.string.end.js","string.quoted.double.js","punctuation.definition.string.begin.js","entity.name.function.js","punctuation.definition.string.end.js","entity.name.function.js","punctuation.definition.parameters.begin.js","variable.parameter.function.js","punctuation.definition.parameters.end.js"],[0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,8,8,9,9,10,10,11,11],tokenFunc,"meta.function.json.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[10],["keyword.operator.new.js","entity.name.type.instance.js"],[0,0,1,1],tokenFunc,"meta.class.instance.constructor",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[11],[],[],tokenFunc,"entity.name.type.object.js.firebug",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[12],[],[],tokenFunc,"support.function.js.firebug",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[13],[],[],tokenFunc,"constant.numeric.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[14],["punctuation.definition.string.begin.js"],[0,0],tokenFunc,"string.quoted.single.js",optOnMatch))) {frameStack.push(2);scopeStack.push(" string.quoted.single.js");} else if ((matchResult = tryMatch2(str,startIndex,exs[15],["punctuation.definition.string.begin.js"],[0,0],tokenFunc,"string.quoted.double.js",optOnMatch))) {frameStack.push(3);scopeStack.push(" string.quoted.double.js");} else if ((matchResult = tryMatch2(str,startIndex,exs[16],["punctuation.definition.comment.js"],[0,0],tokenFunc,"comment.block.documentation.js",optOnMatch))) {frameStack.push(4);scopeStack.push(" comment.block.documentation.js");} else if ((matchResult = tryMatch2(str,startIndex,exs[17],["punctuation.definition.comment.js"],[0,0],tokenFunc,"comment.block.js",optOnMatch))) {frameStack.push(5);scopeStack.push(" comment.block.js");} else if ((matchResult = tryMatch2(str,startIndex,exs[18],["punctuation.definition.comment.js"],[0,0],tokenFunc,"comment.line.double-slash.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[19],["punctuation.definition.comment.html.js"],[0,0],tokenFunc,"comment.block.html.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[20],[],[],tokenFunc,"storage.type.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[21],[],[],tokenFunc,"storage.modifier.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[22],[],[],tokenFunc,"keyword.control.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[23],[],[],tokenFunc,"keyword.operator.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[24],[],[],tokenFunc,"constant.language.boolean.true.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[25],[],[],tokenFunc,"constant.language.boolean.false.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[26],[],[],tokenFunc,"constant.language.null.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[27],[],[],tokenFunc,"variable.language.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[28],[],[],tokenFunc,"keyword.other.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[29],[],[],tokenFunc,"support.class.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[30],[],[],tokenFunc,"support.function.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[31],[],[],tokenFunc,"support.function.dom.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,(rxTest(str,rxs[32],(startIndex - 1))?exs[32]:null),[],[],tokenFunc,"support.constant.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,(rxTest(str,rxs[32],(startIndex - 1))?exs[33]:null),[],[],tokenFunc,"support.constant.dom.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[34],[],[],tokenFunc,"support.constant.dom.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[35],[],[],tokenFunc,"support.function.event-handler.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,((! rxTest(str,rxs[37],(startIndex - 1)))?exs[36]:exs[37]),[],[],tokenFunc,"keyword.operator.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[38],[],[],tokenFunc,"constant.language.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,(((rxTest(str,rxs[41],(startIndex - 0)) || rxTest(str,rxs[42],(startIndex - 1))) || rxTest(str,rxs[43],(startIndex - 6)))?exs[39]:null),["punctuation.definition.string.begin.js"],[0,0],tokenFunc,"string.regexp.js",optOnMatch))) {frameStack.push(6);scopeStack.push(" string.regexp.js");} else if ((matchResult = tryMatch2(str,startIndex,exs[40],[],[],tokenFunc,"punctuation.terminator.statement.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[41],[],[],tokenFunc,"meta.delimiter.object.comma.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[42],[],[],tokenFunc,"meta.delimiter.method.period.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[43],[],[],tokenFunc,"meta.brace.curly.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[44],[],[],tokenFunc,"meta.brace.round.js",optOnMatch))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[45],[],[],tokenFunc,"meta.brace.square.js",optOnMatch))) {} else { return false; } return matchResult;} }),6: ({ scopes:"string.regexp.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[46],["punctuation.definition.string.end.js"],[0,0],tokenFunc,"string.regexp.js",(function() {(optOnMatch&&optOnMatch());frameStack.pop();scopeStack.pop();})))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[47],[],[],tokenFunc,"constant.character.escape.js",optOnMatch))) {} else { return false; } return matchResult;} }),4: ({ scopes:"comment.block.documentation.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[48],["punctuation.definition.comment.js"],[0,0],tokenFunc,"comment.block.documentation.js",(function() {(optOnMatch&&optOnMatch());frameStack.pop();scopeStack.pop();})))) {} else { return false; } return matchResult;} }),5: ({ scopes:"comment.block.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[49],["punctuation.definition.comment.js"],[0,0],tokenFunc,"comment.block.js",(function() {(optOnMatch&&optOnMatch());frameStack.pop();scopeStack.pop();})))) {} else { return false; } return matchResult;} }),2: ({ scopes:"string.quoted.single.js", go:function(str,startIndex,tokenFunc0,frameStack,scopeStack,optOnMatch) {var tokenFunc = function(txt, scps) { tokenFunc0(txt, (scopeStack.join('')+(scps&&' '+scps)).substring(1)); }; var matchResult; if ((matchResult = tryMatch2(str,startIndex,exs[50],["punctuation.definition.string.end.js"],[0,0],tokenFunc,"string.quoted.single.js",(function() {(optOnMatch&&optOnMatch());frameStack.pop();scopeStack.pop();})))) {} else if ((matchResult = tryMatch2(str,startIndex,exs[51],[],[],tokenFunc,"constant.character.escape.js",optOnMatch))) {} else { return false; } return matchResult;} })};
+var parseLine = function(line, stateString, tokenFunc) {
+ var frameStack = stateString.split('/');
+ var scopeStack = [];
+ for(var i=0;i<frameStack.length;i++) {
+ var scps = frames[frameStack[i]].scopes;
+ scopeStack.push(scps && " "+scps);
+ }
+ var idx = 0;
+ var lineLen = line.length;
+ var tokenizedIdx = 0;
+ var tokenizeUnmatched = function() {
+ if (idx > tokenizedIdx) {
+ tokenFunc(line.substring(tokenizedIdx, idx), scopeStack.join('').substring(1));
+ tokenizedIdx = idx;
+ }
+ }
+ while(idx < lineLen) {
+ var frameResult = frames[frameStack[frameStack.length-1]].go(
+ line, idx, tokenFunc, frameStack, scopeStack, tokenizeUnmatched);
+ if (frameResult) {
+ idx += frameResult[0];
+ tokenizedIdx += frameResult[0];
+ }
+ else {
+ idx++;
+ }
+ }
+ tokenizeUnmatched();
+ return frameStack.join('/');
+ };
+ var getClassesForScope = (function(scope) { return (((/(?:^| )comment(?=\.| |$)|(?:^| )extract\.custom\.title\.sql(?=\.| |$)/.test(scope) && " t1") || "")+((/(?:^| )custom\.title\.sql(?=\.| |$)/.test(scope) && " t2") || "")+((/(?:^| )keyword(?=\.| |$)|(?:^| )storage(?=\.| |$)/.test(scope) && " t3") || "")+((/(?:^| )constant\.numeric(?=\.| |$)/.test(scope) && " t4") || "")+((/(?:^| )constant(?=\.| |$)/.test(scope) && " t5") || "")+((/(?:^| )constant\.language(?=\.| |$)/.test(scope) && " t6") || "")+((/(?:^| )variable\.language(?=\.| |$)|(?:^| )variable\.other(?=\.| |$)/.test(scope) && " t7") || "")+((/(?:^| )string(?=\.| |$)/.test(scope) && " t8") || "")+((/(?:^| )constant\.character\.escape(?=\.| |$)|(?:^| )string(?=\.| |$).*?(?:^| )source(?=\.| |$)/.test(scope) && " t9") || "")+((/(?:^| )meta\.preprocessor(?=\.| |$)/.test(scope) && " t10") || "")+((/(?:^| )keyword\.control\.import(?=\.| |$)/.test(scope) && " t11") || "")+((/(?:^| )entity\.name\.function(?=\.| |$)|(?:^| )support\.function\.any(?=\.| |$)/.test(scope) && " t12") || "")+((/(?:^| )entity\.name\.type(?=\.| |$)/.test(scope) && " t13") || "")+((/(?:^| )entity\.other\.inherited(?=\.| |$)/.test(scope) && " t14") || "")+((/(?:^| )variable\.parameter(?=\.| |$)/.test(scope) && " t15") || "")+((/(?:^| )storage\.type\.method(?=\.| |$)/.test(scope) && " t16") || "")+((/(?:^| )meta\.section(?=\.| |$).*?(?:^| )entity\.name\.section(?=\.| |$)|(?:^| )declaration\.section(?=\.| |$).*?(?:^| )entity\.name\.section(?=\.| |$)/.test(scope) && " t17") || "")+((/(?:^| )support\.function(?=\.| |$)/.test(scope) && " t18") || "")+((/(?:^| )support\.class(?=\.| |$)|(?:^| )support\.type(?=\.| |$)/.test(scope) && " t19") || "")+((/(?:^| )support\.constant(?=\.| |$)/.test(scope) && " t20") || "")+((/(?:^| )support\.variable(?=\.| |$)/.test(scope) && " t21") || "")+((/(?:^| )keyword\.operator\.js(?=\.| |$)/.test(scope) && " t22") || "")+((/(?:^| )invalid(?=\.| |$)/.test(scope) && " t23") || "")+((/(?:^| )invalid\.deprecated\.trailing(?=\.| |$)/.test(scope) && " t24") || "")+((/(?:^| )text(?=\.| |$).*?(?:^| )source(?=\.| |$)|(?:^| )string\.unquoted(?=\.| |$)/.test(scope) && " t25") || "")+((/(?:^| )text(?=\.| |$).*?(?:^| )source(?=\.| |$).*?(?:^| )string\.unquoted(?=\.| |$)|(?:^| )text(?=\.| |$).*?(?:^| )source(?=\.| |$).*?(?:^| )text(?=\.| |$).*?(?:^| )source(?=\.| |$)/.test(scope) && " t26") || "")+((/(?:^| )meta\.tag\.preprocessor\.xml(?=\.| |$)/.test(scope) && " t27") || "")+((/(?:^| )meta\.tag\.sgml\.doctype(?=\.| |$)|(?:^| )meta\.tag\.sgml\.doctype(?=\.| |$).*?(?:^| )entity(?=\.| |$)|(?:^| )meta\.tag\.sgml\.doctype(?=\.| |$).*?(?:^| )string(?=\.| |$)|(?:^| )meta\.tag\.preprocessor\.xml(?=\.| |$)|(?:^| )meta\.tag\.preprocessor\.xml(?=\.| |$).*?(?:^| )entity(?=\.| |$)|(?:^| )meta\.tag\.preprocessor\.xml(?=\.| |$).*?(?:^| )string(?=\.| |$)/.test(scope) && " t28") || "")+((/(?:^| )string\.quoted\.docinfo\.doctype\.DTD(?=\.| |$)/.test(scope) && " t29") || "")+((/(?:^| )meta\.tag(?=\.| |$)|(?:^| )declaration\.tag(?=\.| |$)/.test(scope) && " t30") || "")+((/(?:^| )entity\.name\.tag(?=\.| |$)/.test(scope) && " t31") || "")+((/(?:^| )entity\.other\.attribute(?=\.| |$)/.test(scope) && " t32") || "")+((/(?:^| )markup\.heading(?=\.| |$)/.test(scope) && " t33") || "")+((/(?:^| )markup\.quote(?=\.| |$)/.test(scope) && " t34") || "")+((/(?:^| )markup\.list(?=\.| |$)/.test(scope) && " t35") || "")).substring(1); });
+ return {parseLine:parseLine, initialState:"1",
+ getClassesForScope:getClassesForScope};}())
diff --git a/infrastructure/ace/www/lexer_support.js b/infrastructure/ace/www/lexer_support.js
new file mode 100644
index 0000000..3d54f5c
--- /dev/null
+++ b/infrastructure/ace/www/lexer_support.js
@@ -0,0 +1,1068 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/* This file is also a Helma module, referenced by its path! */
+
+AceLexer = (function lexer_init() {
+
+// utility functions, make this file self-contained
+
+function forEach(array, func) {
+ for(var i=0;i<array.length;i++) {
+ var result = func(array[i], i);
+ if (result) break;
+ }
+}
+
+function map(array, func) {
+ var result = [];
+ // must remain compatible with "arguments" pseudo-array
+ for(var i=0;i<array.length;i++) {
+ if (func) result.push(func(array[i], i));
+ else result.push(array[i]);
+ }
+ return result;
+}
+
+function filter(array, func) {
+ var result = [];
+ // must remain compatible with "arguments" pseudo-array
+ for(var i=0;i<array.length;i++) {
+ if (func(array[i], i)) result.push(array[i]);
+ }
+ return result;
+}
+
+function isArray(testObject) {
+ return testObject && typeof testObject === 'object' &&
+ !(testObject.propertyIsEnumerable('length')) &&
+ typeof testObject.length === 'number';
+}
+
+// these three lines inspired by Steven Levithan's XRegExp
+var singleLineRegex = /(?:[^[\\.]+|\\(?:[\S\s]|$)|\[\^?]?(?:[^\\\]]+|\\(?:[\S\s]|$))*]?)+|\./g;
+var backReferenceRegex = /(?:[^\\[]+|\\(?:[^0-9]|$)|\[\^?]?(?:[^\\\]]+|\\(?:[\S\s]|$))*]?)+|\\([0-9]+)/g;
+var parenFindingRegex = /(?:[^[(\\]+|\\(?:[\S\s]|$)|\[\^?]?(?:[^\\\]]+|\\(?:[\S\s]|$))*]?|\((?=\?))+|(\()/g;
+
+// Creates a function that, when called with (string, startIndex), finds the first of the patterns that
+// matches the string starting at startIndex (and anchored there). Expects startIndex < string.length.
+// The function returns a structure containing "whichCase", a number 0..(patterns.length-1) giving the
+// index of the pattern that matched, or -1 if no pattern did, and "result", an array of the kind
+// returned by RegExp.exec called on that pattern, or the array that would be returned by matching /[\S\s]/
+// (any single character) if no other pattern matched. Supports the flags 'i', 'm', and 's', where the
+// effect of 's' is to make dots match all characters, including newlines.
+// Patterns in general are not allowed to match zero-width strings, but a pattern that is specified
+// as a regular expression literal with the 'm' flag is considered special, and may be zero-width,
+// though as a consequence the match cannot include the final newline of the document. (Other flags
+// on regular expression literals are ignored; use the "flags" argument instead.)
+function makeRegexSwitch(patterns, flags) {
+ var numPatterns = patterns.length;
+ var patternStrings = map(patterns, function (p) {
+ if ((typeof p) == "string")
+ return p; // a string
+ else return p.source; // assume it's a regex
+ });
+ var patternZeros = map(patterns, function (p) {
+ // using "multiline" is a special way to indicate the reg-ex is zero-width
+ return ((typeof p) != "string") && p.multiline;
+ });
+ patternStrings.push("[\\S\\s]"); // default case
+ patternZeros.push(false);
+ // how many capturing groups each pattern has
+ var numGroups = map(patternStrings, function (p) {
+ var count = 0;
+ p.replace(parenFindingRegex, function (full,paren,offset) { if (paren) count++; });
+ return count;
+ });
+ // the group number for each case of the switch
+ var caseGroupNums = [];
+ var idx = 1;
+ forEach(numGroups, function (n) { caseGroupNums.push(idx); idx += n+1; });
+ // make a big alternation of capturing groups
+ var alternation = map(patternStrings, function(p, pi) {
+ // correct the back-reference numbers
+ p = p.replace(backReferenceRegex, function (full, num) {
+ if (num) return "\\"+((+num)+caseGroupNums[pi]);
+ else return full;
+ });
+ var extra = (patternZeros[pi] ? "[\\S\\s]": ""); // tack on another char for zero-widths
+ return '('+p+extra+')';
+ }).join('|');
+ // process regex flags
+ flags = (flags || "");
+ var realFlags = "g";
+ for(var i=0;i<flags.length;i++) {
+ var f = flags.charAt(i);
+ if (f == "i" || f == "m") realFlags += f;
+ else if (f == "s") {
+ alternation = alternation.replace(singleLineRegex,
+ function (x) { return x==='.' ? "[\\S\\s]" : x; });
+ }
+ }
+ //console.log(alternation);
+ var bigRegex = new RegExp(alternation, realFlags);
+ return function (string, matchIndex) {
+ bigRegex.lastIndex = matchIndex;
+ var execResult = bigRegex.exec(string);
+ var whichCase;
+ var resultArray = [];
+ // search linearly for which case matched in the alternation
+ for(var i=0;i<=numPatterns;i++) {
+ var groupNum = caseGroupNums[i];
+ if (execResult[groupNum]) {
+ whichCase = i;
+ for(var j=0;j<=numGroups[i];j++) {
+ var r = execResult[groupNum+j];
+ if (patternZeros[i] && j==0) {
+ r = r.substring(0, r.length-1);
+ }
+ resultArray[j] = r;
+ }
+ break;
+ }
+ }
+ if (whichCase == numPatterns)
+ whichCase = -1; // default case
+ return {whichCase: whichCase, result: resultArray};
+ }
+}
+
+
+var tokenClasses = {
+ 'Token': '',
+
+ 'Text': '',
+ 'TEST': 'test',
+ 'Whitespace': 'w',
+ 'Error': 'err',
+ 'Other': 'x',
+ 'Dirty': 'dirty',
+
+ 'Keyword': 'k',
+ 'Keyword.Constant': 'kc',
+ 'Keyword.Declaration': 'kd',
+ 'Keyword.Pseudo': 'kp',
+ 'Keyword.Reserved': 'kr',
+ 'Keyword.Type': 'kt',
+
+ 'Name': 'n',
+ 'Name.Attribute': 'na',
+ 'Name.Builtin': 'nb',
+ 'Name.Builtin.Pseudo': 'bp',
+ 'Name.Class': 'nc',
+ 'Name.Constant': 'no',
+ 'Name.Decorator': 'nd',
+ 'Name.Entity': 'ni',
+ 'Name.Exception': 'ne',
+ 'Name.Function': 'nf',
+ 'Name.Property': 'py',
+ 'Name.Label': 'nl',
+ 'Name.Namespace': 'nn',
+ 'Name.Other': 'nx',
+ 'Name.Tag': 'nt',
+ 'Name.Variable': 'nv',
+ 'Name.Variable.Class': 'vc',
+ 'Name.Variable.Global': 'vg',
+ 'Name.Variable.Instance': 'vi',
+
+ 'Literal': 'l',
+ 'Literal.Date': 'ld',
+
+ 'String': 's',
+ 'String.Backtick': 'sb',
+ 'String.Char': 'sc',
+ 'String.Doc': 'sd',
+ 'String.Double': 's2',
+ 'String.Escape': 'se',
+ 'String.Heredoc': 'sh',
+ 'String.Interpol': 'si',
+ 'String.Other': 'sx',
+ 'String.Regex': 'sr',
+ 'String.Single': 's1',
+ 'String.Symbol': 'ss',
+
+ 'Number': 'm',
+ 'Number.Float': 'mf',
+ 'Number.Hex': 'mh',
+ 'Number.Integer': 'mi',
+ 'Number.Integer.Long': 'il',
+ 'Number.Oct': 'mo',
+
+ 'Operator': 'o',
+ 'Operator.Word': 'ow',
+
+ 'Punctuation': 'p',
+
+ 'Comment': 'c',
+ 'Comment.Multiline': 'cm',
+ 'Comment.Preproc': 'cp',
+ 'Comment.Single': 'c1',
+ 'Comment.Special': 'cs',
+
+ 'Generic': 'g',
+ 'Generic.Deleted': 'gd',
+ 'Generic.Emph': 'ge',
+ 'Generic.Error': 'gr',
+ 'Generic.Heading': 'gh',
+ 'Generic.Inserted': 'gi',
+ 'Generic.Output': 'go',
+ 'Generic.Prompt': 'gp',
+ 'Generic.Strong': 'gs',
+ 'Generic.Subheading': 'gu',
+ 'Generic.Traceback': 'gt'
+}
+
+
+function makeTokenProducer(regexData, flags) {
+ var data = {};
+ var procCasesMap = {};
+
+ // topological sort of state dependencies
+ var statesToProcess = [];
+ var sortedStates = [];
+ var sortedStatesMap = {};
+ for(var state in regexData) statesToProcess.push(state);
+ while (statesToProcess.length > 0) {
+ var state = statesToProcess.shift();
+ var stateReady = true;
+ forEach(regexData[state], function (c) {
+ if ((typeof c) == "object" && c.include) {
+ var otherState = c.include;
+ if (/!$/.exec(otherState)) {
+ otherState = otherState.substring(0, otherState.length-1);
+ }
+ if (! sortedStatesMap[otherState]) {
+ stateReady = false;
+ return true;
+ }
+ }
+ });
+ if (stateReady) {
+ sortedStates.push(state);
+ sortedStatesMap[state] = true;
+ }
+ else {
+ // move to end of queue
+ statesToProcess.push(state);
+ }
+ }
+
+ forEach(sortedStates, function(state) {
+ var cases = regexData[state];
+ var procCases = [];
+ forEach(cases, function (c) {
+ if ((typeof c) == "object" && c.include) {
+ var otherState = c.include;
+ var isBang = false;
+ if (/!$/.exec(otherState)) {
+ // "bang" include, returns to other state
+ otherState = otherState.substring(0, otherState.length-1);
+ isBang = true;
+ }
+ forEach(procCasesMap[otherState], function (d) {
+ var dd = [d[0], d[1], d[2]];
+ if (isBang) {
+ if (! (d[2] && d[2][0] && d[2][0].indexOf('#pop') != 0)) {
+ dd[2] = ['#pop', otherState].concat(d[2] || []);
+ }
+ }
+ procCases.push(dd);
+ });
+ }
+ else procCases.push(c);
+ });
+ procCasesMap[state] = procCases;
+ data[state] = {
+ switcher: makeRegexSwitch(map(procCases, function(x) { return x[0]; }), flags),
+ tokenTypes: map(procCases, function(x) { return x[1]; }),
+ stateEffects: map(procCases, function(y) {
+ var x = y[2];
+ if (!x) return [];
+ if (isArray(x)) return x;
+ return [x];
+ })
+ }
+ });
+
+ // mutates stateStack, calls tokenFunc on each new token in order, returns new index
+ return function(string, startIndex, stateStack, tokenFunc) {
+ var stateBefore = stateStack.join('/');
+
+ while (true) { // loop until non-zero-length token
+ var stateData = data[stateStack[stateStack.length-1]];
+ var switcherResult = stateData.switcher(string, startIndex);
+ var whichCase = switcherResult.whichCase;
+ var regexResult = switcherResult.result;
+ var tokenTypes, stateEffects;
+ if (whichCase < 0) {
+ tokenTypes = 'Error';
+ stateEffects = null;
+ }
+ else {
+ tokenTypes = stateData.tokenTypes[whichCase];
+ stateEffects = stateData.stateEffects[whichCase];
+ }
+
+ if (stateEffects) {
+ forEach(stateEffects, function (se) {
+ if (se === '#pop') stateStack.pop();
+ else if (se === '#popall') {
+ while (stateStack.length > 0) stateStack.pop();
+ }
+ else stateStack.push(se);
+ });
+ }
+ var stateAfter = stateStack.join('/');
+
+ if (regexResult[0].length > 0) {
+ if ((typeof tokenTypes) === "object" && tokenTypes.bygroups) {
+ var types = tokenTypes.bygroups;
+ forEach(types, function (t,i) {
+ var tkn = { width:regexResult[i+1].length, type:t };
+ if (i == 0) tkn.stateBefore = stateBefore;
+ if (i == (types.length-1)) tkn.stateAfter = stateAfter;
+ tokenFunc(tkn);
+ });
+ }
+ else {
+ tokenFunc({ width:regexResult[0].length, type:tokenTypes,
+ stateBefore:stateBefore, stateAfter:stateAfter });
+ }
+ return startIndex + regexResult[0].length;
+ }
+ }
+ }
+}
+
+function makeSimpleLexer(tokenProducer) {
+ function lexString(str, tokenFunc) {
+ var state = ['root'];
+ var idx = 0;
+ while (idx < str.length) {
+ var i = idx;
+ idx = tokenProducer(str, idx, state, function (tkn) {
+ tokenFunc(str.substr(i, tkn.width), tkn.type);
+ i += tkn.width;
+ });
+ }
+ }
+ function lexAsLines(str, tokenFunc, newLineFunc) {
+ str += "\n";
+ var nextNewline = str.indexOf('\n');
+ var curIndex = 0;
+
+ lexString(str, function(txt, typ) {
+ var wid = txt.length;
+ var widthLeft = wid;
+ while (widthLeft > 0 && curIndex + wid > nextNewline) {
+ var w = nextNewline - curIndex;
+ if (w > 0) {
+ tokenFunc(str.substr(curIndex, w), typ);
+ }
+ curIndex += (w+1);
+ widthLeft -= (w+1);
+ if (curIndex < str.length) {
+ newLineFunc();
+ nextNewline = str.indexOf("\n", curIndex);
+ }
+ }
+ if (widthLeft > 0) {
+ tokenFunc(str.substr(curIndex, widthLeft), typ);
+ curIndex += widthLeft;
+ }
+ });
+ }
+ return {lexString:lexString, lexAsLines:lexAsLines};
+}
+
+var txtTokenProducer = makeTokenProducer(
+ {
+ 'root': [
+ [/.*?\n/, 'Text'],
+ [/.+/, 'Text']
+ ]
+ }, 's');
+
+var jsTokenProducer = makeTokenProducer(
+ {
+ 'root': [
+ [/\/\*[^\w\n]+appjet:version[^\w\n]+[0-9.]+[^\w\n]+\*\/[^\w\n]*(?=\n)/,
+ 'Comment.Special', 'main'],
+ [/(?:)/m, 'Text', ['main', 'regex-ready', 'linestart']]
+ ],
+ 'whitespace' : [
+ [/\n/, 'Text', 'linestart'],
+ [/[^\S\n]+/, 'Text'],
+ [/\/\*/, 'Comment', 'longcomment']
+ ],
+ 'common' : [
+ {include:'whitespace'},
+ [/\"/, 'String.Double', 'dstr'],
+ [/\'/, 'String.Single', 'sstr']
+ ],
+ 'regex-ready' : [
+ {include:'whitespace'},
+ [/\/(?:[^[\\\n\/]|\\.|\[\^?]?(?:[^\\\]\n]|\\.)+\]?)+\/[gim]*/, 'String.Regex'],
+ [/(?:)/m, 'Text', '#pop']
+ ],
+ 'main': [
+ [/\"\"\"/, 'String.Doc', 'mstr'],
+ {include:"common"},
+ [/<!--/, 'Comment'],
+ [/\/\/.*?(?=\n)/, 'Comment'],
+ [/[\{\}\[\]\(;]/, 'Punctuation', 'regex-ready'],
+ [/[\).]/, 'Punctuation'],
+ [/[~\^\*!%&<>\|=:,\/?\\]/, 'Operator', 'regex-ready'],
+ [/[+-]/, 'Operator'],
+ ['(import|break|case|catch|const|continue|default|delete|do|else|'+
+ 'export|for|function|if|in|instanceof|label|new|return|switch|this|'+
+ 'throw|try|typeof|var|void|while|with|abstract|boolean|byte|catch|char|'+
+ 'class|const|debugger|double|enum|extends|final|finally|float|goto|implements|'+
+ 'int|interface|long|native|package|private|protected|public|short|static|super|'+
+ 'synchronized|throws|transient|volatile|let|yield)\\b', 'Keyword'],
+ [/(true|false|null|NaN|Infinity|undefined)\b/, 'Keyword.Constant'],
+ [/[$a-zA-Z_][a-zA-Z0-9_]*/, 'Name.Other'],
+ [/[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?/, 'Number.Float'],
+ [/0x[0-9a-f]+/, 'Number.Hex'],
+ [/[0-9]+/, 'Number.Integer']
+ ],
+ 'csscommon': [ // common outside of style rule brackets
+ {include:'common'},
+ [/\{/, 'Punctuation', 'csscontent'],
+ [/\:[a-zA-Z0-9_-]+/, 'Name.Decorator'],
+ [/\.[a-zA-Z0-9_-]+/, 'Name.Class'],
+ [/\#[a-zA-Z0-9_-]+/, 'Name.Function'],
+ [/[a-zA-Z0-9_-]+/, 'Name.Tag'],
+ [/[~\^\*!%&\[\]\(\)<>\|+=@:;,.\/?-]/, 'Operator']
+ ],
+ 'cssmain': [
+ [/(@media)([^\S\n]+)(\w+)([^\S\n]*)(\{)/, {bygroups:['Keyword', 'Text', 'String',
+ 'Text', 'Punctuation']}, 'cssmedia'],
+ {include:'csscommon'}
+ ],
+ 'cssmedia': [
+ {include:'csscommon'},
+ [/\}/, 'Punctuation', '#pop']
+ ],
+ 'csscontent': [
+ {include:'common'},
+ [/\}/, 'Punctuation', '#pop'],
+ [/url\(.*?\)/, 'String.Other'],
+ ['(azimuth|background-attachment|background-color|'+
+ 'background-image|background-position|background-repeat|'+
+ 'background|border-bottom-color|border-bottom-style|'+
+ 'border-bottom-width|border-left-color|border-left-style|'+
+ 'border-left-width|border-right|border-right-color|'+
+ 'border-right-style|border-right-width|border-top-color|'+
+ 'border-top-style|border-top-width|border-bottom|'+
+ 'border-collapse|border-left|border-width|border-color|'+
+ 'border-spacing|border-style|border-top|border|caption-side|'+
+ 'clear|clip|color|content|counter-increment|counter-reset|'+
+ 'cue-after|cue-before|cue|cursor|direction|display|'+
+ 'elevation|empty-cells|float|font-family|font-size|'+
+ 'font-size-adjust|font-stretch|font-style|font-variant|'+
+ 'font-weight|font|height|letter-spacing|line-height|'+
+ 'list-style-type|list-style-image|list-style-position|'+
+ 'list-style|margin-bottom|margin-left|margin-right|'+
+ 'margin-top|margin|marker-offset|marks|max-height|max-width|'+
+ 'min-height|min-width|opacity|orphans|outline|outline-color|'+
+ 'outline-style|outline-width|overflow|padding-bottom|'+
+ 'padding-left|padding-right|padding-top|padding|page|'+
+ 'page-break-after|page-break-before|page-break-inside|'+
+ 'pause-after|pause-before|pause|pitch|pitch-range|'+
+ 'play-during|position|quotes|richness|right|size|'+
+ 'speak-header|speak-numeral|speak-punctuation|speak|'+
+ 'speech-rate|stress|table-layout|text-align|text-decoration|'+
+ 'text-indent|text-shadow|text-transform|top|unicode-bidi|'+
+ 'vertical-align|visibility|voice-family|volume|white-space|'+
+ 'widows|width|word-spacing|z-index|bottom|left|'+
+ 'above|absolute|always|armenian|aural|auto|avoid|baseline|'+
+ 'behind|below|bidi-override|blink|block|bold|bolder|both|'+
+ 'capitalize|center-left|center-right|center|circle|'+
+ 'cjk-ideographic|close-quote|collapse|condensed|continuous|'+
+ 'crop|crosshair|cross|cursive|dashed|decimal-leading-zero|'+
+ 'decimal|default|digits|disc|dotted|double|e-resize|embed|'+
+ 'extra-condensed|extra-expanded|expanded|fantasy|far-left|'+
+ 'far-right|faster|fast|fixed|georgian|groove|hebrew|help|'+
+ 'hidden|hide|higher|high|hiragana-iroha|hiragana|icon|'+
+ 'inherit|inline-table|inline|inset|inside|invert|italic|'+
+ 'justify|katakana-iroha|katakana|landscape|larger|large|'+
+ 'left-side|leftwards|level|lighter|line-through|list-item|'+
+ 'loud|lower-alpha|lower-greek|lower-roman|lowercase|ltr|'+
+ 'lower|low|medium|message-box|middle|mix|monospace|'+
+ 'n-resize|narrower|ne-resize|no-close-quote|no-open-quote|'+
+ 'no-repeat|none|normal|nowrap|nw-resize|oblique|once|'+
+ 'open-quote|outset|outside|overline|pointer|portrait|px|'+
+ 'relative|repeat-x|repeat-y|repeat|rgb|ridge|right-side|'+
+ 'rightwards|s-resize|sans-serif|scroll|se-resize|'+
+ 'semi-condensed|semi-expanded|separate|serif|show|silent|'+
+ 'slow|slower|small-caps|small-caption|smaller|soft|solid|'+
+ 'spell-out|square|static|status-bar|super|sw-resize|'+
+ 'table-caption|table-cell|table-column|table-column-group|'+
+ 'table-footer-group|table-header-group|table-row|'+
+ 'table-row-group|text|text-bottom|text-top|thick|thin|'+
+ 'transparent|ultra-condensed|ultra-expanded|underline|'+
+ 'upper-alpha|upper-latin|upper-roman|uppercase|url|'+
+ 'visible|w-resize|wait|wider|x-fast|x-high|x-large|x-loud|'+
+ 'x-low|x-small|x-soft|xx-large|xx-small|yes)\\b', 'Keyword'],
+ ['(indigo|gold|firebrick|indianred|yellow|darkolivegreen|'+
+ 'darkseagreen|mediumvioletred|mediumorchid|chartreuse|'+
+ 'mediumslateblue|black|springgreen|crimson|lightsalmon|brown|'+
+ 'turquoise|olivedrab|cyan|silver|skyblue|gray|darkturquoise|'+
+ 'goldenrod|darkgreen|darkviolet|darkgray|lightpink|teal|'+
+ 'darkmagenta|lightgoldenrodyellow|lavender|yellowgreen|thistle|'+
+ 'violet|navy|orchid|blue|ghostwhite|honeydew|cornflowerblue|'+
+ 'darkblue|darkkhaki|mediumpurple|cornsilk|red|bisque|slategray|'+
+ 'darkcyan|khaki|wheat|deepskyblue|darkred|steelblue|aliceblue|'+
+ 'gainsboro|mediumturquoise|floralwhite|coral|purple|lightgrey|'+
+ 'lightcyan|darksalmon|beige|azure|lightsteelblue|oldlace|'+
+ 'greenyellow|royalblue|lightseagreen|mistyrose|sienna|'+
+ 'lightcoral|orangered|navajowhite|lime|palegreen|burlywood|'+
+ 'seashell|mediumspringgreen|fuchsia|papayawhip|blanchedalmond|'+
+ 'peru|aquamarine|white|darkslategray|ivory|dodgerblue|'+
+ 'lemonchiffon|chocolate|orange|forestgreen|slateblue|olive|'+
+ 'mintcream|antiquewhite|darkorange|cadetblue|moccasin|'+
+ 'limegreen|saddlebrown|darkslateblue|lightskyblue|deeppink|'+
+ 'plum|aqua|darkgoldenrod|maroon|sandybrown|magenta|tan|'+
+ 'rosybrown|pink|lightblue|palevioletred|mediumseagreen|'+
+ 'dimgray|powderblue|seagreen|snow|mediumblue|midnightblue|'+
+ 'paleturquoise|palegoldenrod|whitesmoke|darkorchid|salmon|'+
+ 'lightslategray|lawngreen|lightgreen|tomato|hotpink|'+
+ 'lightyellow|lavenderblush|linen|mediumaquamarine|green|'+
+ 'blueviolet|peachpuff)\\b', 'Name.Builtin'],
+ [/\!important/, 'Comment.Preproc'],
+ [/\#[a-zA-Z0-9]{1,6}/, 'Number'],
+ [/[\.-]?[0-9]*[\.]?[0-9]+(em|px|\%|pt|pc|in|mm|cm|ex)/, 'Number'],
+ [/-?[0-9]+/, 'Number'],
+ [/[~\^\*!%&<>\|+=@:,.\/?-]+/, 'Operator'],
+ [/[\[\]();]+/, 'Punctuation'],
+ [/[a-zA-Z][a-zA-Z0-9]+/, 'Name']
+ ],
+ 'linestart': [
+ [/\/\*[^\w\n]+appjet:css[^\w\n]+\*\/[^\w\n]*(?=\n)/, 'Comment.Special',
+ ['#popall', 'root', 'cssmain']],
+ [/\/\*[^\w\n]+appjet:(\w+)[^\w\n]+\*\/[^\w\n]*(?=\n)/, 'Comment.Special',
+ ['#popall', 'root', 'main', 'regex-ready']],
+ [/(?:)/m, 'Text', '#pop']
+ ],
+ 'dstr': [
+ [/\"/, 'String.Double', '#pop'],
+ [/(?=\n)/m, 'String.Double', '#pop'],
+ [/(\\\\|\\\"|[^\"\n])+/, 'String.Double']
+ ],
+ 'sstr': [
+ [/\'/, 'String.Single', '#pop'],
+ [/(?=\n)/m, 'String.Single', '#pop'],
+ [/(\\\\|\\\'|[^\'\n])+/, 'String.Single']
+ ],
+ 'longcomment': [
+ [/\*\//, 'Comment', '#pop'],
+ [/\n/, 'Comment'],
+ [/.+?(?:\n|(?=\*\/))/, 'Comment']
+ ],
+ 'mstr': [
+ [/(\\\"\"\"|\n)/, 'String.Doc'],
+ [/\"\"\"/, 'String.Doc', '#pop'],
+ [/.+?(?=\\"""|"""|\n)/, 'String.Doc']
+ ]
+ }
+);
+
+function escapeHTML(s) {
+ var re = /[&<>\'\" ]/g;
+ if (! re.MAP) {
+ // persisted across function calls!
+ re.MAP = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;',
+ ' ': '&#160;'
+ };
+ }
+ return s.replace(re, function(c) { return re.MAP[c]; });
+}
+
+var simpleLexer = makeSimpleLexer(jsTokenProducer);
+
+function codeStringToHTML(codeString) {
+ var atLineStart = true;
+ var html = [];
+ function tokenFunc(txt, type) {
+ var cls = tokenClasses[type];
+ if (cls) html.push('<tt class="',tokenClasses[type],'">');
+ else html.push('<tt>');
+ html.push(escapeHTML(txt),'</tt>');
+ atLineStart = false;
+ }
+ function newLineFunc() {
+ html.push('<br/>\n');
+ atLineStart = true;
+ }
+ simpleLexer.lexAsLines(codeString, tokenFunc, newLineFunc);
+ if (atLineStart) html.push('<br/>\n');
+ return html.join('');
+}
+
+/* ========== Incremental Lexer for ACE ========== */
+
+function makeIncrementalLexer(tokenProducer) {
+
+ var tokens = newSkipList();
+ var buffer = "";
+ var nextId = 1;
+ var dirtyTokenKeys = [];
+ var uncoloredRanges = [];
+
+ //top.dbg_uncoloredRanges = function() { return uncoloredRanges; }
+ //top.dbg_dirtyTokenKeys = function() { return dirtyTokenKeys; }
+
+ function mergeRangesIfTouching(a, b) {
+ // if a = [a0,a1] and b = [b0,b1] are overlapping or touching, return a single merged range
+ // else return null
+ var a0 = a[0], a1 = a[1], b0 = b[0], b1 = b[1];
+ if (a1 < b0) return null;
+ if (b1 < a0) return null;
+ var c0 = ((a0 < b0) ? a0 : b0);
+ var c1 = ((a1 > b1) ? a1 : b1);
+ return [c0,c1];
+ }
+
+ function addUncoloredRange(rng) {
+ // shouldn't this merge existing ranges if the new range overlaps multiple ones?
+ var done = false;
+ forEach(uncoloredRanges, function (x, i) {
+ var merged = mergeRangesIfTouching(x, rng);
+ if (merged) {
+ uncoloredRanges[i] = merged;
+ done = true;
+ return true;
+ }
+ });
+ if (! done) {
+ uncoloredRanges.push(rng);
+ }
+ }
+
+ function removeUncoloredRange(rng) {
+ var i = uncoloredRanges.length-1;
+ while (i >= 0) {
+ removeUncoloredRangeFrom(rng, i);
+ i--;
+ }
+ }
+
+ function removeUncoloredRangeFrom(rangeToRemove, containingRangeIndex) {
+ var idx = containingRangeIndex;
+ var cont = uncoloredRanges[idx];
+ var rem0 = rangeToRemove[0], rem1 = rangeToRemove[1];
+ // limit to containing range
+ if (rem0 < cont[0]) rem0 = cont[0];
+ if (rem1 > cont[1]) rem1 = cont[1];
+ if (rem1 <= rem0) return;
+ // splice out uncoloredRanes[containingRangeIndex] for 0, 1, or 2 ranges
+ uncoloredRanges.splice(idx, 1);
+ if (cont[0] < rem0)
+ uncoloredRanges.splice(idx, 0, [cont[0], rem0]);
+ if (rem1 < cont[1])
+ uncoloredRanges.splice(idx, 0, [rem1, cont[1]]);
+ }
+
+ function prepareTokens(tokenArray) {
+ forEach(tokenArray, function (t) {
+ t.key = "$"+(nextId++);
+ });
+ return tokenArray;
+ }
+
+ function roundBackToTokenBoundary(charOffset) {
+ return tokens.indexOfOffset(charOffset);
+ }
+ function roundForwardToTokenBoundary(charOffset) {
+ var tokenEnd;
+ if (charOffset == tokens.totalWidth())
+ tokenEnd = tokens.length();
+ else {
+ var endToken = tokens.keyAtOffset(charOffset);
+ tokenEnd = tokens.indexOfKey(endToken);
+ // round up to nearest token boundary
+ if (charOffset > tokens.offsetOfKey(endToken)) {
+ tokenEnd++;
+ }
+ }
+ return tokenEnd;
+ }
+
+ // findLexingStartPoint and findLexingEndPoint take a character boundary
+ // (0 .. buffer.length) and return a token boundary (0 .. tokens.length())
+ // that, if not at the document edge, is such that the next token outside
+ // the boundary has a pre/post lexing state associated with it (i.e is not
+ // a dirty-region token or in the middle of a multi-token lexing rule).
+
+ function findLexingStartPoint(startChar) {
+ if (tokens.length() == 0) return 0;
+ var tokenStart = roundBackToTokenBoundary(startChar);
+ // expand to not break up a series of tokens from the same
+ // lexing rule, and to include dirty regions
+ if (tokenStart > 0) {
+ var tokenBefore = tokens.atIndex(tokenStart - 1);
+ while (tokenBefore && (! tokenBefore.stateAfter)) {
+ tokenStart--;
+ tokenBefore = tokens.prev(tokenBefore);
+ }
+ }
+ return tokenStart;
+ }
+
+ function findLexingEndPoint(endChar) {
+ if (tokens.length() == 0) return 0;
+ var tokenEnd = roundForwardToTokenBoundary(endChar);
+ // expand to not break up a series of tokens from the same
+ // lexing rule, and to include dirty regions
+ if (tokenEnd < tokens.length()) {
+ var tokenAfter = tokens.atIndex(tokenEnd);
+ while (tokenAfter && (! tokenAfter.stateBefore)) {
+ tokenEnd++;
+ tokenAfter = tokens.next(tokenAfter);
+ }
+ }
+ return tokenEnd;
+ }
+
+ function updateBuffer(newBuffer, spliceStart, charsRemoved, charsAdded) {
+ buffer = newBuffer;
+
+ // back up to new line
+ if (spliceStart > 0) {
+ var newStart = buffer.lastIndexOf('\n', spliceStart-1) + 1;
+ var charsBack = spliceStart - newStart;
+ spliceStart -= charsBack;
+ charsRemoved += charsBack;
+ charsAdded += charsBack;
+ }
+ // expand to lexing points
+ var tokenRangeStart = findLexingStartPoint(spliceStart);
+ var tokenRangeEnd = findLexingEndPoint(spliceStart + charsRemoved);
+
+ var dirtyWidth = 0;
+ // make sure to mark at least one token dirty so that deletions correctly cause
+ // rehighlighting; in practice doesn't come up often except when an entire line
+ // is cleanly deleted, like deleting a blank line (which doesn't usually affect highlighting)
+ while (dirtyWidth == 0) {
+ var curStart = tokens.offsetOfIndex(tokenRangeStart);
+ var curEnd = tokens.offsetOfIndex(tokenRangeEnd);
+ dirtyWidth = (curEnd - curStart) + (charsAdded - charsRemoved);
+ if (dirtyWidth == 0) {
+ if (curEnd >= tokens.totalWidth()) break;
+ tokenRangeEnd = findLexingEndPoint(curEnd+1);
+ }
+ }
+
+ var dirtyTokens = []; // 0 or 1 of them
+ if (dirtyWidth > 0) {
+ dirtyTokens.push({ width: dirtyWidth, type: 'Dirty' });
+ }
+
+ //console.log("%d, %d, %d, %d", charsRemoved, charsAdded,
+ //(curEnd - curStart), dirtyWidth);
+
+ tokens.splice(tokenRangeStart, tokenRangeEnd - tokenRangeStart,
+ prepareTokens(dirtyTokens));
+
+ if (tokens.totalWidth() != buffer.length) {
+ console.error("updateBuffer: Bad total token width: "+
+ tokens.totalWidth()+" not "+buffer.length);
+ }
+
+ forEach(dirtyTokens, function (t) { dirtyTokenKeys.push(t.key); });
+ dirtyTokenKeys = filter(dirtyTokenKeys, function (k) { return tokens.containsKey(k); });
+ //console.log("after update: %s", toSource(tokens.slice()));
+
+ function applySpliceToIndex(i) {
+ if (i <= spliceStart) return i;
+ if (i >= (spliceStart + charsRemoved)) return i + charsAdded - charsRemoved;
+ return spliceStart;
+ }
+ for(var i=uncoloredRanges.length-1; i>=0; i--) {
+ var r = uncoloredRanges[i];
+ r[0] = applySpliceToIndex(r[0]);
+ r[1] = applySpliceToIndex(r[1]);
+ if (r[1] <= r[0]) uncoloredRanges.splice(i, 1);
+ }
+ }
+
+ function processDirtyToken(dirtyToken, isTimeUp, stopAtChar) {
+
+ //console.time("lexing");
+ //var p = PROFILER("lex", false);
+ var stateStack;
+ if (! tokens.prev(dirtyToken)) stateStack = ['root'];
+ else stateStack = tokens.prev(dirtyToken).stateAfter.split('/');
+ var newTokens = [];
+ var dirtyTokenIndex = tokens.indexOfEntry(dirtyToken);
+ var tokenCount = 0;
+ var startTime = (new Date()).getTime();
+ var stopBasedOnChar = (typeof(stopAtChar) == "number");
+ //p.mark("tokenize");
+
+ var curOffset = tokens.offsetOfEntry(dirtyToken);
+ var startedOffset = curOffset;
+ var oldToken = dirtyToken;
+ var oldTokenOffset = curOffset;
+ var done = false;
+
+ while ((! done) && (! isTimeUp()) && (! (stopBasedOnChar && curOffset >= stopAtChar))) {
+ curOffset = tokenProducer(buffer, curOffset, stateStack,
+ function (t) { newTokens.push(t); });
+ while (oldToken && (oldTokenOffset + oldToken.width <= curOffset)) {
+ oldTokenOffset += oldToken.width;
+ oldToken = tokens.next(oldToken);
+ }
+ if (curOffset == tokens.totalWidth()) {
+ // hit the end
+ done = true;
+ }
+ else if (oldTokenOffset == curOffset) {
+ // at a token boundary, the beginning of oldTokenOffset
+ if (stateStack.join('/') === oldToken.stateBefore) {
+ // state matches up, we can stop
+ done = true;
+ }
+ }
+ }
+
+ var endedOffset = curOffset;
+ var dist = endedOffset - startedOffset;
+ var tokensToRemove;
+ var newDirtyToken;
+ if (dist < dirtyToken.width) {
+ tokens.setEntryWidth(dirtyToken, dirtyToken.width - dist);
+ tokensToRemove = 0;
+ newDirtyToken = dirtyToken;
+ }
+ else {
+ var nextLexingPoint = findLexingEndPoint(endedOffset);
+ var lexingPointChar = tokens.offsetOfIndex(nextLexingPoint);
+ if (lexingPointChar == endedOffset && (! done) && endedOffset < tokens.totalWidth()) {
+ // happened to stop at token boundary before end, but not done lexing,
+ // so make next token dirty
+ nextLexingPoint = findLexingEndPoint(endedOffset+1);
+ lexingPointChar = tokens.offsetOfIndex(nextLexingPoint);
+ }
+ var dirtyCharsLeft = lexingPointChar - endedOffset;
+ if (dirtyCharsLeft > 0) {
+ newDirtyToken = { width: dirtyCharsLeft, type: 'Dirty' };
+ newTokens.push(newDirtyToken);
+ }
+ tokensToRemove = nextLexingPoint - dirtyTokenIndex;
+ }
+
+ //p.mark("prepare");
+ prepareTokens(newTokens);
+ //p.mark("remove");
+ tokens.splice(dirtyTokenIndex, tokensToRemove, []);
+ //p.mark("insert");
+ tokens.splice(dirtyTokenIndex, 0, newTokens);
+ if (tokens.totalWidth() != buffer.length)
+ console.error("processDirtyToken: Bad total token width: "+
+ tokens.totalWidth()+" not "+buffer.length);
+ //p.end();
+
+ addUncoloredRange([startedOffset, endedOffset]);
+
+ //console.log("processed chars %d to %d", startedOffset, endedOffset);
+ //console.timeEnd("lexing");
+
+ return (newDirtyToken && newDirtyToken.key);
+ }
+
+ function lexSomeDirty(filter, isTimeUp) {
+ var newDirtyTokenKeys = [];
+
+ forEach(dirtyTokenKeys, function (dirtyKey) {
+ if (! tokens.containsKey(dirtyKey)) return;
+ var dirtyToken = tokens.atKey(dirtyKey);
+ var filterResult;
+ if ((! isTimeUp()) && ((filterResult = filter(dirtyToken)))) {
+ var stopAtChar;
+ if ((typeof filterResult) == "object" && (typeof filterResult.stopAtChar) == "number") {
+ stopAtChar = filterResult.stopAtChar;
+ }
+ var tkn = processDirtyToken(dirtyToken, isTimeUp, filterResult.stopAtChar);
+ if (tkn) newDirtyTokenKeys.push(tkn);
+ }
+ else {
+ // leave the token behind
+ newDirtyTokenKeys.push(dirtyKey);
+ }
+
+ if (tokens.totalWidth() != buffer.length)
+ console.error("Bad total token width: "+tokens.totalWidth()+" not "+buffer.length);
+
+ });
+
+ dirtyTokenKeys = newDirtyTokenKeys;
+ }
+
+ function lexCharRange(charRange, isTimeUp) {
+ //var startTime = (new Date()).getTime();
+ //function isTimeUp() { return ((new Date()).getTime() - startTime) > timeLimit; }
+
+ if (isTimeUp()) return;
+
+ lexSomeDirty(function (dirtyToken) {
+ var start = tokens.offsetOfEntry(dirtyToken);
+ var end = start + dirtyToken.width;
+ if (end <= charRange[0]) return false;
+ if (start >= charRange[1]) return false;
+ //console.log("tokenStart: %d, tokenEnd: %d, visStart: %d, visEnd: %d",
+ //start, end, charRange[0], charRange[1]);
+ var result = {};
+ if (charRange[1] < end) {
+ result.stopAtChar = charRange[1];
+ }
+ return result;
+ }, isTimeUp);
+
+ //if (isTimeUp()) return;
+
+ /*
+ // highlight the visible area
+ var i = uncoloredRanges.length-1;
+ // iterate backwards because we change the array
+ while (i >= 0) {
+ var rng = uncoloredRanges[i];
+ var start = rng[0], end = rng[1];
+ if (start < viewRange[0]) start = viewRange[0];
+ if (end > viewRange[1]) end = viewRange[1];
+ if (end > start) {
+ var charsRecolored = recolorFunc(start, end-start,
+ isTimeUp, getSpansForRange);
+ removeUncoloredSubrange([start, start+charsRecolored], i);
+ }
+ if (isTimeUp()) break;
+ i--;
+ }*/
+ }
+
+ function tokenToString(tkn) {
+ return toSource({width:tkn.width, type:tkn.type, stateBefore:tkn.stateBefore, stateAfter:tkn.stateAfter});
+ }
+
+ // Calls func(startChar, endChar) on each range of characters that needs to be colored
+ // in the DOM, based on calls to getSpansForRange (which removes chars from consideration)
+ // and lexCharRange (which calculates new colors and adds chars for consideration).
+ // There are usually relatively few uncolored ranges, each of which may be many lines,
+ // even the whole document.
+ // func must return true iff any tokens are accessed through getSpansForRange during
+ // the call. func should not do new lexing.
+ function forEachUncoloredRange(func, isTimeUp) {
+ var i = 0;
+ // uncoloredRanges will change during this function!
+ // Terminates is time runs out, whole document is colored,
+ // or the func "passes" on all ranges by returning false.
+ while (i < uncoloredRanges.length && ! isTimeUp()) {
+ var rng = uncoloredRanges[i];
+ var returnVal = func(rng[0], rng[1], isTimeUp);
+ if (returnVal) {
+ // func did something, uncolored ranges may have changed around
+ i = 0;
+ }
+ else {
+ i++;
+ }
+ }
+ }
+
+ // Like forEachUncoloredRange, but "cropped" to the char range given. For example,
+ // if no "uncolored ranges" extend by a non-zero amount into the char range,
+ // func will never be called.
+ function forEachUncoloredSubrange(startChar, endChar, func, isTimeUp) {
+ forEachUncoloredRange(function (s, e, isTimeUp2) {
+ if (s < startChar) s = startChar;
+ if (e > endChar) e = endChar;
+ if (e > s) {
+ return func(s, e, isTimeUp2);
+ }
+ return false;
+ }, isTimeUp);
+ }
+
+ // This function takes note of what it's passed, and assumes that part of the
+ // DOM has been taken care of (unless justPeek).
+ // The "func" takes arguments tokenWidth and tokenClass, and is called on each
+ // token in the range, with the widths adding up to the range size.
+ function getSpansForRange(startChar, endChar, func, justPeek) {
+
+ if (startChar == endChar) return;
+
+ var startToken = tokens.atOffset(startChar);
+ var startTokenStart = tokens.offsetOfEntry(startToken);
+ var curOffset = startChar;
+ var curToken = startToken;
+ while (curOffset < endChar) {
+ var spanEnd;
+ if (curToken === startToken) {
+ spanEnd = startTokenStart + startToken.width;
+ }
+ else {
+ spanEnd = curOffset + curToken.width;
+ }
+ if (spanEnd > endChar) spanEnd = endChar;
+ if (spanEnd > curOffset) {
+ func(spanEnd - curOffset, tokenClasses[curToken.type]);
+ }
+ curOffset = spanEnd;
+ curToken = tokens.next(curToken);
+ }
+
+ if (! justPeek) removeUncoloredRange([startChar, endChar]);
+ }
+
+ function markRangeUncolored(start, end) {
+ addUncoloredRange([start, end]);
+ }
+
+ return {
+ updateBuffer: updateBuffer,
+ lexCharRange: lexCharRange,
+ getSpansForRange: getSpansForRange,
+ forEachUncoloredSubrange: forEachUncoloredSubrange,
+ markRangeUncolored: markRangeUncolored
+ };
+}
+
+/* ========== End Incremental Lexer ========== */
+
+tokenProds = {js: jsTokenProducer, txt: txtTokenProducer};
+
+function getTokenProducer(type) {
+ return tokenProds[type || 'txt'] || tokenProds['txt'];
+}
+
+function getIncrementalLexer(type) {
+ return makeIncrementalLexer(getTokenProducer(type));
+}
+function getSimpleLexer(type) {
+ return makeSimpleLexer(getTokenProducer(type));
+}
+
+return {getIncrementalLexer:getIncrementalLexer, getSimpleLexer:getSimpleLexer,
+ codeStringToHTML:codeStringToHTML};
+
+})();
diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js
new file mode 100644
index 0000000..0ac578b
--- /dev/null
+++ b/infrastructure/ace/www/linestylefilter.js
@@ -0,0 +1,247 @@
+// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.linestylefilter
+// %APPJET%: import("etherpad.collab.ace.easysync2.Changeset");
+
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// requires: easysync2.Changeset
+
+var linestylefilter = {};
+
+linestylefilter.ATTRIB_CLASSES = {
+ 'bold':'tag:b',
+ 'italic':'tag:i',
+ 'underline':'tag:u',
+ 'strikethrough':'tag:s'
+};
+
+linestylefilter.getAuthorClassName = function(author) {
+ return "author-"+author.replace(/[^a-y0-9]/g, function(c) {
+ if (c == ".") return "-";
+ return 'z'+c.charCodeAt(0)+'z';
+ });
+};
+
+// lineLength is without newline; aline includes newline,
+// but may be falsy if lineLength == 0
+linestylefilter.getLineStyleFilter = function(lineLength, aline,
+ textAndClassFunc, apool) {
+
+ if (lineLength == 0) return textAndClassFunc;
+
+ var nextAfterAuthorColors = textAndClassFunc;
+
+ var authorColorFunc = (function() {
+ var lineEnd = lineLength;
+ var curIndex = 0;
+ var extraClasses;
+ var leftInAuthor;
+
+ function attribsToClasses(attribs) {
+ var classes = '';
+ Changeset.eachAttribNumber(attribs, function(n) {
+ var key = apool.getAttribKey(n);
+ if (key) {
+ var value = apool.getAttribValue(n);
+ if (value) {
+ if (key == 'author') {
+ classes += ' '+linestylefilter.getAuthorClassName(value);
+ }
+ else if (key == 'list') {
+ classes += ' list:'+value;
+ }
+ else if (linestylefilter.ATTRIB_CLASSES[key]) {
+ classes += ' '+linestylefilter.ATTRIB_CLASSES[key];
+ }
+ }
+ }
+ });
+ return classes.substring(1);
+ }
+
+ var attributionIter = Changeset.opIterator(aline);
+ var nextOp, nextOpClasses;
+ function goNextOp() {
+ nextOp = attributionIter.next();
+ nextOpClasses = (nextOp.opcode && attribsToClasses(nextOp.attribs));
+ }
+ goNextOp();
+ function nextClasses() {
+ if (curIndex < lineEnd) {
+ extraClasses = nextOpClasses;
+ leftInAuthor = nextOp.chars;
+ goNextOp();
+ while (nextOp.opcode && nextOpClasses == extraClasses) {
+ leftInAuthor += nextOp.chars;
+ goNextOp();
+ }
+ }
+ }
+ nextClasses();
+
+ return function(txt, cls) {
+ while (txt.length > 0) {
+ if (leftInAuthor <= 0) {
+ // prevent infinite loop if something funny's going on
+ return nextAfterAuthorColors(txt, cls);
+ }
+ var spanSize = txt.length;
+ if (spanSize > leftInAuthor) {
+ spanSize = leftInAuthor;
+ }
+ var curTxt = txt.substring(0, spanSize);
+ txt = txt.substring(spanSize);
+ nextAfterAuthorColors(curTxt, (cls&&cls+" ")+extraClasses);
+ curIndex += spanSize;
+ leftInAuthor -= spanSize;
+ if (leftInAuthor == 0) {
+ nextClasses();
+ }
+ }
+ };
+ })();
+ return authorColorFunc;
+};
+
+linestylefilter.getAtSignSplitterFilter = function(lineText,
+ textAndClassFunc) {
+ var at = /@/g;
+ at.lastIndex = 0;
+ var splitPoints = null;
+ var execResult;
+ while ((execResult = at.exec(lineText))) {
+ if (! splitPoints) {
+ splitPoints = [];
+ }
+ splitPoints.push(execResult.index);
+ }
+
+ if (! splitPoints) return textAndClassFunc;
+
+ return linestylefilter.textAndClassFuncSplitter(textAndClassFunc,
+ splitPoints);
+};
+
+linestylefilter.REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
+linestylefilter.REGEX_URLCHAR = new RegExp('('+/[-:@a-zA-Z0-9_.,~%+\/\\?=&#;()$]/.source+'|'+linestylefilter.REGEX_WORDCHAR.source+')');
+linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt):\/\/|mailto:)/.source+linestylefilter.REGEX_URLCHAR.source+'*(?![:.,;])'+linestylefilter.REGEX_URLCHAR.source, 'g');
+
+linestylefilter.getURLFilter = function(lineText, textAndClassFunc) {
+ linestylefilter.REGEX_URL.lastIndex = 0;
+ var urls = null;
+ var splitPoints = null;
+ var execResult;
+ while ((execResult = linestylefilter.REGEX_URL.exec(lineText))) {
+ if (! urls) {
+ urls = [];
+ splitPoints = [];
+ }
+ var startIndex = execResult.index;
+ var url = execResult[0];
+ urls.push([startIndex, url]);
+ splitPoints.push(startIndex, startIndex + url.length);
+ }
+
+ if (! urls) return textAndClassFunc;
+
+ function urlForIndex(idx) {
+ for(var k=0; k<urls.length; k++) {
+ var u = urls[k];
+ if (idx >= u[0] && idx < u[0]+u[1].length) {
+ return u[1];
+ }
+ }
+ return false;
+ }
+
+ var handleUrlsAfterSplit = (function() {
+ var curIndex = 0;
+ return function(txt, cls) {
+ var txtlen = txt.length;
+ var newCls = cls;
+ var url = urlForIndex(curIndex);
+ if (url) {
+ newCls += " url:"+url;
+ }
+ textAndClassFunc(txt, newCls);
+ curIndex += txtlen;
+ };
+ })();
+
+ return linestylefilter.textAndClassFuncSplitter(handleUrlsAfterSplit,
+ splitPoints);
+};
+
+linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) {
+ var nextPointIndex = 0;
+ var idx = 0;
+
+ // don't split at 0
+ while (splitPointsOpt &&
+ nextPointIndex < splitPointsOpt.length &&
+ splitPointsOpt[nextPointIndex] == 0) {
+ nextPointIndex++;
+ }
+
+ function spanHandler(txt, cls) {
+ if ((! splitPointsOpt) || nextPointIndex >= splitPointsOpt.length) {
+ func(txt, cls);
+ idx += txt.length;
+ }
+ else {
+ var splitPoints = splitPointsOpt;
+ var pointLocInSpan = splitPoints[nextPointIndex] - idx;
+ var txtlen = txt.length;
+ if (pointLocInSpan >= txtlen) {
+ func(txt, cls);
+ idx += txt.length;
+ if (pointLocInSpan == txtlen) {
+ nextPointIndex++;
+ }
+ }
+ else {
+ if (pointLocInSpan > 0) {
+ func(txt.substring(0, pointLocInSpan), cls);
+ idx += pointLocInSpan;
+ }
+ nextPointIndex++;
+ // recurse
+ spanHandler(txt.substring(pointLocInSpan), cls);
+ }
+ }
+ }
+ return spanHandler;
+};
+
+// domLineObj is like that returned by domline.createDomLine
+linestylefilter.populateDomLine = function(textLine, aline, apool,
+ domLineObj) {
+ // remove final newline from text if any
+ var text = textLine;
+ if (text.slice(-1) == '\n') {
+ text = text.substring(0, text.length-1);
+ }
+
+ function textAndClassFunc(tokenText, tokenClass) {
+ domLineObj.appendSpan(tokenText, tokenClass);
+ }
+
+ var func = textAndClassFunc;
+ func = linestylefilter.getURLFilter(text, func);
+ func = linestylefilter.getLineStyleFilter(text.length, aline,
+ func, apool);
+ func(text, '');
+};
diff --git a/infrastructure/ace/www/magicdom.js b/infrastructure/ace/www/magicdom.js
new file mode 100644
index 0000000..4bad3d4
--- /dev/null
+++ b/infrastructure/ace/www/magicdom.js
@@ -0,0 +1,293 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+function makeMagicDom(rootDomNode, contentWindow){
+ function nodeToString(node) {
+ if (isNodeText(node)) return '"'+node.nodeValue+'"';
+ else return '&lt;'+node.tagName+'&gt;';
+ }
+
+ var doc = rootDomNode.ownerDocument || rootDomNode.document;
+
+ function childIndex(dnode) {
+ var idx = 0;
+ var n = dnode;
+ while (n.previousSibling) {
+ idx++;
+ n = n.previousSibling;
+ }
+ return idx;
+ }
+
+ function ensureNormalized(dnode) {
+ function mergePair(text1, text2) {
+ var theParent = text1.parentNode;
+ var newTextNode = mdom.doc.createTextNode(text1.nodeValue+""+text2.nodeValue);
+ theParent.insertBefore(newTextNode, text1);
+ theParent.removeChild(text1);
+ theParent.removeChild(text2);
+ return newTextNode;
+ }
+
+ var n = dnode;
+ if (!isNodeText(n)) return;
+ while (n.previousSibling && isNodeText(n.previousSibling)) {
+ n = mergePair(n.previousSibling, n);
+ }
+ while (n.nextSibling && isNodeText(n.nextSibling)) {
+ n = mergePair(n, n.nextSibling);
+ }
+ }
+
+ function nextUniqueId() {
+ // returns new unique identifier string;
+ // not actually checked for uniqueness, but unique
+ // wrt magicdom.
+ // is document-unique to allow document.getElementById even
+ // in theoretical case of multiple magicdoms per doc
+ var doc = mdom.doc;
+ var nextId = (getAssoc(doc, "nextId") || 1);
+ setAssoc(doc, "nextId", nextId+1);
+ return "magicdomid"+nextId;
+ }
+
+ var nodeProto = {
+ parent: function() {
+ return wrapDom(((! this.isRoot) && this.dom.parentNode) || null);
+ },
+ index: function() {
+ return childIndex(this.dom);
+ },
+ equals: function (otherNode) {
+ return otherNode && otherNode.dom && (this.dom == otherNode.dom);
+ },
+ prev: function() {
+ return wrapDom(this.dom.previousSibling || null);
+ },
+ next: function() {
+ return wrapDom(this.dom.nextSibling || null);
+ },
+ remove: function() {
+ if (! this.isRoot) {
+ var dnode = this.dom;
+ var prevSib = dnode.previousSibling;
+ var nextSib = dnode.nextSibling;
+ var normalizeNeeded = (prevSib && isNodeText(prevSib) && nextSib && isNodeText(nextSib));
+ var theParent = dnode.parentNode;
+ theParent.removeChild(dnode);
+ if (normalizeNeeded) {
+ ensureNormalized(prevSib);
+ }
+ }
+ },
+ addNext: function (newNode) {
+ var dnode = this.dom;
+ var nextSib = dnode.nextSibling;
+ if (nextSib) {
+ dnode.parentNode.insertBefore(newNode.dom, nextSib);
+ }
+ else {
+ dnode.parentNode.appendChild(newNode.dom);
+ }
+ if (newNode.isText) ensureNormalized(newNode.dom);
+ },
+ addPrev: function (newNode) {
+ var dnode = this.dom;
+ dnode.parentNode.insertBefore(newNode.dom, dnode);
+ if (newNode.isText) ensureNormalized(newNode.dom);
+ },
+ replaceWith: function (newNodes) { // var-args
+ this.replaceWithArray(arguments);
+ },
+ replaceWithArray: function (newNodes) {
+ var addFunc;
+ if (this.next()) {
+ var next = this.next();
+ addFunc = function (n) { next.addPrev(n); };
+ }
+ else {
+ var parent = this.parent();
+ addFunc = function (n) { parent.appendChild(n); };
+ }
+ // when using "this" functions, have to keep text
+ // nodes from merging inappropriately
+ var tempNode = mdom.newElement("span");
+ this.addNext(tempNode);
+ this.remove();
+ forEach(newNodes, function (n) {
+ addFunc(n);
+ });
+ tempNode.remove();
+ },
+ getProp: function (propName) {
+ return getAssoc(this.dom, propName);
+ },
+ setProp: function (propName, value) {
+ setAssoc(this.dom, propName, value);
+ },
+ // not consistent between browsers in how line-breaks are handled
+ innerText: function() {
+ var dnode = this.dom;
+ if ((typeof dnode.innerText) == "string") return dnode.innerText;
+ if ((typeof dnode.textContent) == "string") return dnode.textContent;
+ if ((typeof dnode.nodeValue) == "string") return dnode.nodeValue;
+ return "";
+ },
+ depth: function() {
+ try { // ZZZ
+ var d = 0;
+ var n = this;
+ while (! n.isRoot) {
+ d++;
+ n = n.parent();
+ }
+ return d;
+ }
+ catch (e) {
+ parent.BAD_NODE = this.dom;
+ throw e;
+ }
+ }
+ };
+
+ var textNodeProto = extend(object(nodeProto), {
+ isText: true,
+ text: function() {
+ return this.dom.nodeValue;
+ },
+ eachChild: function() {},
+ childCount: function() { return 0; },
+ eachDescendant: function() {},
+ // precondition: 0 <= start < end <= length
+ wrapRange: function(start, end, newNode) {
+ var origText = this.text();
+ var text1 = null;
+ if (start > 0) {
+ text1 = mdom.newText(origText.substring(0, start));
+ }
+ var text2 = mdom.newText(origText.substring(start, end));
+ var text3 = null;
+ if (end < origText.length) {
+ text3 = mdom.newText(origText.substring(end, origText.length));
+ }
+ newNode.appendChild(text2);
+ var nodesToUse = []
+ if (text1) nodesToUse.push(text1);
+ nodesToUse.push(newNode);
+ if (text3) nodesToUse.push(text3);
+ this.replaceWithArray(nodesToUse);
+ return [text1, newNode, text3];
+ }
+ });
+
+ var elementNodeProto = extend(object(nodeProto), {
+ isText: false,
+ childCount: function() {
+ return this.dom.childNodes.length;
+ },
+ child: function (i) {
+ return wrapDom(this.dom.childNodes.item(i));
+ },
+ firstChild: function() {
+ return ((this.childCount() > 0) && this.child(0)) || null;
+ },
+ lastChild: function() {
+ return ((this.childCount() > 0) && this.child(this.childCount()-1)) || null;
+ },
+ appendChild: function (newNode) {
+ this.dom.appendChild(newNode.dom);
+ if (newNode.isText) {
+ ensureNormalized(newNode.dom);
+ }
+ },
+ prependChild: function (newNode) {
+ if (this.childCount() > 0) {
+ this.child(0).addPrev(newNode);
+ }
+ else {
+ this.appendChild(newNode);
+ }
+ },
+ eachChild: function (func) {
+ for(var i=0;i<this.childCount();i++) {
+ var result = func(this.child(i), i);
+ if (result) break;
+ }
+ },
+ eachDescendant: function (func) {
+ this.eachChild(function (n) {
+ var result = func(n);
+ if (! result) n.eachDescendant(func);
+ });
+ },
+ dumpContents: function() {
+ var mnode = this, dnode = this.dom;
+ if (mnode.childCount() < 1) {
+ mnode.remove();
+ }
+ else {
+ var theParent = dnode.parentNode;
+ var n;
+ while ((n = dnode.firstChild)) {
+ dnode.removeChild(n);
+ theParent.insertBefore(n, dnode);
+ ensureNormalized(n);
+ }
+ mnode.remove();
+ }
+ },
+ uniqueId: function() {
+ // not actually guaranteed to be unique, e.g. if user copy-pastes
+ // nodes with ids
+ var dnode = this.dom;
+ if (dnode.id) return dnode.id;
+ dnode.id = nextUniqueId();
+ return dnode.id;
+ }
+ });
+
+ function wrapDom(dnode) {
+ if (! dnode) return dnode;
+ var mnode;
+ if (isNodeText(dnode)) {
+ mnode = object(textNodeProto);
+ }
+ else {
+ mnode = object(elementNodeProto);
+ }
+ mnode.isRoot = (dnode == rootDomNode);
+ mnode.dom = dnode;
+ return mnode;
+ }
+
+ var mdom = {};
+ mdom.root = wrapDom(rootDomNode);
+ mdom.doc = doc;
+ mdom.win = contentWindow;
+ mdom.byId = function (id) {
+ return wrapDom(mdom.doc.getElementById(id));
+ }
+ mdom.newText = function (txt) {
+ return wrapDom(mdom.doc.createTextNode(txt));
+ }
+ mdom.newElement = function (tagName) {
+ return wrapDom(mdom.doc.createElement(tagName));
+ }
+ mdom.wrapDom = wrapDom;
+
+ return mdom;
+}
diff --git a/infrastructure/ace/www/multilang_lexer.js b/infrastructure/ace/www/multilang_lexer.js
new file mode 100644
index 0000000..9617981
--- /dev/null
+++ b/infrastructure/ace/www/multilang_lexer.js
@@ -0,0 +1,349 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+AceLexer = (function lexer_init() {
+
+function makeIncrementalLexer(lineParser) {
+
+ var parseLine = lineParser.parseLine;
+ var initialState = lineParser.initialState;
+ var getClassesForScope = lineParser.getClassesForScope;
+
+ var lineData = newSkipList(); // one entry per line
+ var buffer = ""; // full text of document, each line ending with \n
+ var lineStatus = ""; // one char per line in buffer, (d)irty/(u)ncolored/(c)olored
+ var nextLineDataId = 1;
+
+ // "dirty" lines are unparsed lines. Other lines have properties startState,endState.
+ // "uncolored" lines are parsed but the data has not been handled by ACE.
+
+ function roundBackToLineIndex(charOffset) { // charOffset is [0,document length]
+ return lineData.indexOfOffset(charOffset);
+ // result is [0,num lines]
+ }
+
+ function roundForwardToLineIndex(charOffset) { // charOffset is [0,document length]
+ var idx = lineData.indexOfOffset(charOffset);
+ var newCharOffset = lineData.offsetOfIndex(idx);
+ if (newCharOffset < charOffset) {
+ // rounded back, round forward instead
+ return idx + 1;
+ }
+ return idx;
+ // result is [0,num lines]
+ }
+
+ function updateBuffer(newBuffer, spliceStart, charsRemoved, charsAdded) {
+ // newBuffer is string to replace buffer, other args explain the splice
+ // that happened between the old buffer and newBuffer
+
+ // determine range of lines (and character offsets of line boundaries) affected
+ var spliceStartLineIndex = roundBackToLineIndex(spliceStart);
+ var spliceStartCharOffset = lineData.offsetOfIndex(spliceStartLineIndex);
+ var spliceEndLineIndex = roundForwardToLineIndex(spliceStart + charsRemoved);
+ var spliceEndCharOffset = lineData.offsetOfIndex(spliceEndLineIndex);
+
+ var extraBeginChars = spliceStart - spliceStartCharOffset;
+ var extraEndChars = spliceEndCharOffset - (spliceStart + charsRemoved);
+ var newChars = newBuffer.substring(spliceStart - extraBeginChars,
+ spliceStart + charsAdded + extraEndChars);
+
+ var newLineEntries = [];
+ newChars.replace(/[^\n]*\n/g, function(line) {
+ newLineEntries.push({ width: line.length, key: String(nextLineDataId++) });
+ });
+
+ lineData.splice(spliceStartLineIndex, spliceEndLineIndex - spliceStartLineIndex,
+ newLineEntries);
+
+ var newDirtyStatus = "";
+ for(var i=0;i<newLineEntries.length;i++) newDirtyStatus += "d";
+ var extraDirty = 0;
+ if ((! newDirtyStatus) && spliceEndLineIndex < lineStatus.length &&
+ spliceEndLineIndex > spliceStartLineIndex) {
+ // pure deletion of one or more lines, mark the next line after
+ // the deletion as dirty to trigger relexing
+ newDirtyStatus = "d";
+ extraDirty = 1;
+ }
+ lineStatus = lineStatus.substring(0, spliceStartLineIndex) +
+ newDirtyStatus + lineStatus.substring(spliceEndLineIndex + extraDirty);
+
+ buffer = newBuffer;
+ }
+
+ function findBeginningOfDirtyRegion(dirtyLineIndex) {
+ // search backwards for a line that is either the first line
+ // or is preceded by a non-dirty line.
+ var cleanLine = Math.max(lineStatus.lastIndexOf("c", dirtyLineIndex),
+ lineStatus.lastIndexOf("u", dirtyLineIndex));
+ // cleanLine is now either -1 (if all lines are dirty back to beginning of doc)
+ // or the index of a clean line
+ return cleanLine + 1;
+ }
+
+ function findEndOfUncoloredRegion(uncoloredLineIndex) {
+ // search forwards for a line that is not uncolored,
+ // or return number of lines in doc if end of doc is hit.
+ var idx1 = lineStatus.indexOf("c", uncoloredLineIndex);
+ var idx2 = lineStatus.indexOf("d", uncoloredLineIndex);
+ if (idx1 < 0) {
+ if (idx2 < 0) return lineStatus.length;
+ else return idx2;
+ }
+ else {
+ if (idx2 < 0) return idx1;
+ else return Math.min(idx1, idx2);
+ }
+ }
+
+ function getLineText(lineIndex) {
+ var lineEntry = lineData.atIndex(lineIndex);
+ var lineTextStart = lineData.offsetOfIndex(lineIndex);
+ var lineTextEnd = lineTextStart + lineEntry.width;
+ return buffer.substring(lineTextStart, lineTextEnd);
+ }
+
+ function setLineStatus(lineIndex, status) {
+ lineStatus = lineStatus.substring(0, lineIndex) + status +
+ lineStatus.substring(lineIndex+1);
+ }
+
+ function lexCharRange(charRange, isTimeUp) {
+ if (isTimeUp()) return;
+
+ var lexStart = roundBackToLineIndex(charRange[0]);
+ var lexEnd = roundForwardToLineIndex(charRange[1]);
+
+ // can't parse a dirty line in the middle of a dirty region,
+ // no sensible start state; so find beginning of dirty region
+ var nextCandidate = findBeginningOfDirtyRegion(lexStart);
+
+ while (! isTimeUp()) {
+ // find a dirty line to parse; if may be before lexStart,
+ // but stop at lexEnd.
+ var nextDirty = lineStatus.indexOf("d", nextCandidate);
+ if (nextDirty < 0 || nextDirty >= lexEnd) {
+ break;
+ }
+ var theLineIndex = nextDirty;
+ var theLineEntry = lineData.atIndex(theLineIndex);
+ var lineText = getLineText(theLineIndex);
+
+ // assert: previous line is not dirty
+ var startState;
+ if (theLineIndex > 0) {
+ startState = lineData.atIndex(theLineIndex-1).endState;
+ }
+ else {
+ startState = initialState;
+ }
+
+ var tokenWidths = [];
+ var tokenNames = [];
+ var tokenFunc = function(str, cls) {
+ tokenWidths.push(str.length);
+ tokenNames.push(cls);
+ }
+ var endState = parseLine(lineText, startState, tokenFunc);
+
+ theLineEntry.startState = startState;
+ theLineEntry.endState = endState;
+ theLineEntry.tokenWidths = tokenWidths;
+ theLineEntry.tokenNames = tokenNames;
+
+ setLineStatus(theLineIndex, "u");
+
+ nextCandidate = theLineIndex + 1;
+ if (nextCandidate < lineStatus.length &&
+ lineStatus.charAt(nextCandidate) != "d" &&
+ lineData.atIndex(nextCandidate).startState != endState) {
+ // state has changed, lexing must continue past end of dirty
+ // region
+ setLineStatus(nextCandidate, "d");
+ }
+ }
+ }
+
+ function forEachUncoloredSubrange(startChar, endChar, func, isTimeUp) {
+ var startLine = roundBackToLineIndex(startChar);
+ var endLine = roundForwardToLineIndex(endChar);
+
+ var nextCandidate = startLine;
+
+ while (! isTimeUp()) {
+ var nextUncolored = lineStatus.indexOf("u", nextCandidate);
+ if (nextUncolored < 0 || nextUncolored >= endLine) {
+ break;
+ }
+ var uncoloredEndLine = findEndOfUncoloredRegion(nextUncolored);
+
+ var rangeStart = Math.max(startChar, lineData.offsetOfIndex(nextUncolored));
+ var rangeEnd = Math.min(endChar, lineData.offsetOfIndex(uncoloredEndLine));
+
+ func(rangeStart, rangeEnd, isTimeUp);
+
+ nextCandidate = uncoloredEndLine;
+ }
+ }
+
+ function getSpansForRange(startChar, endChar, func, justPeek) {
+ var startLine = roundBackToLineIndex(startChar);
+ var endLine = roundForwardToLineIndex(endChar);
+
+ function doToken(tokenStart, tokenWidth, tokenClass) {
+ // crop token to [startChar,endChar] range
+ if (tokenStart + tokenWidth <= startChar) return;
+ if (tokenStart >= endChar) return;
+ if (tokenStart < startChar) {
+ tokenWidth -= (startChar - tokenStart);
+ tokenStart = startChar;
+ }
+ if (tokenStart + tokenWidth > endChar) {
+ tokenWidth -= (tokenStart + tokenWidth - endChar);
+ }
+ if (tokenWidth <= 0) return;
+ func(tokenWidth, tokenClass);
+ }
+
+ for(var i=startLine; i<endLine; i++) {
+ var status = lineStatus.charAt(i);
+ var lineEntry = lineData.atIndex(i);
+ var charOffset = lineData.offsetOfIndex(i);
+ if (status == "d") {
+ doToken(charOffset, lineEntry.width, "dirty");
+ }
+ else {
+ var tokenWidths = lineEntry.tokenWidths;
+ var tokenNames = lineEntry.tokenNames;
+ for(var j=0;j<tokenWidths.length;j++) {
+ var w = tokenWidths[j];
+ doToken(charOffset, w, getClassesForScope(tokenNames[j]));
+ charOffset += w;
+ }
+ if (status != "c" && ! justPeek) {
+ setLineStatus(i, "c");
+ }
+ }
+ }
+ }
+
+ function markRangeUncolored(startChar, endChar) {
+ var startLine = roundBackToLineIndex(startChar);
+ var endLine = roundForwardToLineIndex(endChar);
+
+ function stripColors(statuses) {
+ var a = [];
+ for(var i=0;i<statuses.length;i++) {
+ var x = statuses.charAt(i);
+ a.push((x == 'c') ? 'u' : x);
+ }
+ return a.join('');
+ }
+
+ lineStatus = lineStatus.substring(0, startLine) +
+ stripColors(lineStatus.substring(startLine, endLine)) +
+ lineStatus.substring(endLine);
+ }
+
+ function _vars() {
+ return {lineData:lineData, buffer:buffer, lineStatus:lineStatus, nextLineDataId:nextLineDataId,
+ lineParser:lineParser};
+ }
+
+ return {
+ updateBuffer: updateBuffer,
+ lexCharRange: lexCharRange,
+ getSpansForRange: getSpansForRange,
+ forEachUncoloredSubrange: forEachUncoloredSubrange,
+ markRangeUncolored: markRangeUncolored,
+ _vars: _vars
+ };
+}
+
+function makeSimpleLexer(lineParser) {
+ var parseLine = lineParser.parseLine;
+ var initialState = lineParser.initialState;
+ var getClassesForScope = lineParser.getClassesForScope;
+
+ function lexAsLines(str, tokenFunc, newLineFunc) {
+ if (str.charAt(str.length-1) != '\n') {
+ str = str+'\n';
+ }
+ function doToken(txt, scope) {
+ tokenFunc(txt, getClassesForScope(scope));
+ }
+ var state = initialState;
+ str.replace(/[^\n]*\n/g, function(line) {
+ state = parseLine(line, state, doToken);
+ newLineFunc();
+ });
+ }
+
+ function lexString(str, tokenFunc) {
+ lexAsLines(str, tokenFunc, function() {});
+ }
+
+ return {lexString:lexString, lexAsLines:lexAsLines};
+}
+
+function codeStringToHTML(codeString) {
+ var simpleLexer = makeSimpleLexer(grammars["source.js"]);
+ var atLineStart = true;
+ var html = [];
+ function tokenFunc(txt, type) {
+ var cls = type;
+ if (cls) html.push('<tt class="',cls,'">');
+ else html.push('<tt>');
+ html.push(escapeHTML(txt),'</tt>');
+ atLineStart = false;
+ }
+ function newLineFunc() {
+ html.push('<br/>\n');
+ atLineStart = true;
+ }
+ simpleLexer.lexAsLines(codeString, tokenFunc, newLineFunc);
+ if (atLineStart) html.push('<br/>\n');
+ return html.join('');
+}
+
+function escapeHTML(s) {
+ var re = /[&<>\'\" ]/g;
+ if (! re.MAP) {
+ // persisted across function calls!
+ re.MAP = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;',
+ ' ': '&#160;'
+ };
+ }
+ return s.replace(re, function(c) { return re.MAP[c]; });
+}
+
+function getIncrementalLexer(type) {
+ return makeIncrementalLexer(grammars["text.html.basic"]);//grammars[type]);
+}
+function getSimpleLexer(type) {
+ return makeSimpleLexer(grammars[type]);
+}
+
+return {getIncrementalLexer:getIncrementalLexer, getSimpleLexer:getSimpleLexer,
+ codeStringToHTML:codeStringToHTML};
+
+})();
diff --git a/infrastructure/ace/www/processing.js b/infrastructure/ace/www/processing.js
new file mode 100644
index 0000000..988ef76
--- /dev/null
+++ b/infrastructure/ace/www/processing.js
@@ -0,0 +1,1714 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Processing.js - John Resig (http://ejohn.org/)
+ * MIT Licensed
+ * http://ejohn.org/blog/processingjs/
+ *
+ * This is a port of the Processing Visualization Language.
+ * More information: http://processing.org/
+ */
+
+(function(){
+
+this.Processing = function Processing( aElement, aCode )
+{
+ var p = buildProcessing( aElement );
+ p.init( aCode );
+ return p;
+};
+
+function log()
+{
+ try
+ {
+ console.log.apply( console, arguments );
+ }
+ catch(e)
+ {
+ try
+ {
+ opera.postError.apply( opera, arguments );
+ }
+ catch(e){}
+ }
+}
+
+function parse( aCode, p )
+{
+ // Angels weep at this parsing code :-(
+
+ // Remove end-of-line comments
+ aCode = aCode.replace(/\/\/ .*\n/g, "\n");
+
+ // Weird parsing errors with %
+ aCode = aCode.replace(/([^\s])%([^\s])/g, "$1 % $2");
+
+ // Simple convert a function-like thing to function
+ aCode = aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function(all, type, name, args)
+ {
+ if ( name == "if" || name == "for" || name == "while" )
+ {
+ return all;
+ }
+ else
+ {
+ return "Processing." + name + " = function " + name + args;
+ }
+ });
+
+ // Force .length() to be .length
+ aCode = aCode.replace(/\.length\(\)/g, ".length");
+
+ // foo( int foo, float bar )
+ aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4");
+ aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4");
+
+ // float[] foo = new float[5];
+ aCode = aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g, function(all, name, args)
+ {
+ return "new ArrayList(" + args.slice(1,-1).split("][").join(", ") + ")";
+ });
+
+ aCode = aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function(all)
+ {
+ return all.replace(/{/g, "[").replace(/}/g, "]");
+ });
+
+ // int|float foo;
+ var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;
+ while ( intFloat.test(aCode) )
+ {
+ aCode = aCode.replace(new RegExp(intFloat), function(all, type, name, sep)
+ {
+ return type + " " + name + " = 0" + sep;
+ });
+ }
+
+ // float foo = 5;
+ aCode = aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function(all, type, arr, name, sep)
+ {
+ if ( type == "return" )
+ return all;
+ else
+ return "var " + name + sep;
+ });
+
+ // Fix Array[] foo = {...} to [...]
+ aCode = aCode.replace(/=\s*{((.|\s)*?)};/g, function(all,data)
+ {
+ return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]";
+ });
+
+ // static { ... } blocks
+ aCode = aCode.replace(/static\s*{((.|\n)*?)}/g, function(all, init)
+ {
+ // Convert the static definitons to variable assignments
+ //return init.replace(/\((.*?)\)/g, " = $1");
+ return init;
+ });
+
+ // super() is a reserved word
+ aCode = aCode.replace(/super\(/g, "superMethod(");
+
+ var classes = ["int", "float", "boolean", "string"];
+
+ function ClassReplace(all, name, extend, vars, last)
+ {
+ classes.push( name );
+
+ var static = "";
+
+ vars = vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g, function(all,set)
+ {
+ static += " " + name + "." + set;
+ return "";
+ });
+
+ // Move arguments up from constructor and wrap contents with
+ // a with(this), and unwrap constructor
+ return "function " + name + "() {with(this){\n " +
+ (extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "") +
+ // Replace var foo = 0; with this.foo = 0;
+ // and force var foo; to become this.foo = null;
+ vars
+ .replace(/,\s?/g, ";\n this.")
+ .replace(/\b(var |final |public )+\s*/g, "this.")
+ .replace(/this.(\w+);/g, "this.$1 = null;") +
+ (extend ? "extendClass(this, " + extend + ");\n" : "") +
+ "<CLASS " + name + " " + static + ">" + (typeof last == "string" ? last : name + "(");
+ }
+
+ var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;
+ var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;
+
+ aCode = aCode.replace(matchClasses, ClassReplace);
+ aCode = aCode.replace(matchNoCon, ClassReplace);
+
+ var matchClass = /<CLASS (\w+) (.*?)>/, m;
+
+ while ( (m = aCode.match( matchClass )) )
+ {
+ var left = RegExp.leftContext,
+ allRest = RegExp.rightContext,
+ rest = nextBrace(allRest),
+ className = m[1],
+ staticVars = m[2] || "";
+
+ allRest = allRest.slice( rest.length + 1 );
+
+ rest = rest.replace(new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function(all, args)
+ {
+ args = args.split(/,\s*?/);
+
+ if ( args[0].match(/^\s*$/) )
+ args.shift();
+
+ var fn = "if ( arguments.length == " + args.length + " ) {\n";
+
+ for ( var i = 0; i < args.length; i++ )
+ {
+ fn += " var " + args[i] + " = arguments[" + i + "];\n";
+ }
+
+ return fn;
+ });
+
+ // Fix class method names
+ // this.collide = function() { ... }
+ // and add closing } for with(this) ...
+ rest = rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function(all, name, args)
+ {
+ return "ADDMETHOD(this, '" + name + "', function(" + args + ")";
+ });
+
+ var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc;
+ var methods = "";
+
+ while ( (mc = rest.match( matchMethod )) )
+ {
+ var prev = RegExp.leftContext,
+ allNext = RegExp.rightContext,
+ next = nextBrace(allNext);
+
+ methods += "addMethod" + mc[1] + next + "});"
+
+ rest = prev + allNext.slice( next.length + 1 );
+
+ }
+
+ rest = methods + rest;
+
+ aCode = left + rest + "\n}}" + staticVars + allRest;
+ }
+
+ // Do some tidying up, where necessary
+ aCode = aCode.replace(/Processing.\w+ = function addMethod/g, "addMethod");
+
+ function nextBrace( right )
+ {
+ var rest = right;
+ var position = 0;
+ var leftCount = 1, rightCount = 0;
+
+ while ( leftCount != rightCount )
+ {
+ var nextLeft = rest.indexOf("{");
+ var nextRight = rest.indexOf("}");
+
+ if ( nextLeft < nextRight && nextLeft != -1 )
+ {
+ leftCount++;
+ rest = rest.slice( nextLeft + 1 );
+ position += nextLeft + 1;
+ }
+ else
+ {
+ rightCount++;
+ rest = rest.slice( nextRight + 1 );
+ position += nextRight + 1;
+ }
+ }
+
+ return right.slice(0, position - 1);
+ }
+
+ // Handle (int) Casting
+ aCode = aCode.replace(/\(int\)/g, "0|");
+
+ // Remove Casting
+ aCode = aCode.replace(new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), "");
+
+ // Convert 3.0f to just 3.0
+ aCode = aCode.replace(/(\d+)f/g, "$1");
+
+ // Force numbers to exist
+ //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, "$1$2 = ($2||0) +");
+
+ // Force characters-as-bytes to work
+ aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)");
+
+ // Convert #aaaaaa into color
+ aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){
+ var num = toNumbers(hex);
+ return "color(" + num[0] + "," + num[1] + "," + num[2] + ")";
+ });
+
+ function toNumbers( str ){
+ var ret = [];
+ str.replace(/(..)/g, function(str){
+ ret.push( parseInt( str, 16 ) );
+ });
+ return ret;
+ }
+
+//log(aCode);
+
+ return aCode;
+}
+
+function buildProcessing( curElement ){
+
+ var p = {};
+
+ // init
+ p.PI = Math.PI;
+ p.TWO_PI = 2 * p.PI;
+ p.HALF_PI = p.PI / 2;
+ p.P3D = 3;
+ p.CORNER = 0;
+ p.CENTER = 1;
+ p.CENTER_RADIUS = 2;
+ p.RADIUS = 2;
+ p.POLYGON = 1;
+ p.TRIANGLES = 6;
+ p.POINTS = 7;
+ p.LINES = 8;
+ p.TRIANGLE_STRIP = 9;
+ p.CORNERS = 10;
+ p.CLOSE = true;
+ p.RGB = 1;
+ p.HSB = 2;
+
+ // "Private" variables used to maintain state
+ var curContext = curElement.getContext("2d");
+ var doFill = true;
+ var doStroke = true;
+ var loopStarted = false;
+ var hasBackground = false;
+ var doLoop = true;
+ var curRectMode = p.CORNER;
+ var curEllipseMode = p.CENTER;
+ var inSetup = false;
+ var inDraw = false;
+ var curBackground = "rgba(204,204,204,1)";
+ var curFrameRate = 1000;
+ var curShape = p.POLYGON;
+ var curShapeCount = 0;
+ var opacityRange = 255;
+ var redRange = 255;
+ var greenRange = 255;
+ var blueRange = 255;
+ var pathOpen = false;
+ var mousePressed = false;
+ var keyPressed = false;
+ var firstX, firstY, prevX, prevY;
+ var curColorMode = p.RGB;
+ var curTint = -1;
+ var curTextSize = 12;
+ var curTextFont = "Arial";
+ var getLoaded = false;
+ var start = (new Date).getTime();
+
+ // Global vars for tracking mouse position
+ p.pmouseX = 0;
+ p.pmouseY = 0;
+ p.mouseX = 0;
+ p.mouseY = 0;
+
+ // Will be replaced by the user, most likely
+ p.mouseDragged = undefined;
+ p.mouseMoved = undefined;
+ p.mousePressed = undefined;
+ p.mouseReleased = undefined;
+ p.keyPressed = undefined;
+ p.keyReleased = undefined;
+ p.draw = undefined;
+ p.setup = undefined;
+
+ // The height/width of the canvas
+ p.width = curElement.width - 0;
+ p.height = curElement.height - 0;
+
+ // In case I ever need to do HSV conversion:
+ // http://srufaculty.sru.edu/david.dailey/javascript/js/5rml.js
+ p.color = function color( aValue1, aValue2, aValue3, aValue4 )
+ {
+ var aColor = "";
+
+ if ( arguments.length == 3 )
+ {
+ aColor = p.color( aValue1, aValue2, aValue3, opacityRange );
+ }
+ else if ( arguments.length == 4 )
+ {
+ var a = aValue4 / opacityRange;
+ a = isNaN(a) ? 1 : a;
+
+ if ( curColorMode == p.HSB )
+ {
+ var rgb = HSBtoRGB(aValue1, aValue2, aValue3);
+ var r = rgb[0], g = rgb[1], b = rgb[2];
+ }
+ else
+ {
+ var r = getColor(aValue1, redRange);
+ var g = getColor(aValue2, greenRange);
+ var b = getColor(aValue3, blueRange);
+ }
+
+ aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")";
+ }
+ else if ( typeof aValue1 == "string" )
+ {
+ aColor = aValue1;
+
+ if ( arguments.length == 2 )
+ {
+ var c = aColor.split(",");
+ c[3] = (aValue2 / opacityRange) + ")";
+ aColor = c.join(",");
+ }
+ }
+ else if ( arguments.length == 2 )
+ {
+ aColor = p.color( aValue1, aValue1, aValue1, aValue2 );
+ }
+ else if ( typeof aValue1 == "number" )
+ {
+ aColor = p.color( aValue1, aValue1, aValue1, opacityRange );
+ }
+ else
+ {
+ aColor = p.color( redRange, greenRange, blueRange, opacityRange );
+ }
+
+ // HSB conversion function from Mootools, MIT Licensed
+ function HSBtoRGB(h, s, b)
+ {
+ h = (h / redRange) * 100;
+ s = (s / greenRange) * 100;
+ b = (b / blueRange) * 100;
+ if (s == 0){
+ return [b, b, b];
+ } else {
+ var hue = h % 360;
+ var f = hue % 60;
+ var br = Math.round(b / 100 * 255);
+ var p = Math.round((b * (100 - s)) / 10000 * 255);
+ var q = Math.round((b * (6000 - s * f)) / 600000 * 255);
+ var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255);
+ switch (Math.floor(hue / 60)){
+ case 0: return [br, t, p];
+ case 1: return [q, br, p];
+ case 2: return [p, br, t];
+ case 3: return [p, q, br];
+ case 4: return [t, p, br];
+ case 5: return [br, p, q];
+ }
+ }
+ }
+
+ function getColor( aValue, range )
+ {
+ return Math.round(255 * (aValue / range));
+ }
+
+ return aColor;
+ }
+
+ p.nf = function( num, pad )
+ {
+ var str = "" + num;
+ while ( pad - str.length )
+ str = "0" + str;
+ return str;
+ };
+
+ p.AniSprite = function( prefix, frames )
+ {
+ this.images = [];
+ this.pos = 0;
+
+ for ( var i = 0; i < frames; i++ )
+ {
+ this.images.push( prefix + p.nf( i, ("" + frames).length ) + ".gif" );
+ }
+
+ this.display = function( x, y )
+ {
+ p.image( this.images[ this.pos ], x, y );
+
+ if ( ++this.pos >= frames )
+ this.pos = 0;
+ };
+
+ this.getWidth = function()
+ {
+ return getImage(this.images[0]).width;
+ };
+
+ this.getHeight = function()
+ {
+ return getImage(this.images[0]).height;
+ };
+ };
+
+ function buildImageObject( obj )
+ {
+ var pixels = obj.data;
+ var data = p.createImage( obj.width, obj.height );
+
+ if ( data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__("pixels") )
+ {
+ var pixelsDone;
+ data.__defineGetter__("pixels", function()
+ {
+ if ( pixelsDone )
+ return pixelsDone;
+
+ pixelsDone = [];
+
+ for ( var i = 0; i < pixels.length; i += 4 )
+ {
+ pixelsDone.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
+ }
+
+ return pixelsDone;
+ });
+ }
+ else
+ {
+ data.pixels = [];
+
+ for ( var i = 0; i < pixels.length; i += 4 )
+ {
+ data.pixels.push( p.color(pixels[i], pixels[i+1], pixels[i+2], pixels[i+3]) );
+ }
+ }
+
+ return data;
+ }
+
+ p.createImage = function createImage( w, h, mode )
+ {
+ var data = {
+ width: w,
+ height: h,
+ pixels: new Array( w * h ),
+ get: function(x,y)
+ {
+ return this.pixels[w*y+x];
+ },
+ _mask: null,
+ mask: function(img)
+ {
+ this._mask = img;
+ },
+ loadPixels: function()
+ {
+ },
+ updatePixels: function()
+ {
+ }
+ };
+
+ return data;
+ }
+
+ p.createGraphics = function createGraphics( w, h )
+ {
+ var canvas = document.createElement("canvas");
+ var ret = buildProcessing( canvas );
+ ret.size( w, h );
+ ret.canvas = canvas;
+ return ret;
+ }
+
+ p.beginDraw = function beginDraw()
+ {
+
+ }
+
+ p.endDraw = function endDraw()
+ {
+
+ }
+
+ p.tint = function tint( rgb, a )
+ {
+ curTint = a;
+ }
+
+ function getImage( img ) {
+ if ( typeof img == "string" )
+ {
+ return document.getElementById(img);
+ }
+
+ if ( img.img || img.canvas )
+ {
+ return img.img || img.canvas;
+ }
+
+ img.data = [];
+
+ for ( var i = 0, l = img.pixels.length; i < l; i++ )
+ {
+ var c = (img.pixels[i] || "rgba(0,0,0,1)").slice(5,-1).split(",");
+ img.data.push( parseInt(c[0]), parseInt(c[1]), parseInt(c[2]), parseFloat(c[3]) * 100 );
+ }
+
+ var canvas = document.createElement("canvas")
+ canvas.width = img.width;
+ canvas.height = img.height;
+ var context = canvas.getContext("2d");
+ context.putImageData( img, 0, 0 );
+
+ img.canvas = canvas;
+
+ return canvas;
+ }
+
+ p.image = function image( img, x, y, w, h )
+ {
+ x = x || 0;
+ y = y || 0;
+
+ var obj = getImage(img);
+
+ if ( curTint >= 0 )
+ {
+ var oldAlpha = curContext.globalAlpha;
+ curContext.globalAlpha = curTint / opacityRange;
+ }
+
+ if ( arguments.length == 3 )
+ {
+ curContext.drawImage( obj, x, y );
+ }
+ else
+ {
+ curContext.drawImage( obj, x, y, w, h );
+ }
+
+ if ( curTint >= 0 )
+ {
+ curContext.globalAlpha = oldAlpha;
+ }
+
+ if ( img._mask )
+ {
+ var oldComposite = curContext.globalCompositeOperation;
+ curContext.globalCompositeOperation = "darker";
+ p.image( img._mask, x, y );
+ curContext.globalCompositeOperation = oldComposite;
+ }
+ }
+
+ p.exit = function exit()
+ {
+
+ }
+
+ p.save = function save( file )
+ {
+
+ }
+
+ p.loadImage = function loadImage( file )
+ {
+ var img = document.getElementById(file);
+ if ( !img )
+ return;
+
+ var h = img.height, w = img.width;
+
+ var canvas = document.createElement("canvas");
+ canvas.width = w;
+ canvas.height = h;
+ var context = canvas.getContext("2d");
+
+ context.drawImage( img, 0, 0 );
+ var data = buildImageObject( context.getImageData( 0, 0, w, h ) );
+ data.img = img;
+ return data;
+ }
+
+ p.loadFont = function loadFont( name )
+ {
+ return {
+ name: name,
+ width: function( str )
+ {
+ if ( curContext.mozMeasureText )
+ return curContext.mozMeasureText( typeof str == "number" ?
+ String.fromCharCode( str ) :
+ str) / curTextSize;
+ else
+ return 0;
+ }
+ };
+ }
+
+ p.textFont = function textFont( name, size )
+ {
+ curTextFont = name;
+ p.textSize( size );
+ }
+
+ p.textSize = function textSize( size )
+ {
+ if ( size )
+ {
+ curTextSize = size;
+ }
+ }
+
+ p.textAlign = function textAlign()
+ {
+
+ }
+
+ p.text = function text( str, x, y )
+ {
+ if ( str && curContext.mozDrawText )
+ {
+ curContext.save();
+ curContext.mozTextStyle = curTextSize + "px " + curTextFont.name;
+ curContext.translate(x, y);
+ curContext.mozDrawText( typeof str == "number" ?
+ String.fromCharCode( str ) :
+ str );
+ curContext.restore();
+ }
+ }
+
+ p.char = function char( key )
+ {
+ //return String.fromCharCode( key );
+ return key;
+ }
+
+ p.println = function println()
+ {
+
+ }
+
+ p.map = function map( value, istart, istop, ostart, ostop )
+ {
+ return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
+ };
+
+ String.prototype.replaceAll = function(re, replace)
+ {
+ return this.replace(new RegExp(re, "g"), replace);
+ };
+
+ p.Point = function Point( x, y )
+ {
+ this.x = x;
+ this.y = y;
+ this.copy = function()
+ {
+ return new Point( x, y );
+ }
+ }
+
+ p.Random = function()
+ {
+ var haveNextNextGaussian = false;
+ var nextNextGaussian;
+
+ this.nextGaussian = function()
+ {
+ if (haveNextNextGaussian) {
+ haveNextNextGaussian = false;
+
+ return nextNextGaussian;
+ } else {
+ var v1, v2, s;
+ do {
+ v1 = 2 * p.random(1) - 1; // between -1.0 and 1.0
+ v2 = 2 * p.random(1) - 1; // between -1.0 and 1.0
+ s = v1 * v1 + v2 * v2;
+ } while (s >= 1 || s == 0);
+ var multiplier = Math.sqrt(-2 * Math.log(s)/s);
+ nextNextGaussian = v2 * multiplier;
+ haveNextNextGaussian = true;
+
+ return v1 * multiplier;
+ }
+ };
+ }
+
+ p.ArrayList = function ArrayList( size, size2, size3 )
+ {
+ var array = new Array( 0 | size );
+
+ if ( size2 )
+ {
+ for ( var i = 0; i < size; i++ )
+ {
+ array[i] = [];
+
+ for ( var j = 0; j < size2; j++ )
+ {
+ var a = array[i][j] = size3 ? new Array( size3 ) : 0;
+ for ( var k = 0; k < size3; k++ )
+ {
+ a[k] = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( var i = 0; i < size; i++ )
+ {
+ array[i] = 0;
+ }
+ }
+
+ array.size = function()
+ {
+ return this.length;
+ };
+ array.get = function( i )
+ {
+ return this[ i ];
+ };
+ array.remove = function( i )
+ {
+ return this.splice( i, 1 );
+ };
+ array.add = function( item )
+ {
+ for ( var i = 0; this[ i ] != undefined; i++ ) {}
+ this[ i ] = item;
+ };
+ array.clone = function()
+ {
+ var a = new ArrayList( size );
+ for ( var i = 0; i < size; i++ )
+ {
+ a[ i ] = this[ i ];
+ }
+ return a;
+ };
+ array.isEmpty = function()
+ {
+ return !this.length;
+ };
+ array.clear = function()
+ {
+ this.length = 0;
+ };
+
+ return array;
+ }
+
+ p.colorMode = function colorMode( mode, range1, range2, range3, range4 )
+ {
+ curColorMode = mode;
+
+ if ( arguments.length >= 4 )
+ {
+ redRange = range1;
+ greenRange = range2;
+ blueRange = range3;
+ }
+
+ if ( arguments.length == 5 )
+ {
+ opacityRange = range4;
+ }
+
+ if ( arguments.length == 2 )
+ {
+ p.colorMode( mode, range1, range1, range1, range1 );
+ }
+ }
+
+ p.beginShape = function beginShape( type )
+ {
+ curShape = type;
+ curShapeCount = 0;
+ }
+
+ p.endShape = function endShape( close )
+ {
+ if ( curShapeCount != 0 )
+ {
+ curContext.lineTo( firstX, firstY );
+
+ if ( doFill )
+ curContext.fill();
+
+ if ( doStroke )
+ curContext.stroke();
+
+ curContext.closePath();
+ curShapeCount = 0;
+ pathOpen = false;
+ }
+
+ if ( pathOpen )
+ {
+ curContext.closePath();
+ }
+ }
+
+ p.vertex = function vertex( x, y, x2, y2, x3, y3 )
+ {
+ if ( curShapeCount == 0 && curShape != p.POINTS )
+ {
+ pathOpen = true;
+ curContext.beginPath();
+ curContext.moveTo( x, y );
+ }
+ else
+ {
+ if ( curShape == p.POINTS )
+ {
+ p.point( x, y );
+ }
+ else if ( arguments.length == 2 )
+ {
+ if ( curShape == p.TRIANGLE_STRIP && curShapeCount == 2 )
+ {
+ curContext.moveTo( prevX, prevY );
+ curContext.lineTo( firstX, firstY );
+ }
+
+ curContext.lineTo( x, y );
+ }
+ else if ( arguments.length == 4 )
+ {
+ if ( curShapeCount > 1 )
+ {
+ curContext.moveTo( prevX, prevY );
+ curContext.quadraticCurveTo( firstX, firstY, x, y );
+ curShapeCount = 1;
+ }
+ }
+ else if ( arguments.length == 6 )
+ {
+ curContext.bezierCurveTo( x, y, x2, y2, x3, y3 );
+ curShapeCount = -1;
+ }
+ }
+
+ prevX = firstX;
+ prevY = firstY;
+ firstX = x;
+ firstY = y;
+
+
+ curShapeCount++;
+
+ if ( curShape == p.LINES && curShapeCount == 2 ||
+ (curShape == p.TRIANGLES || curShape == p.TRIANGLE_STRIP) && curShapeCount == 3 )
+ {
+ p.endShape();
+ }
+
+ if ( curShape == p.TRIANGLE_STRIP && curShapeCount == 3 )
+ {
+ curShapeCount = 2;
+ }
+ }
+
+ p.curveTightness = function()
+ {
+
+ }
+
+ // Unimplmented - not really possible with the Canvas API
+ p.curveVertex = function( x, y, x2, y2 )
+ {
+ p.vertex( x, y, x2, y2 );
+ }
+
+ p.bezierVertex = p.vertex
+
+ p.rectMode = function rectMode( aRectMode )
+ {
+ curRectMode = aRectMode;
+ }
+
+ p.imageMode = function()
+ {
+
+ }
+
+ p.ellipseMode = function ellipseMode( aEllipseMode )
+ {
+ curEllipseMode = aEllipseMode;
+ }
+
+ p.dist = function dist( x1, y1, x2, y2 )
+ {
+ return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );
+ }
+
+ p.year = function year()
+ {
+ return (new Date).getYear() + 1900;
+ }
+
+ p.month = function month()
+ {
+ return (new Date).getMonth();
+ }
+
+ p.day = function day()
+ {
+ return (new Date).getDay();
+ }
+
+ p.hour = function hour()
+ {
+ return (new Date).getHours();
+ }
+
+ p.minute = function minute()
+ {
+ return (new Date).getMinutes();
+ }
+
+ p.second = function second()
+ {
+ return (new Date).getSeconds();
+ }
+
+ p.millis = function millis()
+ {
+ return (new Date).getTime() - start;
+ }
+
+ p.ortho = function ortho()
+ {
+
+ }
+
+ p.translate = function translate( x, y )
+ {
+ curContext.translate( x, y );
+ }
+
+ p.scale = function scale( x, y )
+ {
+ curContext.scale( x, y || x );
+ }
+
+ p.rotate = function rotate( aAngle )
+ {
+ curContext.rotate( aAngle );
+ }
+
+ p.pushMatrix = function pushMatrix()
+ {
+ curContext.save();
+ }
+
+ p.popMatrix = function popMatrix()
+ {
+ curContext.restore();
+ }
+
+ p.redraw = function redraw()
+ {
+ if ( hasBackground )
+ {
+ p.background();
+ }
+
+ inDraw = true;
+ p.pushMatrix();
+ p.draw();
+ p.popMatrix();
+ inDraw = false;
+ }
+
+ p.loop = function loop()
+ {
+ if ( loopStarted )
+ return;
+
+ var looping = setInterval(function()
+ {
+ try
+ {
+ p.redraw();
+ }
+ catch(e)
+ {
+ clearInterval( looping );
+ throw e;
+ }
+ }, 1000 / curFrameRate );
+
+ loopStarted = true;
+ }
+
+ p.frameRate = function frameRate( aRate )
+ {
+ curFrameRate = aRate;
+ }
+
+ p.background = function background( img )
+ {
+ if ( arguments.length )
+ {
+ if ( img && img.img )
+ {
+ curBackground = img;
+ }
+ else
+ {
+ curBackground = p.color.apply( this, arguments );
+ }
+ }
+
+
+ if ( curBackground.img )
+ {
+ p.image( curBackground, 0, 0 );
+ }
+ else
+ {
+ var oldFill = curContext.fillStyle;
+ curContext.fillStyle = curBackground + "";
+ curContext.fillRect( 0, 0, p.width, p.height );
+ curContext.fillStyle = oldFill;
+ }
+ }
+
+ p.sq = function sq( aNumber )
+ {
+ return aNumber * aNumber;
+ }
+
+ p.sqrt = function sqrt( aNumber )
+ {
+ return Math.sqrt( aNumber );
+ }
+
+ p.int = function int( aNumber )
+ {
+ return Math.floor( aNumber );
+ }
+
+ p.min = function min( aNumber, aNumber2 )
+ {
+ return Math.min( aNumber, aNumber2 );
+ }
+
+ p.max = function max( aNumber, aNumber2 )
+ {
+ return Math.max( aNumber, aNumber2 );
+ }
+
+ p.ceil = function ceil( aNumber )
+ {
+ return Math.ceil( aNumber );
+ }
+
+ p.floor = function floor( aNumber )
+ {
+ return Math.floor( aNumber );
+ }
+
+ p.float = function float( aNumber )
+ {
+ return typeof aNumber == "string" ?
+ p.float( aNumber.charCodeAt(0) ) :
+ parseFloat( aNumber );
+ }
+
+ p.byte = function byte( aNumber )
+ {
+ return aNumber || 0;
+ }
+
+ p.random = function random( aMin, aMax )
+ {
+ return arguments.length == 2 ?
+ aMin + (Math.random() * (aMax - aMin)) :
+ Math.random() * aMin;
+ }
+
+ // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
+ p.noise = function( x, y, z )
+ {
+ return arguments.length >= 2 ?
+ PerlinNoise_2D( x, y ) :
+ PerlinNoise_2D( x, x );
+ }
+
+ function Noise(x, y)
+ {
+ var n = x + y * 57;
+ n = (n<<13) ^ n;
+ return Math.abs(1.0 - (((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0));
+ }
+
+ function SmoothedNoise(x, y)
+ {
+ var corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
+ var sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
+ var center = Noise(x, y) / 4;
+ return corners + sides + center;
+ }
+
+ function InterpolatedNoise(x, y)
+ {
+ var integer_X = Math.floor(x);
+ var fractional_X = x - integer_X;
+
+ var integer_Y = Math.floor(y);
+ var fractional_Y = y - integer_Y;
+
+ var v1 = SmoothedNoise(integer_X, integer_Y);
+ var v2 = SmoothedNoise(integer_X + 1, integer_Y);
+ var v3 = SmoothedNoise(integer_X, integer_Y + 1);
+ var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1);
+
+ var i1 = Interpolate(v1 , v2 , fractional_X);
+ var i2 = Interpolate(v3 , v4 , fractional_X);
+
+ return Interpolate(i1 , i2 , fractional_Y);
+ }
+
+ function PerlinNoise_2D(x, y)
+ {
+ var total = 0;
+ var p = 0.25;
+ var n = 3;
+
+ for ( var i = 0; i <= n; i++ )
+ {
+ var frequency = Math.pow(2, i);
+ var amplitude = Math.pow(p, i);
+
+ total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
+ }
+
+ return total;
+ }
+
+ function Interpolate(a, b, x)
+ {
+ var ft = x * p.PI;
+ var f = (1 - p.cos(ft)) * .5;
+ return a*(1-f) + b*f;
+ }
+
+ p.red = function( aColor )
+ {
+ return parseInt(aColor.slice(5));
+ }
+
+ p.green = function( aColor )
+ {
+ return parseInt(aColor.split(",")[1]);
+ }
+
+ p.blue = function( aColor )
+ {
+ return parseInt(aColor.split(",")[2]);
+ }
+
+ p.alpha = function( aColor )
+ {
+ return parseInt(aColor.split(",")[3]);
+ }
+
+ p.abs = function abs( aNumber )
+ {
+ return Math.abs( aNumber );
+ }
+
+ p.cos = function cos( aNumber )
+ {
+ return Math.cos( aNumber );
+ }
+
+ p.sin = function sin( aNumber )
+ {
+ return Math.sin( aNumber );
+ }
+
+ p.pow = function pow( aNumber, aExponent )
+ {
+ return Math.pow( aNumber, aExponent );
+ }
+
+ p.constrain = function constrain( aNumber, aMin, aMax )
+ {
+ return Math.min( Math.max( aNumber, aMin ), aMax );
+ }
+
+ p.sqrt = function sqrt( aNumber )
+ {
+ return Math.sqrt( aNumber );
+ }
+
+ p.atan2 = function atan2( aNumber, aNumber2 )
+ {
+ return Math.atan2( aNumber, aNumber2 );
+ }
+
+ p.radians = function radians( aAngle )
+ {
+ return ( aAngle / 180 ) * p.PI;
+ }
+
+ p.size = function size( aWidth, aHeight )
+ {
+ var fillStyle = curContext.fillStyle;
+ var strokeStyle = curContext.strokeStyle;
+
+ curElement.width = p.width = aWidth;
+ curElement.height = p.height = aHeight;
+
+ curContext.fillStyle = fillStyle;
+ curContext.strokeStyle = strokeStyle;
+ }
+
+ p.noStroke = function noStroke()
+ {
+ doStroke = false;
+ }
+
+ p.noFill = function noFill()
+ {
+ doFill = false;
+ }
+
+ p.smooth = function smooth()
+ {
+
+ }
+
+ p.noLoop = function noLoop()
+ {
+ doLoop = false;
+ }
+
+ p.fill = function fill()
+ {
+ doFill = true;
+ curContext.fillStyle = p.color.apply( this, arguments );
+ }
+
+ p.stroke = function stroke()
+ {
+ doStroke = true;
+ curContext.strokeStyle = p.color.apply( this, arguments );
+ }
+
+ p.strokeWeight = function strokeWeight( w )
+ {
+ curContext.lineWidth = w;
+ }
+
+ p.point = function point( x, y )
+ {
+ var oldFill = curContext.fillStyle;
+ curContext.fillStyle = curContext.strokeStyle;
+ curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
+ curContext.fillStyle = oldFill;
+ }
+
+ p.get = function get( x, y )
+ {
+ if ( arguments.length == 0 )
+ {
+ var c = p.createGraphics( p.width, p.height );
+ c.image( curContext, 0, 0 );
+ return c;
+ }
+
+ if ( !getLoaded )
+ {
+ getLoaded = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) );
+ }
+
+ return getLoaded.get( x, y );
+ }
+
+ p.set = function set( x, y, color )
+ {
+ var oldFill = curContext.fillStyle;
+ curContext.fillStyle = color;
+ curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
+ curContext.fillStyle = oldFill;
+ }
+
+ p.arc = function arc( x, y, width, height, start, stop )
+ {
+ if ( width <= 0 )
+ return;
+
+ if ( curEllipseMode == p.CORNER )
+ {
+ x += width / 2;
+ y += height / 2;
+ }
+
+ curContext.beginPath();
+
+ curContext.moveTo( x, y );
+ curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false );
+
+ if ( doFill )
+ curContext.fill();
+
+ if ( doStroke )
+ curContext.stroke();
+
+ curContext.closePath();
+ }
+
+ p.line = function line( x1, y1, x2, y2 )
+ {
+ curContext.lineCap = "round";
+ curContext.beginPath();
+
+ curContext.moveTo( x1 || 0, y1 || 0 );
+ curContext.lineTo( x2 || 0, y2 || 0 );
+
+ curContext.stroke();
+
+ curContext.closePath();
+ }
+
+ p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 )
+ {
+ curContext.lineCap = "butt";
+ curContext.beginPath();
+
+ curContext.moveTo( x1, y1 );
+ curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 );
+
+ curContext.stroke();
+
+ curContext.closePath();
+ }
+
+ p.triangle = function triangle( x1, y1, x2, y2, x3, y3 )
+ {
+ p.beginShape();
+ p.vertex( x1, y1 );
+ p.vertex( x2, y2 );
+ p.vertex( x3, y3 );
+ p.endShape();
+ }
+
+ p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 )
+ {
+ p.beginShape();
+ p.vertex( x1, y1 );
+ p.vertex( x2, y2 );
+ p.vertex( x3, y3 );
+ p.vertex( x4, y4 );
+ p.endShape();
+ }
+
+ p.rect = function rect( x, y, width, height )
+ {
+ if ( width == 0 && height == 0 )
+ return;
+
+ curContext.beginPath();
+
+ var offsetStart = 0;
+ var offsetEnd = 0;
+
+ if ( curRectMode == p.CORNERS )
+ {
+ width -= x;
+ height -= y;
+ }
+
+ if ( curRectMode == p.RADIUS )
+ {
+ width *= 2;
+ height *= 2;
+ }
+
+ if ( curRectMode == p.CENTER || curRectMode == p.RADIUS )
+ {
+ x -= width / 2;
+ y -= height / 2;
+ }
+
+ curContext.rect(
+ Math.round( x ) - offsetStart,
+ Math.round( y ) - offsetStart,
+ Math.round( width ) + offsetEnd,
+ Math.round( height ) + offsetEnd
+ );
+
+ if ( doFill )
+ curContext.fill();
+
+ if ( doStroke )
+ curContext.stroke();
+
+ curContext.closePath();
+ }
+
+ p.ellipse = function ellipse( x, y, width, height )
+ {
+ x = x || 0;
+ y = y || 0;
+
+ if ( width <= 0 && height <= 0 )
+ return;
+
+ curContext.beginPath();
+
+ if ( curEllipseMode == p.RADIUS )
+ {
+ width *= 2;
+ height *= 2;
+ }
+
+ var offsetStart = 0;
+
+ // Shortcut for drawing a circle
+ if ( width == height )
+ curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, Math.PI * 2, false );
+
+ if ( doFill )
+ curContext.fill();
+
+ if ( doStroke )
+ curContext.stroke();
+
+ curContext.closePath();
+ }
+
+ p.link = function( href, target )
+ {
+ window.location = href;
+ }
+
+ p.loadPixels = function()
+ {
+ p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels;
+ }
+
+ p.updatePixels = function()
+ {
+ var colors = /(\d+),(\d+),(\d+),(\d+)/;
+ var pixels = {};
+ var data = pixels.data = [];
+ pixels.width = p.width;
+ pixels.height = p.height;
+
+ var pos = 0;
+
+ for ( var i = 0, l = p.pixels.length; i < l; i++ ) {
+ var c = (p.pixels[i] || "rgba(0,0,0,1)").match(colors);
+ data[pos] = parseInt(c[1]);
+ data[pos+1] = parseInt(c[2]);
+ data[pos+2] = parseInt(c[3]);
+ data[pos+3] = parseFloat(c[4]) * 100;
+ pos += 4;
+ }
+
+ curContext.putImageData(pixels, 0, 0);
+ }
+
+ p.extendClass = function extendClass( obj, args, fn )
+ {
+ if ( arguments.length == 3 )
+ {
+ fn.apply( obj, args );
+ }
+ else
+ {
+ args.call( obj );
+ }
+ }
+
+ p.addMethod = function addMethod( object, name, fn )
+ {
+ if ( object[ name ] )
+ {
+ var args = fn.length;
+
+ var oldfn = object[ name ];
+ object[ name ] = function()
+ {
+ if ( arguments.length == args )
+ return fn.apply( this, arguments );
+ else
+ return oldfn.apply( this, arguments );
+ };
+ }
+ else
+ {
+ object[ name ] = fn;
+ }
+ }
+
+ p.init = function init(code){
+ p.stroke( 0 );
+ p.fill( 255 );
+
+ // Canvas has trouble rendering single pixel stuff on whole-pixel
+ // counts, so we slightly offset it (this is super lame).
+ curContext.translate( 0.5, 0.5 );
+
+ if ( code )
+ {
+ (function(Processing){with (p){
+ eval(parse(code, p));
+ }})(p);
+ }
+
+ if ( p.setup )
+ {
+ inSetup = true;
+ p.setup();
+ }
+
+ inSetup = false;
+
+ if ( p.draw )
+ {
+ if ( !doLoop )
+ {
+ p.redraw();
+ }
+ else
+ {
+ p.loop();
+ }
+ }
+
+ attach( curElement, "mousemove", function(e)
+ {
+ p.pmouseX = p.mouseX;
+ p.pmouseY = p.mouseY;
+ p.mouseX = e.clientX - curElement.offsetLeft;
+ p.mouseY = e.clientY - curElement.offsetTop;
+
+ if ( p.mouseMoved )
+ {
+ p.mouseMoved();
+ }
+
+ if ( mousePressed && p.mouseDragged )
+ {
+ p.mouseDragged();
+ }
+ });
+
+ attach( curElement, "mousedown", function(e)
+ {
+ mousePressed = true;
+
+ if ( typeof p.mousePressed == "function" )
+ {
+ p.mousePressed();
+ }
+ else
+ {
+ p.mousePressed = true;
+ }
+ });
+
+ attach( curElement, "mouseup", function(e)
+ {
+ mousePressed = false;
+
+ if ( typeof p.mousePressed != "function" )
+ {
+ p.mousePressed = false;
+ }
+
+ if ( p.mouseReleased )
+ {
+ p.mouseReleased();
+ }
+ });
+
+ attach( document, "keydown", function(e)
+ {
+ keyPressed = true;
+
+ p.key = e.keyCode + 32;
+
+ if ( e.shiftKey )
+ {
+ p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt(0);
+ }
+
+ if ( typeof p.keyPressed == "function" )
+ {
+ p.keyPressed();
+ }
+ else
+ {
+ p.keyPressed = true;
+ }
+ });
+
+ attach( document, "keyup", function(e)
+ {
+ keyPressed = false;
+
+ if ( typeof p.keyPressed != "function" )
+ {
+ p.keyPressed = false;
+ }
+
+ if ( p.keyReleased )
+ {
+ p.keyReleased();
+ }
+ });
+
+ function attach(elem, type, fn)
+ {
+ if ( elem.addEventListener )
+ elem.addEventListener( type, fn, false );
+ else
+ elem.attachEvent( "on" + type, fn );
+ }
+ };
+
+ return p;
+}
+
+})();
diff --git a/infrastructure/ace/www/profiler.js b/infrastructure/ace/www/profiler.js
new file mode 100644
index 0000000..24b68a2
--- /dev/null
+++ b/infrastructure/ace/www/profiler.js
@@ -0,0 +1,117 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// author: David Greenspan
+// a basic profiler
+// e.g. var p = PROFILER("somename", true);
+// p.mark("abc"); abc();
+// p.mark("xyz"); var x = xyz();
+// p.literal(x, "someNumber");
+// p.end();
+
+// Note that IE/Win only has 16 ms time resolution for each run.
+
+var _profilersByName = {};
+function PROFILER(name, enabled) {
+ if (!_profilersByName['$'+name]) {
+ _profilersByName['$'+name] = _makeProfiler(name, enabled);
+ }
+ var p = _profilersByName['$'+name];
+ p.start();
+ return p;
+}
+
+function resetProfiler(name) {
+ delete _profilersByName['$'+name];
+}
+
+function _makeProfiler(name, enabled) {
+ enabled = (enabled !== false);
+
+ var _profileTime;
+ var _profileResults;
+ var _profileTotal;
+ var _profileHistory = [];
+ var running = false;
+
+ function profileStart(name) {
+ _profileResults = [];
+ _profileTotal = 0;
+ if (name) _profileResults.push(name);
+ running = true;
+ _profileTime = (new Date()).getTime();
+ }
+
+ function profileMark(name) {
+ var stopTime = (new Date()).getTime();
+ var dt = stopTime - _profileTime;
+ _profileResults.push(dt);
+ _profileTotal += dt;
+ if (name) _profileResults.push(name);
+ _profileTime = (new Date()).getTime();
+ }
+
+ function profileLiteral(value, name) {
+ _profileResults.push(value);
+ if (name) _profileResults.push("%="+name);
+ }
+
+ function profileEnd(name) {
+ if (running == false) return;
+ var stopTime = (new Date()).getTime();
+ var dt = stopTime - _profileTime;
+ _profileResults.push(dt);
+ _profileTotal += dt;
+ if (name) _profileResults.push(name);
+ _profileResults.unshift(_profileTotal,"=");
+ _profileHistory.push(_profileResults);
+ if (dumpProfileDataTimeout)
+ top.clearTimeout(dumpProfileDataTimeout);
+ dumpProfileDataTimeout = top.setTimeout(dumpProfileData, 800);
+ running = false;
+ }
+
+ var dumpProfileDataTimeout = null;
+
+ function dumpProfileData() {
+ var data = _profileHistory[0].slice();
+ forEach(_profileHistory.slice(1), function (h) {
+ forEach(h, function (x, i) {
+ if ((typeof x) == "number") data[i] += x;
+ });
+ });
+ data = map(data, function (x) {
+ if ((typeof x) == "number") return String(x/_profileHistory.length).substring(0,4);
+ return x;
+ });
+ data.push("("+_profileHistory.length+")");
+ top.pad.dmesg(data.join(" ").replace(/ %/g,''));
+ dumpProfileDataTimeout = null;
+ }
+
+ function noop() {}
+ function cancel() {
+ running = false;
+ }
+
+ if (enabled) {
+ return {start:profileStart, mark:profileMark, literal:profileLiteral, end:profileEnd,
+ cancel:cancel};
+ }
+ else {
+ return {start:noop, mark:noop, literal:noop, end:noop, cancel:noop};
+ }
+}
diff --git a/infrastructure/ace/www/skiplist.js b/infrastructure/ace/www/skiplist.js
new file mode 100644
index 0000000..e6c2e04
--- /dev/null
+++ b/infrastructure/ace/www/skiplist.js
@@ -0,0 +1,347 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+
+
+function newSkipList() {
+ var PROFILER = window.PROFILER;
+ if (!PROFILER) {
+ PROFILER = function() { return {start:noop, mark:noop, literal:noop, end:noop, cancel:noop}; };
+ }
+ function noop() {}
+
+ // if there are N elements in the skiplist, "start" is element -1 and "end" is element N
+ var start = {key:null, levels: 1, upPtrs:[null], downPtrs:[null], downSkips:[1], downSkipWidths:[0]};
+ var end = {key:null, levels: 1, upPtrs:[null], downPtrs:[null], downSkips:[null], downSkipWidths:[null]};
+ var numNodes = 0;
+ var totalWidth = 0;
+ var keyToNodeMap = {};
+ start.downPtrs[0] = end;
+ end.upPtrs[0] = start;
+ // a "point" object at location x allows modifications immediately after the first
+ // x elements of the skiplist, such as multiple inserts or deletes.
+ // After an insert or delete using point P, the point is still valid and points
+ // to the same index in the skiplist. Other operations with other points invalidate
+ // this point.
+ function _getPoint(targetLoc) {
+ var numLevels = start.levels;
+ var lvl = numLevels-1;
+ var i = -1, ws = 0;
+ var nodes = new Array(numLevels);
+ var idxs = new Array(numLevels);
+ var widthSkips = new Array(numLevels);
+ nodes[lvl] = start;
+ idxs[lvl] = -1;
+ widthSkips[lvl] = 0;
+ while (lvl >= 0) {
+ var n = nodes[lvl];
+ while (n.downPtrs[lvl] &&
+ (i + n.downSkips[lvl] < targetLoc)) {
+ i += n.downSkips[lvl];
+ ws += n.downSkipWidths[lvl];
+ n = n.downPtrs[lvl];
+ }
+ nodes[lvl] = n;
+ idxs[lvl] = i;
+ widthSkips[lvl] = ws;
+ lvl--;
+ if (lvl >= 0) {
+ nodes[lvl] = n;
+ }
+ }
+ return {nodes:nodes, idxs:idxs, loc:targetLoc, widthSkips:widthSkips, toString: function() {
+ return "getPoint("+targetLoc+")"; } };
+ }
+ function _getNodeAtOffset(targetOffset) {
+ var i = 0;
+ var n = start;
+ var lvl = start.levels-1;
+ while (lvl >= 0 && n.downPtrs[lvl]) {
+ while (n.downPtrs[lvl] && (i + n.downSkipWidths[lvl] <= targetOffset)) {
+ i += n.downSkipWidths[lvl];
+ n = n.downPtrs[lvl];
+ }
+ lvl--;
+ }
+ if (n === start) return (start.downPtrs[0] || null);
+ else if (n === end) return (targetOffset == totalWidth ? (end.upPtrs[0] || null) : null);
+ return n;
+ }
+ function _entryWidth(e) { return (e && e.width) || 0; }
+ function _insertKeyAtPoint(point, newKey, entry) {
+ var p = PROFILER("insertKey", false);
+ var newNode = {key:newKey, levels: 0, upPtrs:[], downPtrs:[], downSkips:[], downSkipWidths:[]};
+ p.mark("donealloc");
+ var pNodes = point.nodes;
+ var pIdxs = point.idxs;
+ var pLoc = point.loc;
+ var widthLoc = point.widthSkips[0] + point.nodes[0].downSkipWidths[0];
+ var newWidth = _entryWidth(entry);
+ p.mark("loop1");
+ while (newNode.levels == 0 || Math.random() < 0.01) {
+ var lvl = newNode.levels;
+ newNode.levels++;
+ if (lvl == pNodes.length) {
+ // assume we have just passed the end of point.nodes, and reached one level greater
+ // than the skiplist currently supports
+ pNodes[lvl] = start;
+ pIdxs[lvl] = -1;
+ start.levels++;
+ end.levels++;
+ start.downPtrs[lvl] = end;
+ end.upPtrs[lvl] = start;
+ start.downSkips[lvl] = numNodes+1;
+ start.downSkipWidths[lvl] = totalWidth;
+ point.widthSkips[lvl] = 0;
+ }
+ var me = newNode;
+ var up = pNodes[lvl];
+ var down = up.downPtrs[lvl];
+ var skip1 = pLoc - pIdxs[lvl];
+ var skip2 = up.downSkips[lvl] + 1 - skip1;
+ up.downSkips[lvl] = skip1;
+ up.downPtrs[lvl] = me;
+ me.downSkips[lvl] = skip2;
+ me.upPtrs[lvl] = up;
+ me.downPtrs[lvl] = down;
+ down.upPtrs[lvl] = me;
+ var widthSkip1 = widthLoc - point.widthSkips[lvl];
+ var widthSkip2 = up.downSkipWidths[lvl] + newWidth - widthSkip1;
+ up.downSkipWidths[lvl] = widthSkip1;
+ me.downSkipWidths[lvl] = widthSkip2;
+ }
+ p.mark("loop2");
+ p.literal(pNodes.length, "PNL");
+ for(var lvl=newNode.levels; lvl<pNodes.length; lvl++) {
+ var up = pNodes[lvl];
+ up.downSkips[lvl]++;
+ up.downSkipWidths[lvl] += newWidth;
+ }
+ p.mark("map");
+ keyToNodeMap['$KEY$'+newKey] = newNode;
+ numNodes++;
+ totalWidth += newWidth;
+ p.end();
+ }
+ function _getNodeAtPoint(point) {
+ return point.nodes[0].downPtrs[0];
+ }
+ function _incrementPoint(point) {
+ point.loc++;
+ for(var i=0;i<point.nodes.length;i++) {
+ if (point.idxs[i] + point.nodes[i].downSkips[i] < point.loc) {
+ point.idxs[i] += point.nodes[i].downSkips[i];
+ point.widthSkips[i] += point.nodes[i].downSkipWidths[i];
+ point.nodes[i] = point.nodes[i].downPtrs[i];
+ }
+ }
+ }
+ function _deleteKeyAtPoint(point) {
+ var elem = point.nodes[0].downPtrs[0];
+ var elemWidth = _entryWidth(elem.entry);
+ for(var i=0;i<point.nodes.length;i++) {
+ if (i < elem.levels) {
+ var up = elem.upPtrs[i];
+ var down = elem.downPtrs[i];
+ var totalSkip = up.downSkips[i] + elem.downSkips[i] - 1;
+ up.downPtrs[i] = down;
+ down.upPtrs[i] = up;
+ up.downSkips[i] = totalSkip;
+ var totalWidthSkip = up.downSkipWidths[i] + elem.downSkipWidths[i] - elemWidth;
+ up.downSkipWidths[i] = totalWidthSkip;
+ }
+ else {
+ var up = point.nodes[i];
+ var down = up.downPtrs[i];
+ up.downSkips[i]--;
+ up.downSkipWidths[i] -= elemWidth;
+ }
+ }
+ delete keyToNodeMap['$KEY$'+elem.key];
+ numNodes--;
+ totalWidth -= elemWidth;
+ }
+ function _propagateWidthChange(node) {
+ var oldWidth = node.downSkipWidths[0];
+ var newWidth = _entryWidth(node.entry);
+ var widthChange = newWidth - oldWidth;
+ var n = node;
+ var lvl = 0;
+ while (lvl < n.levels) {
+ n.downSkipWidths[lvl] += widthChange;
+ lvl++;
+ while (lvl >= n.levels && n.upPtrs[lvl-1]) {
+ n = n.upPtrs[lvl-1];
+ }
+ }
+ totalWidth += widthChange;
+ }
+ function _getNodeIndex(node, byWidth) {
+ var dist = (byWidth ? 0 : -1);
+ var n = node;
+ while (n !== start) {
+ var lvl = n.levels-1;
+ n = n.upPtrs[lvl];
+ if (byWidth) dist += n.downSkipWidths[lvl];
+ else dist += n.downSkips[lvl];
+ }
+ return dist;
+ }
+ /*function _debugToString() {
+ var array = [start];
+ while (array[array.length-1] !== end) {
+ array[array.length] = array[array.length-1].downPtrs[0];
+ }
+ function getIndex(node) {
+ if (!node) return null;
+ for(var i=0;i<array.length;i++) {
+ if (array[i] === node)
+ return i-1;
+ }
+ return false;
+ }
+ var processedArray = map(array, function(node) {
+ var x = {key:node.key, levels: node.levels, downSkips: node.downSkips,
+ upPtrs: map(node.upPtrs, getIndex), downPtrs: map(node.downPtrs, getIndex),
+ downSkipWidths: node.downSkipWidths};
+ return x;
+ });
+ return map(processedArray, function (x) { return x.toSource(); }).join("\n");
+ }*/
+
+ function _getNodeByKey(key) {
+ return keyToNodeMap['$KEY$'+key];
+ }
+
+ // Returns index of first entry such that entryFunc(entry) is truthy,
+ // or length() if no such entry. Assumes all falsy entries come before
+ // all truthy entries.
+ function _search(entryFunc) {
+ var low = start;
+ var lvl = start.levels-1;
+ var lowIndex = -1;
+ function f(node) {
+ if (node === start) return false;
+ else if (node === end) return true;
+ else return entryFunc(node.entry);
+ }
+ while (lvl >= 0) {
+ var nextLow = low.downPtrs[lvl];
+ while (!f(nextLow)) {
+ lowIndex += low.downSkips[lvl];
+ low = nextLow;
+ nextLow = low.downPtrs[lvl];
+ }
+ lvl--;
+ }
+ return lowIndex+1;
+ }
+
+/*
+The skip-list contains "entries", JavaScript objects that each must have a unique "key" property
+that is a string.
+*/
+ var self = {
+ length: function() { return numNodes; },
+ atIndex: function(i) {
+ if (i < 0) console.warn("atIndex("+i+")");
+ if (i >= numNodes) console.warn("atIndex("+i+">="+numNodes+")");
+ return _getNodeAtPoint(_getPoint(i)).entry;
+ },
+ // differs from Array.splice() in that new elements are in an array, not varargs
+ splice: function(start, deleteCount, newEntryArray) {
+ if (start < 0) console.warn("splice("+start+", ...)");
+ if (start + deleteCount > numNodes) {
+ console.warn("splice("+start+", "+deleteCount+", ...), N="+numNodes);
+ console.warn("%s %s %s", typeof start, typeof deleteCount, typeof numNodes);
+ console.trace();
+ }
+
+ if (! newEntryArray) newEntryArray = [];
+ var pt = _getPoint(start);
+ for(var i=0;i<deleteCount;i++) {
+ _deleteKeyAtPoint(pt);
+ }
+ for(var i=(newEntryArray.length-1);i>=0;i--) {
+ var entry = newEntryArray[i];
+ _insertKeyAtPoint(pt, entry.key, entry);
+ var node = _getNodeByKey(entry.key);
+ node.entry = entry;
+ }
+ },
+ next: function (entry) {
+ return _getNodeByKey(entry.key).downPtrs[0].entry || null;
+ },
+ prev: function (entry) {
+ return _getNodeByKey(entry.key).upPtrs[0].entry || null;
+ },
+ push: function(entry) {
+ self.splice(numNodes, 0, [entry]);
+ },
+ slice: function(start, end) {
+ // act like Array.slice()
+ if (start === undefined) start = 0;
+ else if (start < 0) start += numNodes;
+ if (end === undefined) end = numNodes;
+ else if (end < 0) end += numNodes;
+
+ if (start < 0) start = 0;
+ if (start > numNodes) start = numNodes;
+ if (end < 0) end = 0;
+ if (end > numNodes) end = numNodes;
+
+ dmesg(String([start,end,numNodes]));
+ if (end <= start) return [];
+ var n = self.atIndex(start);
+ var array = [n];
+ for(var i=1;i<(end-start);i++) {
+ n = self.next(n);
+ array.push(n);
+ }
+ return array;
+ },
+ atKey: function(key) { return _getNodeByKey(key).entry; },
+ indexOfKey: function(key) { return _getNodeIndex(_getNodeByKey(key)); },
+ indexOfEntry: function (entry) { return self.indexOfKey(entry.key); },
+ containsKey: function(key) { return !!(_getNodeByKey(key)); },
+ // gets the last entry starting at or before the offset
+ atOffset: function(offset) { return _getNodeAtOffset(offset).entry; },
+ keyAtOffset: function(offset) { return self.atOffset(offset).key; },
+ offsetOfKey: function(key) { return _getNodeIndex(_getNodeByKey(key), true); },
+ offsetOfEntry: function(entry) { return self.offsetOfKey(entry.key); },
+ setEntryWidth: function(entry, width) { entry.width = width; _propagateWidthChange(_getNodeByKey(entry.key)); },
+ totalWidth: function() { return totalWidth; },
+ offsetOfIndex: function(i) {
+ if (i < 0) return 0;
+ if (i >= numNodes) return totalWidth;
+ return self.offsetOfEntry(self.atIndex(i));
+ },
+ indexOfOffset: function(offset) {
+ if (offset <= 0) return 0;
+ if (offset >= totalWidth) return numNodes;
+ return self.indexOfEntry(self.atOffset(offset));
+ },
+ search: function(entryFunc) {
+ return _search(entryFunc);
+ },
+ //debugToString: _debugToString,
+ debugGetPoint: _getPoint,
+ debugDepth: function() { return start.levels; }
+ }
+ return self;
+}
diff --git a/infrastructure/ace/www/spanlist.js b/infrastructure/ace/www/spanlist.js
new file mode 100644
index 0000000..756a411
--- /dev/null
+++ b/infrastructure/ace/www/spanlist.js
@@ -0,0 +1,279 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+function newSpanList() {
+ function encodeInt(num) {
+ num = num & 0x1fffffff;
+ // neither 16-bit char can be 0x0001 or mistakable for the other
+ return String.fromCharCode(((num >> 15) & 0x3fff) | 0x4000) +
+ String.fromCharCode((num & 0x7fff) | 0x8000);
+ }
+ function decodeInt(str) {
+ return ((str.charCodeAt(0) & 0x3fff) << 15) | (str.charCodeAt(1) & 0x7fff);
+ }
+ function indexOfInt(str, n) {
+ var result = str.indexOf(encodeInt(n));
+ if (result < 0) return result;
+ return result/2;
+ }
+ function intAt(str, i) {
+ var idx = i*2;
+ return decodeInt(str.substr(idx, 2));
+ }
+ function numInts(str) { return str.length/2; }
+ function subrange(str, start, end) {
+ return str.substring(start*2, end*2);
+ }
+ var nil = "\1\1";
+ var repeatNilCache = [''];
+ function repeatNil(times) {
+ while (times >= repeatNilCache.length) {
+ repeatNilCache.push(repeatNilCache[repeatNilCache.length-1] + nil);
+ }
+ return repeatNilCache[times];
+ }
+ function indexOfNonnil(str, start) {
+ startIndex = (start || 0)*2;
+ var nonnilChar = /[^\1]/g;
+ nonnilChar.lastIndex = startIndex;
+ var result = nonnilChar.exec(str);
+ if (! result) {
+ return str.length/2;
+ }
+ return (nonnilChar.lastIndex - 1)/2;
+ }
+ function intSplice(str, start, delCount, newStr) {
+ return str.substring(0, start*2) + newStr + str.substring((start+delCount)*2);
+ }
+
+ function entryWidth(entry) {
+ if ((typeof entry) == "number") return entry;
+ return (entry && entry.width) || 1;
+ }
+
+ // "func" is a function over 0..(numItems-1) that is monotonically
+ // "increasing" with index (false, then true). Finds the boundary
+ // between false and true, a number between 0 and numItems inclusive.
+ function binarySearch(numItems, func) {
+ if (numItems < 1) return 0;
+ if (func(0)) return 0;
+ if (! func(numItems-1)) return numItems;
+ var low = 0; // func(low) is always false
+ var high = numItems-1; // func(high) is always true
+ while ((high - low) > 1) {
+ var x = Math.floor((low+high)/2); // x != low, x != high
+ if (func(x)) high = x;
+ else low = x;
+ }
+ return high;
+ }
+
+ var NEXT_ID = 1;
+ var entryList = ""; // e.g. 2, 4, 3, 6
+ var charList = ""; // e.g. nil, nil, nil, 2, nil, 4, nil, nil, nil, nil, 3, 6
+ var keyToId = {};
+ var idToKey = {};
+ var idToEntry = {};
+ var idToNextId = {};
+ var idToPrevId = {};
+ var length = 0;
+ var totalWidth = 0;
+
+ function idAtIndex(i) { return intAt(entryList, i); }
+ function indexOfId(id) { return indexOfInt(entryList, id); }
+ function offsetOfId(id) {
+ if (! id) return totalWidth;
+ var entry = idToEntry[id];
+ var wid = entryWidth(entry);
+ var lastCharLoc = indexOfInt(charList, id);
+ return lastCharLoc + 1 - wid;
+ }
+ function idAtOffset(n) {
+ return intAt(charList, indexOfNonnil(charList, n));
+ }
+
+ var self = {
+ length: function() { return length; },
+ totalWidth: function() { return totalWidth; },
+ next: function (entryOrKey) {
+ if ((typeof entryOrKey) == "object") {
+ var entry = entryOrKey;
+ var id = idToNextId[keyToId[entry.key]];
+ if (id) return idToEntry[id];
+ return null;
+ }
+ else {
+ var k = entryOrKey;
+ var id = idToNextId[keyToId[k]];
+ if (id) return idToKey[id];
+ return null;
+ }
+ },
+ prev: function (entryOrKey) {
+ if ((typeof entryOrKey) == "object") {
+ var entry = entryOrKey;
+ var id = idToPrevId[keyToId[entry.key]];
+ if (id) return idToEntry[id];
+ return null;
+ }
+ else {
+ var k = entryOrKey;
+ var id = idToPrevId[keyToId[k]];
+ if (id) return idToKey[id];
+ return null;
+ }
+ },
+ atKey: function (k) { return idToEntry[keyToId[k]]; },
+ atIndex: function (i) { return idToEntry[idAtIndex(i)]; },
+ keyAtIndex: function(i) { return idToKey[idAtIndex(i)]; },
+ keyAtOffset: function(n) { return idToKey[idAtOffset(n)]; },
+ containsKey: function (k) { return !! keyToId[k]; },
+ indexOfKey: function (k) { return indexOfId(keyToId[k]); },
+ indexOfEntry: function (entry) { return self.indexOfKey(entry.key); },
+ setKeyWidth: function (k, width) {
+ var id = keyToId[k];
+ var charStart = offsetOfId(id);
+ var oldWidth = entryWidth(idToEntry[id]);
+ var toDelete = 0;
+ var toInsert = 0;
+ if (width < oldWidth) toDelete = oldWidth - width;
+ else if (width > oldWidth) toInsert = width - oldWidth;
+ charList = intSplice(charList, charStart, toDelete, repeatNil(toInsert));
+ totalWidth += (width - oldWidth);
+ },
+ setEntryWidth: function (entry, width) {
+ return self.setKeyWidth(entry.key, width);
+ },
+ getEntryWidth: function (entry) {
+ return entryWidth(entry);
+ },
+ getKeyWidth: function (k) {
+ return entryWidth(idToEntry[keyToId[k]]);
+ },
+ offsetOfKey: function(k) { return offsetOfId(keyToId[k]); },
+ offsetOfEntry: function(entry) { return self.offsetOfKey(entry.key); },
+ offsetOfIndex: function (i) {
+ if (i < 0) return 0;
+ else if (i >= length) {
+ return totalWidth;
+ }
+ else {
+ return offsetOfId(idAtIndex(i));
+ }
+ },
+ atOffset: function (n) {
+ return idToEntry[idAtOffset(n)];
+ },
+ indexOfOffset: function (n) {
+ if (n < 0) return 0;
+ else if (n >= totalWidth) return length;
+ return indexOfId(idAtOffset(n));
+ },
+ search: function(entryFunc) {
+ return binarySearch(length, function (i) {
+ return entryFunc(idToEntry[idAtIndex(i)]);
+ });
+ },
+ push: function(entry, optKey) {
+ self.splice(length, 0, [entry], (optKey && [optKey]));
+ },
+ // entries can be objects with a 'key' property, possibly a 'width' property,
+ // and any other properties; OR they can be just a width number, for an
+ // ultra-light-weight representation. In the latter case the key array is
+ // used to get the keys. Some functions become useless with this usage, i.e.
+ // the ones that use an entry for identity.
+ splice: function (start, deleteCount, newEntryArray, optKeyArray) {
+ var charStart = self.offsetOfIndex(start);
+ var charsToDelete = 0;
+ var idBefore = ((start == 0) ? null : intAt(entryList, start-1));
+ // idAfter is mutated into id of node following deleted nodes
+ var idAfter = ((start == length) ? null : (idBefore ? idToNextId[idBefore] :
+ intAt(entryList, start)));
+ if (deleteCount > 0) {
+ var deleteId = idAfter;
+ for(var i=0;i<deleteCount;i++) {
+ var nextId = idToNextId[deleteId];
+ var entry = idToEntry[deleteId];
+ var wid = entryWidth(entry);
+ delete keyToId[idToKey[deleteId]];
+ delete idToKey[deleteId];
+ delete idToEntry[deleteId];
+ delete idToNextId[deleteId];
+ delete idToPrevId[deleteId];
+ length--;
+ totalWidth -= wid;
+ charsToDelete += wid;
+ deleteId = nextId;
+ }
+ idAfter = (deleteId || null);
+ }
+ var newChars = [];
+ var newIds = [];
+ var prevId = idBefore;
+ if (newEntryArray && newEntryArray.length > 0) {
+ for(var i=0,n=newEntryArray.length; i<n; i++) {
+ var entry = newEntryArray[i];
+ var newId = (NEXT_ID++);
+ var encId = encodeInt(newId);
+ newIds.push(encId);
+ var wid = entryWidth(entry);
+ newChars.push(repeatNil(wid-1), encId);
+ var key = (optKeyArray ? optKeyArray[i] : entry.key);
+ keyToId[key] = newId;
+ idToKey[newId] = key;
+ idToEntry[newId] = entry;
+ if (prevId) {
+ idToNextId[prevId] = newId;
+ idToPrevId[newId] = prevId;
+ }
+ prevId = newId;
+ length++;
+ totalWidth += wid;
+ }
+ if (prevId && idAfter) {
+ idToNextId[prevId] = idAfter;
+ idToPrevId[idAfter] = prevId;
+ }
+ }
+ else {
+ if (idBefore && idAfter) {
+ idToNextId[idBefore] = idAfter;
+ idToPrevId[idAfter] = idBefore;
+ }
+ else if (idBefore) delete idToNextId[idBefore];
+ else if (idAfter) delete idToPrevId[idAfter];
+ }
+ entryList = intSplice(entryList, start, deleteCount, newIds.join(''));
+ charList = intSplice(charList, charStart, charsToDelete, newChars.join(''));
+
+ if (length > 0) {
+ // checkrep
+ if (idToPrevId[idAtIndex(0)]) console.error("a");
+ if (idToNextId[idAtIndex(length-1)]) console.error("b");
+ for(var i=0;i<length-1;i++) {
+ if (idToNextId[idAtIndex(i)] != idAtIndex(i+1)) console.error("c"+i);
+ }
+ for(var i=1;i<length;i++) {
+ if (idToPrevId[idAtIndex(i)] != idAtIndex(i-1)) console.error("d"+i);
+ }
+ }
+ }
+ };
+
+ return self;
+}
+
diff --git a/infrastructure/ace/www/syntax-new.css b/infrastructure/ace/www/syntax-new.css
new file mode 100644
index 0000000..30f1823
--- /dev/null
+++ b/infrastructure/ace/www/syntax-new.css
@@ -0,0 +1,35 @@
+.syntax .t1 {font-style:italic;color:#2AC300;}
+.syntax .t2 {color:#CC6633;}
+.syntax .t3 {font-weight:bold;color:#6699FF;}
+.syntax .t4 {color:#A700CC;}
+.syntax .t5 {color:#000000;}
+.syntax .t6 {font-weight:bold;color:#000CFF;}
+.syntax .t7 {color:#318495;}
+.syntax .t8 {color:#33CC33;}
+.syntax .t9 {color:#1A921C;}
+.syntax .t10 {font-weight:bold;color:#0C450D;}
+.syntax .t11 {font-weight:bold;color:#000099;}
+.syntax .t12 {}
+.syntax .t13 {}
+.syntax .t14 {}
+.syntax .t15 {color:#70727E;}
+.syntax .t16 {font-style:italic;color:#000000;}
+.syntax .t17 {color:#990099;}
+.syntax .t18 {color:#CC6633;}
+.syntax .t19 {color:#990099;}
+.syntax .t20 {color:#CC6633;}
+.syntax .t21 {color:#000000;}
+.syntax .t22 {color:#990000;font-weight:bold;}
+.syntax .t23 {}
+.syntax .t24 {}
+.syntax .t25 {}
+.syntax .t26 {color:#68685B;}
+.syntax .t27 {color:#888888;}
+.syntax .t28 {font-style:italic;}
+.syntax .t29 {color:#1C02FF;}
+.syntax .t30 {font-weight:bold;}
+.syntax .t31 {font-style:italic;}
+.syntax .t32 {font-weight:bold;color:#0C07FF;}
+.syntax .t33 {font-style:italic;color:#000000;}
+.syntax .t34 {color:#B90690;}
+.syntax .t35 {color:#666666;}
diff --git a/infrastructure/ace/www/syntax.css b/infrastructure/ace/www/syntax.css
new file mode 100644
index 0000000..e018320
--- /dev/null
+++ b/infrastructure/ace/www/syntax.css
@@ -0,0 +1,32 @@
+/* ---------- Used by JavaScript Lexer ---------- */
+.syntax .c { color: #bd3f00; font-style: italic } /* Comment */
+.syntax .o { font-weight: bold; } /* Operator */
+.syntax .p { font-weight: bold; } /* Punctuation */
+.syntax .k { color: blue; } /* Keyword */
+.syntax .kc { color: purple } /* Keyword.Constant */
+.syntax .nx { } /* Name.Other */
+.syntax .mf { color: purple } /* Literal.Number.Float */
+.syntax .mh { color: purple } /* Literal.Number.Hex */
+.syntax .mi { color: purple } /* Literal.Number.Integer */
+.syntax .sr { color: purple } /* Literal.String.Regex */
+.syntax .s2 { color: purple } /* Literal.String.Double */
+.syntax .s1 { color: purple } /* Literal.String.Single */
+.syntax .sd { color: purple } /* Literal.String.Doc */
+.syntax .cs { color: #00aa33; font-weight: bold; font-style: italic } /* Comment.Special */
+.syntax .err { color: #cc0000; font-weight: bold; text-decoration: underline; } /* Error */
+
+/* css */
+.syntax .nt { font-weight: bold; } /* tag */
+.syntax .nc { color: #336; } /* class */
+.syntax .nf { color: #336; } /* id */
+.syntax .nd { color: #999; } /* :foo */
+.syntax .m { color: purple } /* number */
+.syntax .nb { color: purple } /* built-in */
+.syntax .cp { color: #bd3f00; } /* !important */
+
+.syntax .flash { background-color: #adf !important; }
+.syntax .flashbad { background-color: #f55 !important; }
+
+/*.syntax .test { background-color: #0f0; }*/
+/*.syntax .test { background: url(http://dl.getdropbox.com/u/88/blackvert.gif)
+ repeat-y left top; }*/
diff --git a/infrastructure/ace/www/test.html b/infrastructure/ace/www/test.html
new file mode 100644
index 0000000..73fa45c
--- /dev/null
+++ b/infrastructure/ace/www/test.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head>
+ <script src="bbtree.js"></script>
+ </head>
+ <body>
+ &nbsp;
+ </body>
+</html>
diff --git a/infrastructure/ace/www/testcode.js b/infrastructure/ace/www/testcode.js
new file mode 100644
index 0000000..f393335
--- /dev/null
+++ b/infrastructure/ace/www/testcode.js
@@ -0,0 +1,36 @@
+function getTestCode() {
+ var testCode = [
+'/* appjet:version 0.1 */',
+'(function(){',
+'/*',
+' * jQuery 1.2.1 - New Wave Javascript',
+' *',
+' * Copyright (c) 2007 John Resig (jquery.com)',
+' * Dual licensed under the MIT (MIT-LICENSE.txt)',
+' * and GPL (GPL-LICENSE.txt) licenses.',
+' *',
+' * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $',
+' * $Rev: 3353 $',
+' */',
+'',
+'// Map over jQuery in case of overwrite',
+'if ( typeof jQuery != "undefined" )',
+' var _jQuery = jQuery;',
+'',
+'var jQuery = window.jQuery = function(selector, context) {',
+' // If the context is a namespace object, return a new object',
+' return this instanceof jQuery ?',
+' this.init(selector, context) :',
+' new jQuery(selector, context);',
+'};',
+'',
+'// Map over the $ in case of overwrite',
+'if ( typeof $ != "undefined" )',
+' var _$ = $;',
+' ',
+'// Map the jQuery namespace to the \'$\' one',
+'window.$ = jQuery;',
+'',
+'var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;'].join('\n');
+ return testCode;
+}
diff --git a/infrastructure/ace/www/toSource.js b/infrastructure/ace/www/toSource.js
new file mode 100644
index 0000000..bf96df7
--- /dev/null
+++ b/infrastructure/ace/www/toSource.js
@@ -0,0 +1,274 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ based on: http://www.JSON.org/json2.js
+ 2008-07-15
+*/
+toSource = function () {
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ Date.prototype.toJSON = function (key) {
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+ // If the string contains no control characters, no quote characters, and no
+ // backslash characters, then we can safely slap some quotes around it.
+ // Otherwise we must also replace the offending characters with safe escape
+ // sequences.
+
+ escapeable.lastIndex = 0;
+ return escapeable.test(string) ?
+ '"' + string.replace(escapeable, function (a) {
+ var c = meta[a];
+ if (typeof c === 'string') {
+ return c;
+ }
+ return '\\u' + ('0000' +
+ (+(a.charCodeAt(0))).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+ // Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ // If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+ // If we were called with a replacer function, then call the replacer to
+ // obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ // What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+ // JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+ // If the value is a boolean or null, convert it to a string. Note:
+ // typeof null does not produce 'null'. The case is included here in
+ // the remote chance that this gets fixed someday.
+
+ return String(value);
+
+ // If the type is 'object', we might be dealing with an object or an array or
+ // null.
+
+ case 'object':
+
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
+ // so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+ // Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+ if (!(value instanceof Object)) {
+ function domNodeIndex(nd) {
+ if (nd.parentNode && nd.parentNode.childNodes.length) {
+ var nds = nd.parentNode.childNodes;
+ var i = 0;
+ while (i < nds.length && nds.item(i) !== nd) {
+ i++;
+ }
+ if (i < nds.length) {
+ return "("+i+")";
+ }
+ }
+ return "";
+ }
+ if (value.nodeType == 3) {
+ return "['"+value.nodeValue+domNodeIndex(value)+"']";
+ }
+ else if (value.tagName) {
+ return "["+value.tagName+domNodeIndex(value)+"]";
+ }
+ else {
+ return '(special)';
+ }
+ }
+
+ // If the object has a dontEnum length property, we'll treat it as an array.
+
+ if (typeof value.length === 'number' &&
+ !(value.propertyIsEnumerable('length'))) {
+
+ // The object is an array. Stringify every element. Use null as a placeholder
+ // for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ // Join all of the elements together, separated with commas, and wrap them in
+ // brackets.
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+ // If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+ // Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ // Join all of the member texts together, separated with commas,
+ // and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ return function (value, replacer, space) {
+
+ // The stringify method takes a value and an optional replacer, and an optional
+ // space parameter, and returns a JSON text. The replacer can be a function
+ // that can replace values, or an array of strings that will select the keys.
+ // A default replacer method can be provided. Use of the space parameter can
+ // produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+ // If the space parameter is a number, make an indent string containing that
+ // many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+ // If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+ // If there is a replacer, it must be a function or an array.
+ // Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+ // Make a fake root object containing our value under the key of ''.
+ // Return the result of stringifying the value.
+
+ return str('', {'': value});
+ }
+}();
diff --git a/infrastructure/ace/www/undomodule.js b/infrastructure/ace/www/undomodule.js
new file mode 100644
index 0000000..b8a56f9
--- /dev/null
+++ b/infrastructure/ace/www/undomodule.js
@@ -0,0 +1,258 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+undoModule = (function() {
+ var stack = (function() {
+ var stackElements = [];
+ // two types of stackElements:
+ // 1) { elementType: UNDOABLE_EVENT, eventType: "anything", [backset: <changeset>,]
+ // [selStart: <char number>, selEnd: <char number>, selFocusAtStart: <boolean>] }
+ // 2) { elementType: EXTERNAL_CHANGE, changeset: <changeset> }
+ // invariant: no two consecutive EXTERNAL_CHANGEs
+ var numUndoableEvents = 0;
+
+ var UNDOABLE_EVENT = "undoableEvent";
+ var EXTERNAL_CHANGE = "externalChange";
+
+ function clearStack() {
+ stackElements.length = 0;
+ stackElements.push({ elementType: UNDOABLE_EVENT, eventType: "bottom" });
+ numUndoableEvents = 1;
+ }
+ clearStack();
+
+ function pushEvent(event) {
+ var e = extend({}, event);
+ e.elementType = UNDOABLE_EVENT;
+ stackElements.push(e);
+ numUndoableEvents++;
+ //dmesg("pushEvent backset: "+event.backset);
+ }
+
+ function pushExternalChange(cs) {
+ var idx = stackElements.length-1;
+ if (stackElements[idx].elementType == EXTERNAL_CHANGE) {
+ stackElements[idx].changeset = Changeset.compose(stackElements[idx].changeset, cs, getAPool());
+ }
+ else {
+ stackElements.push({elementType: EXTERNAL_CHANGE, changeset: cs});
+ }
+ }
+
+ function _exposeEvent(nthFromTop) {
+ // precond: 0 <= nthFromTop < numUndoableEvents
+ var targetIndex = stackElements.length - 1 - nthFromTop;
+ var idx = stackElements.length - 1;
+ while (idx > targetIndex || stackElements[idx].elementType == EXTERNAL_CHANGE) {
+ if (stackElements[idx].elementType == EXTERNAL_CHANGE) {
+ var ex = stackElements[idx];
+ var un = stackElements[idx-1];
+ if (un.backset) {
+ var excs = ex.changeset;
+ var unbs = un.backset;
+ un.backset = Changeset.follow(excs, un.backset, false, getAPool());
+ ex.changeset = Changeset.follow(unbs, ex.changeset, true, getAPool());
+ if ((typeof un.selStart) == "number") {
+ var newSel = Changeset.characterRangeFollow(excs, un.selStart, un.selEnd);
+ un.selStart = newSel[0];
+ un.selEnd = newSel[1];
+ if (un.selStart == un.selEnd) {
+ un.selFocusAtStart = false;
+ }
+ }
+ }
+ stackElements[idx-1] = ex;
+ stackElements[idx] = un;
+ if (idx >= 2 && stackElements[idx-2].elementType == EXTERNAL_CHANGE) {
+ ex.changeset = Changeset.compose(stackElements[idx-2].changeset,
+ ex.changeset, getAPool());
+ stackElements.splice(idx-2, 1);
+ idx--;
+ }
+ }
+ else {
+ idx--;
+ }
+ }
+ }
+
+ function getNthFromTop(n) {
+ // precond: 0 <= n < numEvents()
+ _exposeEvent(n);
+ return stackElements[stackElements.length - 1 - n];
+ }
+
+ function numEvents() {
+ return numUndoableEvents;
+ }
+
+ function popEvent() {
+ // precond: numEvents() > 0
+ _exposeEvent(0);
+ numUndoableEvents--;
+ return stackElements.pop();
+ }
+
+ return {numEvents:numEvents, popEvent:popEvent, pushEvent: pushEvent,
+ pushExternalChange: pushExternalChange, clearStack: clearStack,
+ getNthFromTop:getNthFromTop};
+ })();
+
+ // invariant: stack always has at least one undoable event
+
+ var undoPtr = 0; // zero-index from top of stack, 0 == top
+
+ function clearHistory() {
+ stack.clearStack();
+ undoPtr = 0;
+ }
+
+ function _charOccurrences(str, c) {
+ var i = 0;
+ var count = 0;
+ while (i >= 0 && i < str.length) {
+ i = str.indexOf(c, i);
+ if (i >= 0) {
+ count++;
+ i++;
+ }
+ }
+ return count;
+ }
+
+ function _opcodeOccurrences(cs, opcode) {
+ return _charOccurrences(Changeset.unpack(cs).ops, opcode);
+ }
+
+ function _mergeChangesets(cs1, cs2) {
+ if (! cs1) return cs2;
+ if (! cs2) return cs1;
+
+ // Rough heuristic for whether changesets should be considered one action:
+ // each does exactly one insertion, no dels, and the composition does also; or
+ // each does exactly one deletion, no ins, and the composition does also.
+ // A little weird in that it won't merge "make bold" with "insert char"
+ // but will merge "make bold and insert char" with "insert char",
+ // though that isn't expected to come up.
+ var plusCount1 = _opcodeOccurrences(cs1, '+');
+ var plusCount2 = _opcodeOccurrences(cs2, '+');
+ var minusCount1 = _opcodeOccurrences(cs1, '-');
+ var minusCount2 = _opcodeOccurrences(cs2, '-');
+ if (plusCount1 == 1 && plusCount2 == 1 && minusCount1 == 0 && minusCount2 == 0) {
+ var merge = Changeset.compose(cs1, cs2, getAPool());
+ var plusCount3 = _opcodeOccurrences(merge, '+');
+ var minusCount3 = _opcodeOccurrences(merge, '-');
+ if (plusCount3 == 1 && minusCount3 == 0) {
+ return merge;
+ }
+ }
+ else if (plusCount1 == 0 && plusCount2 == 0 && minusCount1 == 1 && minusCount2 == 1) {
+ var merge = Changeset.compose(cs1, cs2, getAPool());
+ var plusCount3 = _opcodeOccurrences(merge, '+');
+ var minusCount3 = _opcodeOccurrences(merge, '-');
+ if (plusCount3 == 0 && minusCount3 == 1) {
+ return merge;
+ }
+ }
+ return null;
+ }
+
+ function reportEvent(event) {
+ var topEvent = stack.getNthFromTop(0);
+
+ function applySelectionToTop() {
+ if ((typeof event.selStart) == "number") {
+ topEvent.selStart = event.selStart;
+ topEvent.selEnd = event.selEnd;
+ topEvent.selFocusAtStart = event.selFocusAtStart;
+ }
+ }
+
+ if ((! event.backset) || Changeset.isIdentity(event.backset)) {
+ applySelectionToTop();
+ }
+ else {
+ var merged = false;
+ if (topEvent.eventType == event.eventType) {
+ var merge = _mergeChangesets(event.backset, topEvent.backset);
+ if (merge) {
+ topEvent.backset = merge;
+ //dmesg("reportEvent merge: "+merge);
+ applySelectionToTop();
+ merged = true;
+ }
+ }
+ if (! merged) {
+ stack.pushEvent(event);
+ }
+ undoPtr = 0;
+ }
+
+ }
+
+ function reportExternalChange(changeset) {
+ if (changeset && ! Changeset.isIdentity(changeset)) {
+ stack.pushExternalChange(changeset);
+ }
+ }
+
+ function _getSelectionInfo(event) {
+ if ((typeof event.selStart) != "number") {
+ return null;
+ }
+ else {
+ return {selStart: event.selStart, selEnd: event.selEnd,
+ selFocusAtStart: event.selFocusAtStart};
+ }
+ }
+
+ // For "undo" and "redo", the change event must be returned
+ // by eventFunc and NOT reported through the normal mechanism.
+ // "eventFunc" should take a changeset and an optional selection info object,
+ // or can be called with no arguments to mean that no undo is possible.
+ // "eventFunc" will be called exactly once.
+
+ function performUndo(eventFunc) {
+ if (undoPtr < stack.numEvents()-1) {
+ var backsetEvent = stack.getNthFromTop(undoPtr);
+ var selectionEvent = stack.getNthFromTop(undoPtr+1);
+ var undoEvent = eventFunc(backsetEvent.backset, _getSelectionInfo(selectionEvent));
+ stack.pushEvent(undoEvent);
+ undoPtr += 2;
+ }
+ else eventFunc();
+ }
+
+ function performRedo(eventFunc) {
+ if (undoPtr >= 2) {
+ var backsetEvent = stack.getNthFromTop(0);
+ var selectionEvent = stack.getNthFromTop(1);
+ eventFunc(backsetEvent.backset, _getSelectionInfo(selectionEvent));
+ stack.popEvent();
+ undoPtr -= 2;
+ }
+ else eventFunc();
+ }
+
+ function getAPool() {
+ return undoModule.apool;
+ }
+
+ return {clearHistory:clearHistory, reportEvent:reportEvent, reportExternalChange:reportExternalChange,
+ performUndo:performUndo, performRedo:performRedo, enabled: true,
+ apool: null}; // apool is filled in by caller
+})(); \ No newline at end of file
diff --git a/infrastructure/ace/www/virtual_lines.js b/infrastructure/ace/www/virtual_lines.js
new file mode 100644
index 0000000..86e3dea
--- /dev/null
+++ b/infrastructure/ace/www/virtual_lines.js
@@ -0,0 +1,287 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function makeVirtualLineView(lineNode) {
+
+ // how much to jump forward or backward at once in a charSeeker before
+ // constructing a DOM node and checking the coordinates (which takes a
+ // significant fraction of a millisecond). From the
+ // coordinates and the approximate line height we can estimate how
+ // many lines we have moved. We risk being off if the number of lines
+ // we move is on the order of the line height in pixels. Fortunately,
+ // when the user boosts the font-size they increase both.
+ var maxCharIncrement = 20;
+ var seekerAtEnd = null;
+
+ function getNumChars() {
+ return lineNode.textContent.length;
+ }
+
+ function getNumVirtualLines() {
+ if (! seekerAtEnd) {
+ var seeker = makeCharSeeker();
+ seeker.forwardByWhile(maxCharIncrement);
+ seekerAtEnd = seeker;
+ }
+ return seekerAtEnd.getVirtualLine() + 1;
+ }
+
+ function getVLineAndOffsetForChar(lineChar) {
+ var seeker = makeCharSeeker();
+ seeker.forwardByWhile(maxCharIncrement, null, lineChar);
+ var theLine = seeker.getVirtualLine();
+ seeker.backwardByWhile(8, function() { return seeker.getVirtualLine() == theLine; });
+ seeker.forwardByWhile(1, function() { return seeker.getVirtualLine() != theLine; });
+ var lineStartChar = seeker.getOffset();
+ return {vline:theLine, offset:(lineChar - lineStartChar)};
+ }
+
+ function getCharForVLineAndOffset(vline, offset) {
+ // returns revised vline and offset as well as absolute char index within line.
+ // if offset is beyond end of line, for example, will give new offset at end of line.
+ var seeker = makeCharSeeker();
+ // go to start of line
+ seeker.binarySearch(function() {
+ return seeker.getVirtualLine() >= vline;
+ });
+ var lineStart = seeker.getOffset();
+ var theLine = seeker.getVirtualLine();
+ // go to offset, overshooting the virtual line only if offset is too large for it
+ seeker.forwardByWhile(maxCharIncrement, null, lineStart+offset);
+ // get back into line
+ seeker.backwardByWhile(1, function() { return seeker.getVirtualLine() != theLine; }, lineStart);
+ var lineChar = seeker.getOffset();
+ var theOffset = lineChar - lineStart;
+ // handle case of last virtual line; should be able to be at end of it
+ if (theOffset < offset && theLine == (getNumVirtualLines()-1)) {
+ var lineLen = getNumChars();
+ theOffset += lineLen-lineChar;
+ lineChar = lineLen;
+ }
+
+ return { vline:theLine, offset:theOffset, lineChar:lineChar };
+ }
+
+ return {getNumVirtualLines:getNumVirtualLines, getVLineAndOffsetForChar:getVLineAndOffsetForChar,
+ getCharForVLineAndOffset:getCharForVLineAndOffset,
+ makeCharSeeker: function() { return makeCharSeeker(); } };
+
+ function deepFirstChildTextNode(nd) {
+ nd = nd.firstChild;
+ while (nd && nd.firstChild) nd = nd.firstChild;
+ if (nd.data) return nd;
+ return null;
+ }
+
+ function makeCharSeeker(/*lineNode*/) {
+
+ function charCoords(tnode, i) {
+ var container = tnode.parentNode;
+
+ // treat space specially; a space at the end of a virtual line
+ // will have weird coordinates
+ var isSpace = (tnode.nodeValue.charAt(i) === " ");
+ if (isSpace) {
+ if (i == 0) {
+ if (container.previousSibling && deepFirstChildTextNode(container.previousSibling)) {
+ tnode = deepFirstChildTextNode(container.previousSibling);
+ i = tnode.length-1;
+ container = tnode.parentNode;
+ }
+ else {
+ return {top:container.offsetTop, left:container.offsetLeft};
+ }
+ }
+ else {
+ i--; // use previous char
+ }
+ }
+
+
+ var charWrapper = document.createElement("SPAN");
+
+ // wrap the character
+ var tnodeText = tnode.nodeValue;
+ var frag = document.createDocumentFragment();
+ frag.appendChild(document.createTextNode(tnodeText.substring(0, i)));
+ charWrapper.appendChild(document.createTextNode(tnodeText.substr(i, 1)));
+ frag.appendChild(charWrapper);
+ frag.appendChild(document.createTextNode(tnodeText.substring(i+1)));
+ container.replaceChild(frag, tnode);
+
+ var result = {top:charWrapper.offsetTop,
+ left:charWrapper.offsetLeft + (isSpace ? charWrapper.offsetWidth : 0),
+ height:charWrapper.offsetHeight};
+
+ while (container.firstChild) container.removeChild(container.firstChild);
+ container.appendChild(tnode);
+
+ return result;
+ }
+
+ var lineText = lineNode.textContent;
+ var lineLength = lineText.length;
+
+ var curNode = null;
+ var curChar = 0;
+ var curCharWithinNode = 0
+ var curTop;
+ var curLeft;
+ var approxLineHeight;
+ var whichLine = 0;
+
+ function nextNode() {
+ var n = curNode;
+ if (! n) n = lineNode.firstChild;
+ else n = n.nextSibling;
+ while (n && ! deepFirstChildTextNode(n)) {
+ n = n.nextSibling;
+ }
+ return n;
+ }
+ function prevNode() {
+ var n = curNode;
+ if (! n) n = lineNode.lastChild;
+ else n = n.previousSibling;
+ while (n && ! deepFirstChildTextNode(n)) {
+ n = n.previousSibling;
+ }
+ return n;
+ }
+
+ var seeker;
+ if (lineLength > 0) {
+ curNode = nextNode();
+ var firstCharData = charCoords(deepFirstChildTextNode(curNode), 0);
+ approxLineHeight = firstCharData.height;
+ curTop = firstCharData.top;
+ curLeft = firstCharData.left;
+
+ function updateCharData(tnode, i) {
+ var coords = charCoords(tnode, i);
+ whichLine += Math.round((coords.top - curTop) / approxLineHeight);
+ curTop = coords.top;
+ curLeft = coords.left;
+ }
+
+ seeker = {
+ forward: function(numChars) {
+ var oldChar = curChar;
+ var newChar = curChar + numChars;
+ if (newChar > (lineLength-1))
+ newChar = lineLength-1;
+ while (curChar < newChar) {
+ var curNodeLength = deepFirstChildTextNode(curNode).length;
+ var toGo = curNodeLength - curCharWithinNode;
+ if (curChar + toGo > newChar || ! nextNode()) {
+ // going to next node would be too far
+ var n = newChar - curChar;
+ if (n >= toGo) n = toGo-1;
+ curChar += n;
+ curCharWithinNode += n;
+ break;
+ }
+ else {
+ // go to next node
+ curChar += toGo;
+ curCharWithinNode = 0;
+ curNode = nextNode();
+ }
+ }
+ updateCharData(deepFirstChildTextNode(curNode), curCharWithinNode);
+ return curChar - oldChar;
+ },
+ backward: function(numChars) {
+ var oldChar = curChar;
+ var newChar = curChar - numChars;
+ if (newChar < 0) newChar = 0;
+ while (curChar > newChar) {
+ if (curChar - curCharWithinNode <= newChar || !prevNode()) {
+ // going to prev node would be too far
+ var n = curChar - newChar;
+ if (n > curCharWithinNode) n = curCharWithinNode;
+ curChar -= n;
+ curCharWithinNode -= n;
+ break;
+ }
+ else {
+ // go to prev node
+ curChar -= curCharWithinNode+1;
+ curNode = prevNode();
+ curCharWithinNode = deepFirstChildTextNode(curNode).length-1;
+ }
+ }
+ updateCharData(deepFirstChildTextNode(curNode), curCharWithinNode);
+ return oldChar - curChar;
+ },
+ getVirtualLine: function() { return whichLine; },
+ getLeftCoord: function() { return curLeft; }
+ };
+ }
+ else {
+ curLeft = lineNode.offsetLeft;
+ seeker = { forward: function(numChars) { return 0; },
+ backward: function(numChars) { return 0; },
+ getVirtualLine: function() { return 0; },
+ getLeftCoord: function() { return curLeft; }
+ };
+ }
+ seeker.getOffset = function() { return curChar; };
+ seeker.getLineLength = function() { return lineLength; };
+ seeker.toString = function() {
+ return "seeker[curChar: "+curChar+"("+lineText.charAt(curChar)+"), left: "+seeker.getLeftCoord()+", vline: "+seeker.getVirtualLine()+"]";
+ };
+
+ function moveByWhile(isBackward, amount, optCondFunc, optCharLimit) {
+ var charsMovedLast = null;
+ var hasCondFunc = ((typeof optCondFunc) == "function");
+ var condFunc = optCondFunc;
+ var hasCharLimit = ((typeof optCharLimit) == "number");
+ var charLimit = optCharLimit;
+ while (charsMovedLast !== 0 && ((! hasCondFunc) || condFunc())) {
+ var toMove = amount;
+ if (hasCharLimit) {
+ var untilLimit = (isBackward ? curChar - charLimit : charLimit - curChar);
+ if (untilLimit < toMove) toMove = untilLimit;
+ }
+ if (toMove < 0) break;
+ charsMovedLast = (isBackward ? seeker.backward(toMove) : seeker.forward(toMove));
+ }
+ }
+
+ seeker.forwardByWhile = function(amount, optCondFunc, optCharLimit) {
+ moveByWhile(false, amount, optCondFunc, optCharLimit);
+ }
+ seeker.backwardByWhile = function(amount, optCondFunc, optCharLimit) {
+ moveByWhile(true, amount, optCondFunc, optCharLimit);
+ }
+ seeker.binarySearch = function(condFunc) {
+ // returns index of boundary between false chars and true chars;
+ // positions seeker at first true char, or else last char
+ var trueFunc = condFunc;
+ var falseFunc = function() { return ! condFunc(); };
+ seeker.forwardByWhile(20, falseFunc);
+ seeker.backwardByWhile(20, trueFunc);
+ seeker.forwardByWhile(10, falseFunc);
+ seeker.backwardByWhile(5, trueFunc);
+ seeker.forwardByWhile(1, falseFunc);
+ return seeker.getOffset() + (condFunc() ? 0 : 1);
+ }
+
+ return seeker;
+ }
+
+}
diff --git a/infrastructure/bin/classpath.sh b/infrastructure/bin/classpath.sh
new file mode 100755
index 0000000..b1d297c
--- /dev/null
+++ b/infrastructure/bin/classpath.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CP="./"
+for f in `ls lib/*.jar`; do
+ CP="${CP}:${f}"
+done
+echo $CP
diff --git a/infrastructure/bin/comp.sh b/infrastructure/bin/comp.sh
new file mode 100755
index 0000000..5f65c2f
--- /dev/null
+++ b/infrastructure/bin/comp.sh
@@ -0,0 +1,199 @@
+#!/bin/bash -e
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source bin/compilecache.sh
+
+rm -rf build
+mkdir build
+
+if [ "$1" == "clearcache" ]; then
+ echo "CLEARING BUILD CACHE"
+ rm -rf buildcache
+ mkdir -p buildcache
+ shift;
+fi
+
+if [ -z "$CC" ]; then
+ CC=fsc
+fi
+echo compiling with \'$CC\'...
+
+CP=`bin/classpath.sh`
+CP="build/:${CP}"
+
+if [ -z "$OBFUSC" ]; then
+ OBFUSC=0
+else
+ echo obfuscation on...
+fi
+
+#THRIFTFILES=`echo net.appjet.fancypants/{storage/KeyValueStore,DebugLog,LtpLog}.thrift`
+#THRIFTFILES=`find gen-java/net/appjet/fancypants -name '*.java'`
+#function genthrift {
+# echo "generating thrift..."
+# rm -rf gen-java
+# for a in $THRIFTFILES; do
+# thrift -java $a
+# done
+
+# echo "compiling thrift..."
+# CP="${CP}:gen-java/"
+# javac \
+# -classpath $CP \
+# -target 1.5 \
+# -d $1 \
+# $THRIFTFILES
+#}
+#cacheonfiles thrift "$THRIFTFILES" genthrift
+
+ARGS=$@
+
+COMMONFILES=`find net.appjet.common -name '*.java'`
+COMMONSCALAFILES=`find net.appjet.common -name '*.scala'`
+function gencommon {
+ echo "compiling common..."
+ javac \
+ -cp $CP \
+ -d $1 \
+ -target 1.5 \
+ $COMMONFILES
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $COMMONSCALAFILES
+}
+cacheonfiles common "$COMMONFILES $COMMONSCALAFILES" gencommon
+
+SARSFILES=`find net.appjet.common.sars -name '*.scala'`
+function gensars {
+ echo "compiling sars..."
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $SARSFILES
+}
+cacheonfiles sars "$SARSFILES" gensars
+
+CLIFILES=`find net.appjet.common.cli -name '*.scala'`
+function gencli {
+ echo "compiling cli..."
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $CLIFILES
+ echo "done with cli"
+}
+cacheonfiles cli "$CLIFILES" gencli
+
+BODYLOCKFILES=`find net.appjet.bodylock -name '*.scala'`
+function genbodylock {
+ echo "compiling rhino abstraction..."
+ $CC \
+ -classpath build:$CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $BODYLOCKFILES
+}
+cacheonfiles bodylock "$BODYLOCKFILES" genbodylock
+
+APPSERVERFILES=`find net.appjet.oui -name '*.scala'`
+APPSERVERJAVAFILES=`find net.appjet.oui -name '*.java'`
+function genappserver {
+ echo "compiling appserver source..."
+ javac \
+ -cp $CP \
+ -d $1 \
+ -target 1.5 \
+ $APPSERVERJAVAFILES
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $APPSERVERFILES
+}
+cacheonfiles appserver "$APPSERVERFILES $APPSERVERJAVAFILES" genappserver
+
+AJSTDLIBFILES=`find net.appjet.ajstdlib -name '*.scala'`
+AJSTDLIBJAVAFILES=`find net.appjet.ajstdlib -name '*.java'`
+function genajstdlib {
+ echo "compiling ajstdlib..."
+ mkdir -p $1
+ if [ ! -z "$AJSTDLIBJAVAFILES" ]; then
+ javac \
+ -cp $CP \
+ -d $1 \
+ -target 1.5 \
+ $AJSTDLIBJAVAFILES
+ fi
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $AJSTDLIBFILES
+}
+cacheonfiles ajstdlib "$AJSTDLIBFILES $AJSTDLIBJAVAFILES" genajstdlib
+
+EPFILES=`find com.etherpad -name '*.scala'`
+function genetherpad {
+ echo "compilng etherpad..."
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $EPFILES
+}
+cacheonfiles etherpad "$EPFILES" genetherpad
+
+OOSERVICEFILES=`find com.etherpad.openofficeservice -name '*.scala'`
+function genooservice {
+ echo "compiling ooservice..."
+ $CC \
+ -classpath $CP \
+ -d $1 \
+ -target:jvm-1.5 \
+ $ARGS \
+ $OOSERVICEFILES
+}
+cacheonfiles ooservice "$OOSERVICEFILES" genooservice
+
+echo "copying files..."
+cp net.appjet.ajstdlib/streaming-client.js build/net/appjet/ajstdlib/
+if [ $OBFUSC ] ; then
+ echo obfuscating...
+ scala -classpath $CP:. net.appjet.bodylock.compressor \
+ build/net/appjet/ajstdlib/streaming-client.js
+fi
+
+cp net.appjet.ajstdlib/streaming-iframe.html build/net/appjet/ajstdlib/
+mkdir -p build/net/appjet/ajstdlib/modules
+
+echo "building javascript classfiles..."
+scala -classpath $CP net.appjet.bodylock.Compiler \
+ -destination=build/net/appjet/ajstdlib/ \
+ -cutPrefix=framework-src \
+ `find framework-src -name '*.js'`
+
+echo "done."
diff --git a/infrastructure/bin/compilecache.sh b/infrastructure/bin/compilecache.sh
new file mode 100644
index 0000000..a2b6220
--- /dev/null
+++ b/infrastructure/bin/compilecache.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CP_CMD="cp -R -u"
+if [ `uname` == "Darwin" ]; then
+ CP_CMD="/bin/cp -R -n"
+fi
+
+function cacheonfiles {
+ NAME=$1; FILES=$2; FUNC=$3; NOCOPY=1;
+ if [ -z "$4" ]; then
+ NOCOPY=0
+ fi
+ REBUILD=0
+ BPATH=buildcache/$NAME
+ FILETEST=$BPATH/t
+ if [ ! -f $FILETEST ]; then
+ REBUILD=1
+ else
+ for a in $FILES; do
+ if [ $FILETEST -ot $a ]; then
+ echo $a has changed, rebuilding $NAME
+ REBUILD=1
+ fi
+ done
+ fi
+ if [ $REBUILD -eq 1 ]; then
+ if [ -d $BPATH ]; then
+ rm -rf $BPATH
+ fi
+ mkdir -p $BPATH
+ $FUNC $BPATH
+ pushd $BPATH >> /dev/null
+ touch t
+ popd >> /dev/null
+ else
+ echo using cached $NAME...
+ fi
+ if [ $NOCOPY -ne 1 ]; then
+ for a in $BPATH/*; do
+ if [ -d $a ]; then
+ $CP_CMD $a build/
+ elif [ -f $a ]; then
+ cp $a build/
+ else
+ echo unknown file type $a
+ exit 1
+ fi
+ done
+ fi
+}
diff --git a/infrastructure/bin/jscomp.sh b/infrastructure/bin/jscomp.sh
new file mode 100755
index 0000000..3f5bc51
--- /dev/null
+++ b/infrastructure/bin/jscomp.sh
@@ -0,0 +1,23 @@
+#!/bin/bash -e
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+rm -rf buildjs
+mkdir buildjs
+
+bin/comp.sh
+CLASSPATH=`bin/classpath.sh`
+
+scala -cp $CLASSPATH:build net.appjet.bodylock.Compiler -destination buildjs $@
diff --git a/infrastructure/bin/makejar.sh b/infrastructure/bin/makejar.sh
new file mode 100755
index 0000000..c774fa6
--- /dev/null
+++ b/infrastructure/bin/makejar.sh
@@ -0,0 +1,74 @@
+#!/bin/bash -e
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ -z "$JAR" ]; then
+ JAR=jar
+else
+ echo "using JAR $JAR..."
+fi
+
+cp ${MYSQL_CONNECTOR_JAR} lib/
+
+source bin/compilecache.sh
+
+if [ "$1" == "clearcache" ]; then
+ echo "CLEARING BUILD CACHE"
+ rm -rf buildcache
+ shift;
+fi
+
+TMPSTORE=/tmp/ajbuild-tmpstore-`date +%s`
+
+JARFILES=`echo $SCALA_HOME/lib/scala-library.jar lib/*.jar lib/manifest`
+function genjar {
+ echo "unzipping JARs..."
+ pushd $1 >> /dev/null
+ $JAR xf $SCALA_HOME/lib/scala-library.jar
+ rm -rf META-INF
+ for a in ../../lib/*.jar; do
+ $JAR xf $a
+ rm -rf META-INF/{MANIFEST.MF,NOTICE{,.txt},LICENSE{,.txt},INDEX.LIST,SUN_MICR.{RSA,SF},maven}
+ done
+
+ echo "making cached JAR...."
+ $JAR -cfm appjet.jar ../../lib/manifest .
+ mv appjet.jar /tmp/appjet.jar
+ rm -rf *
+ mv /tmp/appjet.jar ./
+
+ popd >> /dev/null
+}
+cacheonfiles JAR "$JARFILES" genjar 1
+
+echo "compiling..."
+bin/comp.sh $@
+
+pushd build >> /dev/null
+
+echo "copying cached JAR..."
+cp ../buildcache/JAR/appjet.jar ./
+
+echo "making JAR..."
+mv appjet.jar /tmp/appjet.jar
+$JAR -uf /tmp/appjet.jar . #META-INF com javax org net uk v scala dojox
+mv /tmp/appjet.jar ./
+
+echo "cleaning up..."
+rm -rf $TMPSTORE
+
+popd >> /dev/null
+
+echo "done."
diff --git a/infrastructure/bin/makesars.sh b/infrastructure/bin/makesars.sh
new file mode 100755
index 0000000..541b04a
--- /dev/null
+++ b/infrastructure/bin/makesars.sh
@@ -0,0 +1,23 @@
+#!/bin/bash -e
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+echo "compiling..."
+bin/comp.sh $@
+
+echo "building build/appjet-sars.jar..."
+jar cMf build/appjet-sars.jar -C build `echo build/net/appjet/common/sars/*.class | cut -d/ -f 2-`
+
+echo "done."
diff --git a/infrastructure/bin/run.sh b/infrastructure/bin/run.sh
new file mode 100755
index 0000000..cf918d4
--- /dev/null
+++ b/infrastructure/bin/run.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CP=`bin/classpath.sh`
+
+JAVA_OPTS="-d64 -server -Xmx12288m -Xloggc:/appjet/log/appserver/jvm-gc.log -XX:MaxPermSize=256m" scala -cp build:$CP net.appjet.oui.main -devMode -ajstdlibHome framework-src/modules -listenSars 8081 $@
+
diff --git a/infrastructure/com.etherpad.openofficeservice/importexport.scala b/infrastructure/com.etherpad.openofficeservice/importexport.scala
new file mode 100644
index 0000000..f5150ad
--- /dev/null
+++ b/infrastructure/com.etherpad.openofficeservice/importexport.scala
@@ -0,0 +1,189 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.etherpad.openofficeservice;
+
+import net.appjet.common.sars.{SarsServer,SarsMessageHandler};
+
+import java.io.{DataInputStream,DataOutputStream};
+import java.io.{File,FileOutputStream,ByteArrayInputStream,ByteArrayOutputStream};
+
+class OOSException(m: String) extends RuntimeException(m);
+class UnsupportedFormatException(format: String) extends OOSException("Unsupported format: "+format);
+object TemporaryFailure extends OOSException("Temporary failure");
+
+// stub object here. Please replace if you'd like to use openoffice!
+object OpenOfficeServerUtility {
+ def checkServerAvailability(host: String, port: Int): Boolean = {
+ return false;
+ }
+ def runOpenOfficeServer(path: String, host: String, port: Int, timeout: Int, wait: Boolean) {
+ // nothing
+ }
+}
+
+class OpenOfficeFileConverter {
+ def setOpenOfficeServerDetails(host: String, port: Int) {
+ // nothing
+ }
+
+ def convertFile(src: File, dst: File, converter: String, extension: String): Boolean = {
+ return false;
+ }
+}
+
+object OpenOfficeService {
+ val formats = Map(
+ "pdf" -> "writer_pdf_Export",
+ "doc" -> "MS Word 97",
+ "html" -> "HTML (StarWriter)",
+ "odt" -> "writer8",
+ //"html" -> "XHTML Writer File",
+ "txt" -> "Text"
+ );
+
+ def createTempFile(bytes: Array[byte], suffix: String) = {
+ var f = File.createTempFile("ooconvert-", if (suffix == null) { null } else if (suffix == "") { "" } else { "."+suffix });
+ if (bytes != null) {
+ val fos = new FileOutputStream(f);
+ fos.write(bytes);
+ }
+ f;
+ }
+
+ var soffice = "soffice";
+ def setExecutable(exec: String) {
+ soffice = exec;
+ }
+
+ def convertFile(from: String, to: String, bytes: Array[byte]): Array[byte] = {
+ if (from == to) {
+ return bytes;
+ }
+
+ val tempFile = createTempFile(bytes, from);
+ val outFile = createTempFile(null, to);
+
+ val openOfficeServerHost = "localhost";
+ val openOfficeServerPort = 8100;
+ if (! OpenOfficeServerUtility.checkServerAvailability(openOfficeServerHost, openOfficeServerPort)) {
+ try {
+ OpenOfficeServerUtility.runOpenOfficeServer(soffice, openOfficeServerHost, openOfficeServerPort, 20000, true);
+ } catch {
+ case e: java.io.IOException => {
+ e.printStackTrace();
+ throw TemporaryFailure;
+ }
+ }
+ }
+ var converter = new OpenOfficeFileConverter();
+ converter.setOpenOfficeServerDetails(openOfficeServerHost, openOfficeServerPort);
+ var status = false;
+ try {
+ status = converter.convertFile(tempFile, outFile, formats(to), to);
+ } catch {
+ case e => {
+ e.printStackTrace();
+ throw new OOSException("Unknown exception occurred: "+e.getMessage());
+ }
+ }
+ if (status == false) {
+ throw new UnsupportedFormatException(from);
+ }
+ net.appjet.common.util.BetterFile.getFileBytes(outFile);
+ }
+
+ def main(args: Array[String]) {
+ if (args.length > 0) {
+ soffice = args(0);
+ if (soffice.length == 0) {
+ exit(1);
+ }
+ }
+
+ // Query format:
+ // from: String, to: String, count: Int, bytes: Array[byte]
+ // Response format:
+ // status: Int, <data>
+ // status 0 (success) - <data>: count: Int, bytes: Array[byte]
+ // status 1 (temporary failure) - <data>: <none>
+ // status 2 (permanent failure) - <data>: type: Int
+ // type - 0: unknown failure.
+ // - 1: unsupported format
+ val handler = new SarsMessageHandler {
+ override def handle(b: Array[byte]): Option[Array[byte]] = {
+ val is = new DataInputStream(new ByteArrayInputStream(b));
+ val from = is.readUTF;
+ val to = is.readUTF;
+ val len = is.readInt;
+ val bytes = new Array[byte](len);
+ is.readFully(bytes);
+ var status = 0;
+ var permfailuretype = 0;
+
+ println("Converting "+from+" -> "+to+" ("+len+" bytes)");
+
+ val output = try {
+ convertFile(from, to, bytes);
+ } catch {
+ case TemporaryFailure => {
+ status = 1;
+ null;
+ }
+ case e: UnsupportedFormatException => {
+ status = 2;
+ permfailuretype = 1;
+ null;
+ }
+ case e => {
+ status = 2;
+ permfailuretype = 0;
+ e.printStackTrace();
+ null;
+ }
+ }
+
+ val retBytes = new ByteArrayOutputStream();
+ val ret = new DataOutputStream(retBytes);
+ if (status != 0) {
+ ret.writeInt(status); // error
+ status match {
+ case 2 => {
+ ret.writeInt(permfailuretype);
+ }
+ case _ => { }
+ }
+ } else {
+ ret.writeInt(0); // success
+ ret.writeInt(output.length);
+ ret.write(output, 0, output.length);
+ }
+ Some(retBytes.toByteArray());
+ }
+ }
+
+ val server = new SarsServer("ooffice-password", handler, None, 8101);
+ server.start();
+ println("Server running...");
+ server.join();
+ println("Server quitting...");
+ }
+}
+
+
+
+
+
diff --git a/infrastructure/com.etherpad/easysync2support.scala b/infrastructure/com.etherpad/easysync2support.scala
new file mode 100644
index 0000000..9f1c527
--- /dev/null
+++ b/infrastructure/com.etherpad/easysync2support.scala
@@ -0,0 +1,167 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.etherpad;
+
+object Easysync2Support {
+
+ def numToString(d: Int): String = java.lang.Integer.toString(d.toInt, 36); // lowercase
+ def stringToNum(s: String): Int = java.lang.Integer.parseInt(s, 36);
+
+ def opAssembler() = new OpAssembler();
+
+ class OpAssembler() {
+ val buf = new StringBuilder(1000);
+ def append(op: Op) {
+ append(op.opcode, op.chars, op.lines, op.attribs);
+ }
+ def append(opcode: String, chars: Int, lines: Int, attribs: String) {
+ buf.append(attribs);
+ if (lines > 0) {
+ buf.append('|');
+ buf.append(numToString(lines));
+ }
+ buf.append(opcode);
+ buf.append(numToString(chars));
+ }
+ override def toString(): String = buf.toString;
+ def clear() { buf.clear; }
+ }
+
+ def isAlphanum(c: Char) = (c >= '0' && c <= '9' || c >= 'a' && c <= 'z');
+
+ case object OpParseError extends Error;
+
+ def nextOpInString(str: String, startIndex: Int): Object = {
+ var i = startIndex;
+
+ try {
+ def lookingAt(c: Char) = (i < str.length && str.charAt(i) == c);
+ def lookingAtAlphanum() = (i < str.length && isAlphanum(str.charAt(i)));
+ def atEnd() = (i >= str.length);
+ def readAlphanum(): Int = {
+ if (! lookingAtAlphanum()) {
+ throw OpParseError;
+ }
+ val start = i;
+ while (lookingAtAlphanum()) {
+ i += 1;
+ }
+ val end = i;
+ stringToNum(str.substring(start, end));
+ }
+
+ while (lookingAt('*')) {
+ i += 1;
+ if (! lookingAtAlphanum()) {
+ throw OpParseError;
+ }
+ while (lookingAtAlphanum()) {
+ i += 1;
+ }
+ }
+ val attribsEnd = i;
+
+ var lines_ = 0;
+ if (lookingAt('|')) {
+ i += 1;
+ lines_ = readAlphanum();
+ }
+
+ if (lookingAt('?')) {
+ return new { val opcode = "?"; }
+ }
+ if (! (lookingAt('+') || lookingAt('-') || lookingAt('='))) {
+ throw OpParseError;
+ }
+ val opcode_ = str.substring(i, i+1);
+ i += 1;
+ val chars_ = readAlphanum();
+
+ return new Op(opcode_, chars_, lines_, str.substring(startIndex, attribsEnd)) {
+ val lastIndex = i;
+ };
+ }
+ catch { case OpParseError => null }
+ }
+
+ case class Op(var opcode: String, var chars: Int, var lines: Int, var attribs: String);
+ def newOp() = Op("", 0, 0, "");
+ def clearOp(op: Op) { op.opcode = ""; op.chars = 0; op.lines = 0; op.attribs = ""; }
+
+ // ported from easysync2.js
+ class MergingOpAssembler {
+ val assem = opAssembler();
+ var bufOp = newOp();
+
+ var bufOpAdditionalCharsAfterNewline = 0;
+
+ def flush(isEndDocument: Boolean) {
+ if (bufOp.opcode.length > 0) {
+ if (isEndDocument && bufOp.opcode == "=" && bufOp.attribs.length == 0) {
+ // final merged keep, leave it implicit
+ }
+ else {
+ assem.append(bufOp);
+ if (bufOpAdditionalCharsAfterNewline > 0) {
+ bufOp.chars = bufOpAdditionalCharsAfterNewline;
+ bufOp.lines = 0;
+ assem.append(bufOp);
+ bufOpAdditionalCharsAfterNewline = 0;
+ }
+ }
+ bufOp.opcode = "";
+ }
+ }
+ def append(opcode: String, chars: Int, lines: Int, attribs: String) {
+ if (chars > 0) {
+ if (bufOp.opcode == opcode && bufOp.attribs == attribs) {
+ if (lines > 0) {
+ // bufOp and additional chars are all mergeable into a multi-line op
+ bufOp.chars += bufOpAdditionalCharsAfterNewline + chars;
+ bufOp.lines += lines;
+ bufOpAdditionalCharsAfterNewline = 0;
+ }
+ else if (bufOp.lines == 0) {
+ // both bufOp and op are in-line
+ bufOp.chars += chars;
+ }
+ else {
+ // append in-line text to multi-line bufOp
+ bufOpAdditionalCharsAfterNewline += chars;
+ }
+ }
+ else {
+ flush(false);
+ bufOp = Op(opcode, chars, lines, attribs);
+ }
+ }
+ }
+ def endDocument() {
+ flush(true);
+ }
+ override def toString() = {
+ flush(false);
+ assem.toString();
+ }
+ def clear() {
+ assem.clear();
+ clearOp(bufOp);
+ }
+ }
+
+ def mergingOpAssembler() = new MergingOpAssembler();
+}
diff --git a/infrastructure/com.etherpad/licensing.scala b/infrastructure/com.etherpad/licensing.scala
new file mode 100644
index 0000000..9318f78
--- /dev/null
+++ b/infrastructure/com.etherpad/licensing.scala
@@ -0,0 +1,169 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.etherpad;
+
+import net.appjet.oui.{Encryptomatic, config};
+import net.appjet.common.util.BetterFile;
+
+import java.io.{FileInputStream, FileOutputStream, ByteArrayInputStream, ByteArrayOutputStream, PrintWriter}
+
+import java.security._;
+import java.security.spec._;
+
+object Licensing {
+ val publicKey = "s0dD94jKFjlSHIumgDQ4ldcyIyna1vMHmG5tsgkP987eBTW88XeEIUTo5JtWOjPzb252GURUrr7MReTqMz6NnsOupeJMqtXgjuVxcXbK8AnckxkxhRqMiFfBW39T9NzPgq09yBdH4tKGlPZQmgaBvjFI8cXTYa7a64LrDnrzrpDhDdJsZPZI2kE7G4vBCGijuhsZpyowK8zT5y2cKqIgIdLxUnXNFtayDi0oyuX1ywfBds2OEil9fEUQOQvkcHAt6kYfPXkE2XgQZFasAv0DPeWMUEtaHTbMaQn1U6BsfmsKjHlLhM3oWEzp0wEwUWxCC39iHYjxa5QKtxm5BNvUTTqJgkoEvk7Uu08j8jhFeCFosph6igDWPmyfAPKTnETXJobO2VON83bVHlX8UfKonnalMy0Hnw2C0I7c0UE0MtMIRtJxtwU62a311Ohp1EVrY4LwKIFfqRMVWKDP0cjXDkJyjJS58rC1DRU7SfPspgfuOy5YZo9sLKztXfzAPzNbXerQ24m2AjmYLV4JQked7MnaKQ6VfyZbFBK5th9NFcJwY1bGbIHW2EsKmiKUoNjPKRJ6VMC7odUCIXQyE9J";
+
+ val pkhash = "f7a3dd5940a3f79904b81e4d32a08e2efaa0b2ab";
+ val keyVersion = 2.toByte;
+
+ def thanksForStealingFromPoorHackersTryingToEkeAMeagerLivingFromThisCruelWorld =
+ Encryptomatic.bytesToAscii(MessageDigest.getInstance("SHA1").digest(publicKey.getBytes())) == pkhash;
+ def sha1(b: Array[Byte]): String = Encryptomatic.bytesToAscii(MessageDigest.getInstance("SHA1").digest(b));
+ def sha1(s: String): String = sha1(s.getBytes("UTF-8"));
+
+ def toBytes(i: Int): Array[Byte] =
+ Array((i >> 24).toByte,
+ (i >> 16).toByte,
+ (i >> 8).toByte,
+ i.toByte);
+ def toByte(i: Int): Array[Byte] =
+ Array(i.toByte);
+ def toBytes(l: Long): Array[Byte] =
+ Array((l >> 56).toByte,
+ (l >> 48).toByte,
+ (l >> 40).toByte,
+ (l >> 32).toByte,
+ (l >> 24).toByte,
+ (l >> 16).toByte,
+ (l >> 8).toByte,
+ l.toByte);
+
+ def toInt(b0: Array[Byte]): Int = {
+ val b = b0.map(_.toInt & 0x00FF);
+ (b(0) << 24) | (b(1) << 16) | (b(2) << 8) | b(3);
+ }
+ def toInt(b: Byte): Int = b.toInt & 0x00FF;
+
+ def toLong(b0: Array[Byte]): Long = {
+ val b = b0.map(_.toLong & 0x000000FF);
+ (b(0) << 56) | (b(1) << 48) | (b(2) << 40) | (b(3) << 32) | (b(4) << 24) | (b(5) << 16) | (b(6) << 8) | b(7);
+ }
+
+ def generateKey(personName: String, organizationName: String, expiresDate: Long, editionId: Int, userQuota: Int, majorVersion: Int, minorVersion: Int, patchVersion: Int) = {
+ if (config.licenseGeneratorKey == null) {
+ throw new RuntimeException("No private key available to generate license key.");
+ }
+ def privateKey = Encryptomatic.readPrivateKey("DSA", new FileInputStream(config.licenseGeneratorKey));
+ def clean(s: String) = s.replaceAll(":", "-");
+ val keyPrefix =
+ List(personName, organizationName, expiresDate.toString, editionId.toString, userQuota.toString, majorVersion.toString, minorVersion.toString, patchVersion.toString).map(clean).mkString(":");
+ val sig = Encryptomatic.sign(new ByteArrayInputStream(keyPrefix.getBytes("UTF-8")), privateKey)
+
+ List(personName, organizationName).mkString(":") + ":" +
+ Encryptomatic.bytesToAscii(
+ Array.concat[Byte](Array(keyVersion), // don't want BigInt dropping bytes, that'd be sad. :(
+ toBytes(expiresDate),
+ toBytes(editionId),
+ toBytes(userQuota),
+ toByte(majorVersion),
+ toByte(minorVersion),
+ toByte(patchVersion),
+ sig));
+ }
+
+ def decodeKey(key: String) = try {
+ val Array(personName0, organizationName0, sigAndInfo) = key.split(":");
+ val sigAndInfoBytes = Encryptomatic.asciiToBytes(sigAndInfo);
+ val thisKeyVersion = toInt(sigAndInfoBytes(0));
+ val expiresDate0 = toLong(sigAndInfoBytes.slice(1, 9));
+ val editionId0 = toInt(sigAndInfoBytes.slice(9, 13));
+ val userQuota0 = toInt(sigAndInfoBytes.slice(13, 17));
+ val (majorVersion0, minorVersion0, patchVersion0) =
+ if (thisKeyVersion >= 2) {
+ (toInt(sigAndInfoBytes(17)), toInt(sigAndInfoBytes(18)), toInt(sigAndInfoBytes(19)));
+ } else {
+ (0, 0, 0);
+ }
+ val sig = sigAndInfoBytes.drop(if (thisKeyVersion >= 2) 20 else 17);
+ val keyPrefix = {
+ var a = Seq(personName0, organizationName0, expiresDate0.toString, editionId0.toString, userQuota0.toString);
+ if (thisKeyVersion >= 2) {
+ a = a ++ Seq(majorVersion0.toString, minorVersion0.toString, patchVersion0.toString);
+ }
+ a.mkString(":");
+ }
+ if (! Encryptomatic.verify(new ByteArrayInputStream(keyPrefix.getBytes("UTF-8")),
+ Encryptomatic.readPublicKey("DSA",
+ new ByteArrayInputStream(publicKey.getBytes())), sig)) {
+ null;
+ } else {
+ new {
+ def personName = personName0;
+ def organizationName = organizationName0;
+ def expiresDate = expiresDate0;
+ def editionId = editionId0;
+ def userQuota = userQuota0;
+ def majorVersion = majorVersion0;
+ def minorVersion = minorVersion0;
+ def patchVersion = patchVersion0;
+ }
+ }
+ } catch {
+ case e => null;
+ }
+
+ def main(args: Array[String]) {
+ args(0) match {
+ case "genkeypair" => {
+ println("Generating keypair...");
+ Encryptomatic.writeKeyPair(Encryptomatic.generateKeyPair("DSA"), args(1), args(2));
+ println("Done.");
+ }
+ case "genmainkey" => {
+ println("Generating key for etherpad.com...");
+ config.values("licenseGeneratorKey") = args(1);
+ val out = new PrintWriter(new FileOutputStream(args(2)));
+ out.print(generateKey("etherpad", "AppJet", -1, 0, -1, 0, 0, 0))
+ out.close();
+ println("Done.");
+ }
+ case "test" => {
+ println("Testing key generation.");
+ config.values("licenseGeneratorKey") = args(1);
+ val key = generateKey("Foo Bar", "Baz, Inc.", System.currentTimeMillis() + 86400*1000, 0, 100, 1, 2, 3);
+ println("Key is: "+key);
+ val obj = decodeKey(key);
+ println(List(obj.personName, obj.organizationName, obj.expiresDate, obj.editionId, obj.userQuota, obj.majorVersion, obj.minorVersion, obj.patchVersion).mkString(", "));
+ }
+ case "parsekey" => {
+ println("Testing key decode.");
+ val obj = decodeKey(args(1));
+ println("Key: "+List(obj.personName, obj.organizationName, obj.expiresDate, obj.editionId, obj.userQuota, obj.majorVersion, obj.minorVersion, obj.patchVersion).mkString(", "));
+ }
+ case "testascii" => {
+ val one = 17;
+ val two = -1L;
+ val three = (Math.random*Math.pow(10, (Math.random*10).toInt)).toInt;
+ println(List(one, two, three).mkString(", "));
+ println(List(toInt(toBytes(one)), toLong(toBytes(two)), toInt(toBytes(three))).mkString(", "));
+ val bytes = Encryptomatic.asciiToBytes(Encryptomatic.bytesToAscii(Array.concat[Byte](Array(1.toByte), toBytes(one), toBytes(two), toBytes(three))));
+ println("I can has bytes: "+bytes.length);
+ println(List(toInt(bytes.slice(1, 5)), toLong(bytes.slice(5, 13)), toInt(bytes.slice(13, 17))).mkString(", "));
+ }
+ }
+ }
+}
diff --git a/infrastructure/com.etherpad/main.scala b/infrastructure/com.etherpad/main.scala
new file mode 100644
index 0000000..5110aba
--- /dev/null
+++ b/infrastructure/com.etherpad/main.scala
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.etherpad;
+
+object main {
+ def main(args: Array[String]) {
+ net.appjet.oui.main.main(args);
+ }
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/modules/atomfeed.js b/infrastructure/framework-src/modules/atomfeed.js
new file mode 100644
index 0000000..4b86eeb
--- /dev/null
+++ b/infrastructure/framework-src/modules/atomfeed.js
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("stringutils.sprintf");
+
+// TODO: validate XHTML of entries?
+
+function _xmlDate(d) {
+ return sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",
+ d.getUTCFullYear(), d.getUTCMonth()+1, d.getUTCDate(),
+ d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds());
+}
+
+// "entries" is an object with "forEach" member (an Array works).
+// Each entry should have these properties:
+// * title
+// * author
+// * published (Date)
+// * updated (Date)
+// * href (URL for HTML version)
+// * content (valid xhtml)
+//
+// NOTE: entries should be sorted descending by entry.updated (newest first)
+//
+
+function renderFeed(title, lastUpdated, entries, href) {
+ function ampesc(url) {
+ return url.replace(/&/g, '&amp;');
+ }
+
+ var r = [];
+ r.push('<?xml version="1.0" encoding="utf-8"?>',
+ '<feed xmlns="http://www.w3.org/2005/Atom">');
+
+ r.push('<title type="text">' + title + '</title>');
+ r.push('<updated>' + _xmlDate(lastUpdated) + '</updated>');
+ r.push('<link rel="self" href="' + request.url + '" />');
+ r.push('<link rel="alternate" type="text/html" href="' + href + '" />');
+ r.push('<id>' + ampesc(request.url) + '</id>');
+
+ entries.forEach(function(entry) {
+ r.push('<entry>',
+ '<title>' + entry.title + '</title>',
+ '<author><name>' + entry.author + '</name></author>',
+ '<published>' + _xmlDate(entry.published) + '</published>',
+ '<updated>' + _xmlDate(entry.updated) + '</updated>',
+ '<link rel="alternate" type="text/html" href="' + entry.href + '" />',
+ '<id>'+ampesc(entry.href)+'</id>',
+ '<content type="xhtml">',
+ '<div xmlns="http://www.w3.org/1999/xhtml">'+entry.content+'</div>',
+ '</content>',
+ '</entry>');
+ });
+
+ r.push('</feed>');
+
+ return r.join('\n');
+}
+
diff --git a/infrastructure/framework-src/modules/blob.js b/infrastructure/framework-src/modules/blob.js
new file mode 100644
index 0000000..af788a0
--- /dev/null
+++ b/infrastructure/framework-src/modules/blob.js
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+/**
+ * Constructs and returns a new Blob from a JavaScript string.
+ */
+function stringToBlob(contentType, string) {
+ return { contentType: contentType,
+ _stringData: string,
+ numDataBytes: string.length*2 };
+}
+
+/**
+ * Constructs and returns a new Blob from a Java byte array (byte[]).
+ */
+function byteArrayToBlob(contentType, javaByteArray) {
+ return { contentType: contentType,
+ _binaryData: javaByteArray,
+ numDataBytes: javaByteArray.length };
+}
+
+/**
+ * Serves a Blob to the client, using the appropriate content-type,
+ * and stops execution of the current request.
+ */
+function serveBlob(blob) {
+ response.setContentType(blob.contentType);
+ if (blob._binaryData) {
+ response.writeBytes(new java.lang.String(blob._binaryData, 0));
+ }
+ else if (blob._stringData) {
+ response.write(blob._stringData);
+ }
+ response.stop();
+}
diff --git a/infrastructure/framework-src/modules/cache_utils.js b/infrastructure/framework-src/modules/cache_utils.js
new file mode 100644
index 0000000..f2a360c
--- /dev/null
+++ b/infrastructure/framework-src/modules/cache_utils.js
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("sync");
+
+/* performs function on an object from the cache, all within a lock */
+function syncedWithCache(name, fn) {
+ return sync.doWithStringLock("cache/"+name, function() {
+ var parts = name.split(".");
+ var obj = appjet.cache;
+ for (var i = 0; i < parts.length; i++) {
+ var p = parts[i];
+ if (!obj[p]) {
+ obj[p] = {};
+ }
+ obj = obj[p];
+ }
+ return fn(obj);
+ });
+}
+
+
+
diff --git a/infrastructure/framework-src/modules/comet.js b/infrastructure/framework-src/modules/comet.js
new file mode 100644
index 0000000..2331f8b
--- /dev/null
+++ b/infrastructure/framework-src/modules/comet.js
@@ -0,0 +1,91 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview
+ * Comet presents a real-time bidirectional-channel interface. Using comet, your
+ * server can push data to any connected client without waiting for that client
+ * to issue a request.
+ *
+ * <tt>comet</tt> reserves the <tt>/newcomet</tt> path and its subpaths for its
+ * own use.
+ */
+
+/**
+ * Gets a list of all client currently connected to the server.
+ * @function
+ * @name connections
+ * @return {array} An array of the string ids of all connected clients.
+ */
+function connections() {
+ return Packages.net.appjet.ajstdlib.Comet.connections(appjet.context);
+}
+
+function getNumCurrentConnections() {
+ return Packages.net.appjet.ajstdlib.Comet.getNumCurrentConnections();
+}
+
+function isConnected(id) {
+ return Packages.net.appjet.ajstdlib.Comet.isConnected(id);
+}
+
+function disconnect(id) {
+ Packages.net.appjet.ajstdlib.Comet.disconnect(id);
+}
+
+function getAttribute(id, key) {
+ var ret = Packages.net.appjet.ajstdlib.Comet.getAttribute(appjet.context, id, key);
+ if (ret != null)
+ return String(ret);
+}
+
+function setAttribute(id, key, value) {
+ Packages.net.appjet.ajstdlib.Comet.setAttribute(appjet.context, id, key, value);
+}
+
+/**
+ * Sends a message to a particular client.
+ * @functionn
+ * @name sendMessage
+ * @param {string} id The <tt>id</tt> of the client to send to.
+ * @param {string} data The string data to send to the client.
+ */
+function sendMessage(id, msg) {
+ Packages.net.appjet.ajstdlib.Comet.write(id, msg);
+}
+
+function headInclude() { return '<script src="'+appjet.config.cometPrefix+'/js/client.js"></script>'; };
+function clientCode() {
+ return Packages.net.appjet.ajstdlib.Comet.getClientCode(appjet.context);
+};
+function clientMTime() {
+ return Packages.net.appjet.ajstdlib.Comet.getClientMTime(appjet.context);
+};
+
+/**
+ * WebSocket allows the client to connect to the server via a
+ * "bidirectional" channel. Messages sent by the server are received by
+ * the client without the need for additional connections or other delays.
+ * @class
+ * @name WebSocket
+ * @param {string} id The id to use for this client.
+ */
+
+/**
+ * Connects to the server using the id specified in the constructor.
+ * @methodOf WebSocket
+ * @name connect
+ */
diff --git a/infrastructure/framework-src/modules/dateutils.js b/infrastructure/framework-src/modules/dateutils.js
new file mode 100644
index 0000000..72e87c8
--- /dev/null
+++ b/infrastructure/framework-src/modules/dateutils.js
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function noon(date) {
+ return new Date(date.toString().split(' ').slice(0, 4).join(' ') + " 12:00");
+}
+
+function nextMonth(date) {
+ var newDate = new Date(date.getTime());
+ var newMonth = date.getMonth() + 1;
+ var newYear = date.getFullYear();
+ while (newMonth >= 12) {
+ newYear += 1;
+ newMonth -= 12;
+ }
+ newDate.setMonth(newMonth);
+ newDate.setFullYear(newYear);
+ return newDate;
+}
+
+var months =
+ ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"];
+
+var shortMonths = months.map(function(mon) { return mon.substr(0, 3); });
+
+var days =
+ ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+
+var shortDays = days.map(function(day) { return day.substr(0, 3); });
+
+function dateFormat(date, format) {
+ var formatter = new Packages.java.text.SimpleDateFormat(format);
+ return String(formatter.format(date).toString());
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/modules/dispatch.js b/infrastructure/framework-src/modules/dispatch.js
new file mode 100644
index 0000000..e7e3ef0
--- /dev/null
+++ b/infrastructure/framework-src/modules/dispatch.js
@@ -0,0 +1,149 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview Dispatching for dynamic pages and static files rendered from disk.
+ */
+
+import("jsutils.eachProperty");
+import("stringutils");
+
+jimport("java.lang.System.out.println");
+
+//----------------------------------------------------------------
+// Util
+//----------------------------------------------------------------
+
+function PrefixMatcher(p) {
+ var rs = p.replace(/([\[\]\^\$\\\.\*\+\?\(\)\{\}\|])/g, "\\$1");
+ var r = new RegExp('^' + rs + '(.*)$');
+ return function(path) {
+ return r.exec(path);
+ }
+}
+
+// Like PrefixMatcher, but makes trailing '/' optional, as in /ep/admin or /ep/admin/.
+// If trailing '/' is omitted, will redirect to same path with trailing /.
+function DirMatcher(p) {
+ if (p.substr(-1) == '/') {
+ p = p.substr(0, p.length-1);
+ }
+ var prefixMatcher = PrefixMatcher(p+'/');
+ return function(path) {
+ if (path == p) {
+ response.redirect(p+'/');
+ }
+ return prefixMatcher(path);
+ }
+}
+
+function _pathMatches(p, loc) {
+ // returns a regex-result kind of array with length >= 1, or null
+ if (typeof(loc) == 'string') {
+ return (p == loc) ? [loc] : null;
+ }
+ if (typeof(loc) == 'function') {
+ return (loc(p) || null);
+ }
+ if (loc.exec) { // regexp
+ var r = loc.exec(p);
+ return r || null;
+ }
+ throw new Error('Uknown type of location: '+loc);
+}
+
+//----------------------------------------------------------------
+// Dispatcher
+//----------------------------------------------------------------
+
+var Dispatcher = function() {
+ this._routes = []; // Array([location, (local file path or function)])
+};
+
+Dispatcher.prototype.addLocations = function(l) {
+ var that = this;
+ l.forEach(function(x) { that._routes.push(x); });
+};
+
+Dispatcher.prototype.dispatch = function() {
+ var p = request.path;
+ var served = false;
+
+ for (var i = 0; (i < this._routes.length) && (served == false); i++) {
+ var loc = this._routes[i][0];
+ var dst = this._routes[i][1];
+
+ var match = _pathMatches(p, loc);
+ if (match) {
+ if (typeof(dst) != 'function') {
+ throw new Error('dispatch only dispatches to functions, and this is not a function: '+typeof(dst));
+ }
+
+ // call dst(group1, group2, group3, ...)
+ served = dst.apply(this, Array.prototype.slice.call(match, 1));
+ }
+ };
+
+ return served;
+};
+
+//----------------------------------------------------------------
+// fdisp
+//----------------------------------------------------------------
+
+function forward(module) {
+ return function(name) {
+ if (name === "") {
+ name = "main";
+ }
+ if (name) {
+ name = name.replace(/\-/g, '_');
+ }
+ var onreq = module['onRequest'];
+ var f = module['render_'+name];
+ var fg = module['render_'+name+'_get'];
+ var fp = module['render_'+name+'_post'];
+
+ var served = false;
+
+ if (onreq) {
+ served = onreq(name);
+ }
+
+ if (served) {
+ return true;
+ }
+
+ var method = request.method;
+ if (method == "HEAD") {
+ method = "GET";
+ }
+
+ if (f) {
+ f();
+ served = true;
+ } else if (method == "GET" && fg) {
+ fg();
+ served = true;
+ } else if (method == "POST" && fp) {
+ fp();
+ served = true;
+ }
+
+ return served;
+ };
+}
+
diff --git a/infrastructure/framework-src/modules/ejs.js b/infrastructure/framework-src/modules/ejs.js
new file mode 100644
index 0000000..bf14ed3
--- /dev/null
+++ b/infrastructure/framework-src/modules/ejs.js
@@ -0,0 +1,471 @@
+/*--------------------------------------------------------------------------
+ * EJS - Embedded JavaScript, version 0.1.0
+ * Copyright (c) 2007 Edward Benson
+ * http://www.edwardbenson.com/projects/ejs
+ * ------------------------------------------------------------------------
+ *
+ * EJS is freely distributable under the terms of an MIT-style license.
+ *
+ * EJS is a client-side preprocessing engine written in and for JavaScript.
+ * If you have used PHP, ASP, JSP, or ERB then you get the idea: code embedded
+ * in <% // Code here %> tags will be executed, and code embedded in <%= .. %>
+ * tags will be evaluated and appended to the output.
+ *
+ * This is essentially a direct JavaScript port of Masatoshi Seki's erb.rb
+ * from the Ruby Core, though it contains a subset of ERB's functionality.
+ *
+ * Requirements:
+ * prototype.js
+ *
+ * Usage:
+ * // source should be either a string or a DOM node whose innerHTML
+ * // contains EJB source.
+ * var source = "<% var ejb="EJB"; %><h1>Hello, <%= ejb %>!</h1>";
+ * var compiler = new EjsCompiler(source);
+ * compiler.compile();
+ * var output = eval(compiler.out);
+ * alert(output); // -> "<h1>Hello, EJB!</h1>"
+ *
+ * For a demo: see demo.html
+ * For the license: see license.txt
+ *
+ *--------------------------------------------------------------------------*/
+
+import("jsutils.*");
+import("funhtml");
+
+jimport("java.lang.System.out.println");
+jimport("net.appjet.ajstdlib.execution.executeCodeInNewScope");
+
+/* Make a split function like Ruby's: "abc".split(/b/) -> ['a', 'b', 'c'] */
+function rsplit(x, regex) {
+ var item = x;
+ var result = regex.exec(item);
+ var retArr = new Array();
+ while (result != null)
+ {
+ var first_idx = result.index;
+ var last_idx = regex.lastIndex;
+ if ((first_idx) != 0)
+ {
+ var first_bit = item.substring(0,first_idx);
+ retArr.push(item.substring(0,first_idx));
+ item = item.slice(first_idx);
+ }
+ retArr.push(result[0]);
+ item = item.slice(result[0].length);
+ result = regex.exec(item);
+ }
+ if (! item == '')
+ {
+ retArr.push(item);
+ }
+ return retArr;
+};
+
+/* Chop is nice to have too */
+function chop(x) {
+ return x.substr(0, x.length - 1);
+}
+
+/* Adaptation from the Scanner of erb.rb */
+var EjsScanner = function(source, left, right) {
+ this.left_delimiter = left +'%'; //<%
+ this.right_delimiter = '%'+right; //>
+ this.double_left = left+'%%';
+ this.double_right = '%%'+right;
+ this.left_equal = left+'%=';
+ this.left_comment = left+'%#';
+ if(left=='[') {
+ this.SplitRegexp = /(\[%%)|(%%\])|(\[%=)|(\[%#)|(\[%)|(%\]\n)|(%\])|(\n)/;
+ }
+ else {
+ this.SplitRegexp = new RegExp('('+this.double_left+')|(%%'+this.double_right+')|('+this.left_equal+')|('+this.left_comment+')|('+this.left_delimiter+')|('+this.right_delimiter+'\n)|('+this.right_delimiter+')|(\n)')
+ }
+
+ this.source = source;
+ this.stag = null;
+ this.lines = 0;
+};
+EjsView = function(data) {
+ this.data = data;
+};
+EjsView.prototype.partial = function(options, data){
+ if(!data) data = this.data;
+ return new EJS(options).render(data);
+};
+
+EjsScanner.to_text = function(input){
+ if(input == null || input === undefined)
+ return '';
+ if(input instanceof Date)
+ return input.toDateString();
+ if(input.toString)
+ return input.toString();
+ return '';
+}
+
+EjsScanner.prototype = {
+
+ /* For each line, scan! */
+ scan: function(block) {
+ scanline = this.scanline;
+ regex = this.SplitRegexp;
+ if (! this.source == '')
+ {
+ var source_split = rsplit(this.source, /\n/);
+ for(var i=0; i<source_split.length; i++) {
+ var item = source_split[i];
+ this.scanline(item, regex, block);
+ }
+ }
+ },
+
+ /* For each token, block! */
+ scanline: function(line, regex, block) {
+ this.lines++;
+ var line_split = rsplit(line, regex);
+ for(var i=0; i<line_split.length; i++) {
+ var token = line_split[i];
+ if (token != null) {
+ try{
+ block(token, this);
+ }catch(e){
+ throw {type: 'EjsScanner', line: this.lines};
+ }
+ }
+ }
+ }
+};
+
+/* Adaptation from the Buffer of erb.rb */
+var EjsBuffer = function(pre_cmd, post_cmd) {
+ this.line = new Array();
+ this.script = "";
+ this.pre_cmd = pre_cmd;
+ this.post_cmd = post_cmd;
+
+ for (var i=0; i<this.pre_cmd.length; i++)
+ {
+ this.push(pre_cmd[i]);
+ }
+}
+EjsBuffer.prototype = {
+
+ push: function(cmd) {
+ this.line.push(cmd);
+ },
+
+ cr: function() {
+ this.script = this.script + this.line.join('; ');
+ this.line = new Array();
+ this.script = this.script + "\n";
+ },
+
+ close: function() {
+ if (this.line.length > 0)
+ {
+ for (var i=0; i<this.post_cmd.length; i++)
+ {
+ this.push(pre_cmd[i]);
+ }
+ this.script = this.script + this.line.join('; ');
+ line = null;
+ }
+ }
+
+};
+
+/* Adaptation from the Compiler of erb.rb */
+EjsCompiler = function(source, left) {
+ this.pre_cmd = ['var ___ejsO = "";'];
+ this.post_cmd = new Array();
+ this.source = ' ';
+ if (source != null)
+ {
+ if (typeof source == 'string')
+ {
+ source = source.replace(/\r\n/g, "\n");
+ source = source.replace(/\r/g, "\n");
+ this.source = source;
+ }
+ else if (source.innerHTML)
+ {
+ this.source = source.innerHTML;
+ }
+ if (typeof this.source != 'string')
+ {
+ this.source = "";
+ }
+ }
+ left = left || '<'
+ var right = '>'
+ switch(left) {
+ case '[':
+ right = ']'
+ break;
+ case '<':
+ break;
+ default:
+ throw left+' is not a supported deliminator'
+ break;
+ }
+ this.scanner = new EjsScanner(this.source, left, right);
+ this.out = '';
+}
+EjsCompiler.prototype = {
+ compile: function(options) {
+ options = options || {};
+ this.out = '';
+ var put_cmd = "___ejsO += ";
+ var insert_cmd = put_cmd;
+ var buff = new EjsBuffer(this.pre_cmd, this.post_cmd);
+ var content = '';
+ var clean = function(content)
+ {
+ content = content.replace(/\\/g, '\\\\');
+ content = content.replace(/\n/g, '\\n');
+ content = content.replace(/\"/g, '\\"');
+ return content;
+ };
+ this.scanner.scan(function(token, scanner) {
+ if (scanner.stag == null)
+ {
+ //alert(token+'|'+(token == "\n"))
+ switch(token) {
+ case '\n':
+ content = content + "\n";
+ buff.push(put_cmd + '"' + clean(content) + '";');
+ buff.cr();
+ content = '';
+ break;
+ case scanner.left_delimiter:
+ case scanner.left_equal:
+ case scanner.left_comment:
+ scanner.stag = token;
+ if (content.length > 0)
+ {
+ // Chould be content.dump in Ruby
+
+ buff.push(put_cmd + '"' + clean(content) + '"');
+ }
+ content = '';
+ break;
+ case scanner.double_left:
+ content = content + scanner.left_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ }
+ }
+ else {
+ switch(token) {
+ case scanner.right_delimiter:
+ switch(scanner.stag) {
+ case scanner.left_delimiter:
+ if (content[content.length - 1] == '\n')
+ {
+ content = chop(content);
+ buff.push(content);
+ buff.cr();
+ }
+ else {
+ buff.push(content);
+ }
+ break;
+ case scanner.left_equal:
+ buff.push(insert_cmd + "(EjsScanner.to_text(" + content + "))");
+ break;
+ }
+ scanner.stag = null;
+ content = '';
+ break;
+ case scanner.double_right:
+ content = content + scanner.right_delimiter;
+ break;
+ default:
+ content = content + token;
+ break;
+ }
+ }
+ });
+ if (content.length > 0)
+ {
+ // Chould be content.dump in Ruby
+ buff.push(put_cmd + '"' + clean(content) + '"');
+ }
+ buff.close();
+ this.out = buff.script + ";";
+ var to_be_evaled = [
+ 'var process = function(_CONTEXT,_VIEW) {',
+ ' with(_VIEW) {',
+ ' with (_CONTEXT) {',
+ this.out,
+ ' return ___ejsO;',
+ ' }',
+ ' }',
+ '};'
+ ].join('');
+ // make funhtml.* available in parent scope.
+ var parentScope = {};
+ parentScope.EjsScanner = EjsScanner;
+ keys(funhtml).forEach(function(k) {
+ parentScope[k] = funhtml[k];
+ });
+ var ret = executeCodeInNewScope(
+ parentScope,
+ to_be_evaled,
+ (options.name || "template"),
+ 1
+ );
+ this.process = ret.process;
+ }
+}
+
+
+//type, cache, folder
+EJS = function( options ){
+ this.set_options(options);
+
+ if(options.url){
+ var template = EJS.get(options.url, this.cache);
+ if (template) return template;
+ if (template == EJS.INVALID_PATH) return null;
+ this.text = EJS.request(options.url);
+ if(this.text == null){
+ //EJS.update(options.url, this.INVALID_PATH);
+ throw 'There is no template at '+options.url;
+ }
+ this.name = options.url;
+ }else if(options.element)
+ {
+ if(typeof options.element == 'string'){
+ var name = options.element;
+ options.element = document.getElementById( options.element );
+ if(options.element == null) throw name+'does not exist!';
+ }
+ if(options.element.value){
+ this.text = options.element.value;
+ }else{
+ this.text = options.element.innerHTML;
+ }
+ this.name = options.element.id;
+ this.type = '[';
+ }
+ var template = new EjsCompiler(this.text, this.type);
+
+ template.compile(options);
+
+
+ EJS.update(this.name, this);
+ this.template = template;
+};
+EJS.config = function(options){
+ EJS.cache = options.cache != null ? options.cache : EJS.cache;
+ EJS.type = options.type != null ? options.type : EJS.type;
+ var templates_directory = {}; //nice and private container
+
+ EJS.get = function(path, cache){
+ if(cache == false) return null;
+ if(templates_directory[path]) return templates_directory[path];
+ return null;
+ };
+
+ EJS.update = function(path, template) {
+ if(path == null) return;
+ templates_directory[path] = template;
+ };
+
+ EJS.INVALID_PATH = -1;
+
+
+};
+EJS.config( {cache: true, type: '<' } );
+
+EJS.prototype = {
+ render : function(object){
+ var v = new EjsView(object);
+ return this.template.process.call(v, object, v);
+ },
+ out : function(){
+ return this.template.out;
+ },
+ set_options : function(options){
+ this.type = options.type != null ? options.type : EJS.type;
+ this.cache = options.cache != null ? options.cache : EJS.cache;
+ this.text = options.text != null ? options.text : null;
+ this.name = options.name != null ? options.name : null;
+ },
+ // called without options, returns a function that takes the object
+ // called with options being a string, uses that as a url
+ // called with options as an object
+ update : function(element, options){
+ if(typeof element == 'string'){
+ element = document.getElementById(element);
+ }
+ if(options == null){
+ _template = this;
+ return function(object){
+ EJS.prototype.update.call(_template, element, object);
+ };
+ }
+ if(typeof options == 'string'){
+ params = {};
+ params.url = options;
+ _template = this;
+ params.onComplete = function(request){
+ var object = eval( request.responseText );
+ EJS.prototype.update.call(_template, element, object);
+ };
+ EJS.ajax_request(params);
+ }else
+ {
+ element.innerHTML = this.render(options);
+ }
+ }
+};
+
+ EJS.newRequest = function(){
+ var factories = [function() { return new ActiveXObject("Msxml2.XMLHTTP"); },function() { return new XMLHttpRequest(); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); }];
+ for(var i = 0; i < factories.length; i++) {
+ try {
+ var request = factories[i]();
+ if (request != null) return request;
+ }
+ catch(e) { continue;}
+ }
+ };
+
+ EJS.request = function(path){
+ var request = new EJS.newRequest();
+ request.open("GET", path, false);
+
+ try{request.send(null);}
+ catch(e){return null;}
+
+ if ( request.status == 404 || request.status == 2 ||(request.status == 0 && request.responseText == '') ) return null;
+
+ return request.responseText
+ };
+ EJS.ajax_request = function(params){
+ params.method = ( params.method ? params.method : 'GET');
+
+ var request = new EJS.newRequest();
+ request.onreadystatechange = function(){
+ if(request.readyState == 4){
+ if(request.status == 200){
+ params.onComplete(request);
+ }else
+ {
+ params.onComplete(request);
+ }
+ }
+ };
+ request.open(params.method, params.url);
+ request.send(null);
+ };
+
+//}
+
+
diff --git a/infrastructure/framework-src/modules/email.js b/infrastructure/framework-src/modules/email.js
new file mode 100644
index 0000000..2d81dc3
--- /dev/null
+++ b/infrastructure/framework-src/modules/email.js
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// import("jsutils.eachProperty");
+//
+// function _paramObjectToParamArray(params, enc) {
+// var pa = [];
+// eachProperty(params, function(k, v) {
+// pa.push(enc ? encodeURIComponent(k.toString()) : k.toString());
+// pa.push(enc ? encodeURIComponent(v.toString()) : v.toString());
+// });
+// return pa;
+// }
+
+/**
+ * Simple way to send an email to a single recipient. Emails will have a
+ * "from" address of <code>noreply@{appjet.appName}.{appjet.mainDomain}</code>.
+ *
+ * Sending is limited to 100 emails per developer account per day. However,
+ * emails sent to the address on file for the app's owner are not counted
+ * toward this limit.
+ *
+ * @example
+result = sendEmail("noone@example.com", "Test Subject",
+ "Greetings!", {"Reply-To": "sender@example.com"});
+ *
+ * @param {strings} toAddress An array of email address strings, or a single string.
+ * @param {string} subject The message subject.
+ * @param {string} body The message body.
+ * @param {object} [headers] Optional headers to include in the
+ * message, as a dictionary of {name: value} entries.
+ */
+function sendEmail(toAddress, fromAddress, subject, headers, body) {
+ if (typeof(toAddress) == 'string')
+ toAddress = [toAddress];
+ var ret = Packages.net.appjet.ajstdlib.email.sendEmail(toAddress, fromAddress, subject, headers, body);
+ if (ret != "")
+ throw new Error(ret);
+}
+
diff --git a/infrastructure/framework-src/modules/exceptionutils.js b/infrastructure/framework-src/modules/exceptionutils.js
new file mode 100644
index 0000000..b572a3a
--- /dev/null
+++ b/infrastructure/framework-src/modules/exceptionutils.js
@@ -0,0 +1,210 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("ejs.EJS");
+import("funhtml.*");
+import("jsutils.{scalaF0,scalaF1}");
+import("stringutils.{toHTML,sprintf}");
+
+function _getException(ex) {
+ if (ex instanceof java.lang.Throwable) {
+ return new net.appjet.bodylock.JSRuntimeException(ex.getMessage(), ex);
+ } else if (ex.javaException) {
+ return new net.appjet.bodylock.JSRuntimeException(ex.javaException.getMessage(), ex.javaException);
+ } else if (ex.rhinoException) {
+ return new net.appjet.bodylock.JSRuntimeException(ex.rhinoException.getMessage(), ex.rhinoException);
+ } else {
+ return ex;
+ }
+}
+
+function _convertStackFrameToTable(id, frame) {
+ var r = frame.errorContext(4);
+ var out = [];
+ var t = TABLE({className: "codecontext"});
+ var counter = r._1();
+ r._3().foreach(scalaF1(function(s) {
+ var row = TR(TD({className: "linecell"}, counter++), TD(String(s)));
+ if (counter-1 == frame.errorLine())
+ row[1].attribs['class'] = "offendingline";
+ t.push(row);
+ }));
+ if (id != 0)
+ out.push(DIV({className: "errorframe",
+ onclick: "toggleFrameView('"+id+"')"},
+ IMG({className: "zippy", style: "margin-right: 0.5em;", align: "top", src: "http://appjet.com/img/open-arrow.png", id: "image"+id}),
+ SPAN({className: "errordetail"}, "...was called from "+frame.name()+ " (line "+frame.errorLine()+"):"),
+ SPAN({className: "sourceline"}, " "+frame.errorContext(0)._3().first())));
+ out.push(DIV({id: 'frame'+id, style: (id == 0 ? "" : "display: none;")}, t));
+ return out.map(function(tag) { return toHTML(tag); }).join("");
+}
+
+function getStackTraceHTML(ex) {
+ ex = _getException(ex);
+ if (ex.frames().isEmpty())
+ return "No stack trace available.";
+ var out = [];
+ var counter = 0;
+ var firstFrame = ex.frames().first();
+ out.push(toHTML(DIV({id: "errortitle"}, "Error in "+firstFrame.name())));
+ out.push(toHTML(DIV({id: "errormessage"}, ""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")")));
+ ex.frames().foreach(scalaF1(function(frame) {
+ out.push(_convertStackFrameToTable(counter++, frame));
+ }));
+ return out.join("");
+}
+
+function getStackTraceFullpage(ex) {
+ var tmpl = new EJS({text: _tmpl});
+ return tmpl.render({trace: getStackTraceHTML(ex)});
+}
+
+function getStackTracePlain(ex) {
+ ex = _getException(ex);
+ if (ex.frames().isEmpty()) {
+ var cause = ex.cause();
+ var sw = new java.io.StringWriter();
+ cause.printStackTrace(new java.io.PrintWriter(sw));
+ return sw.toString();
+ }
+ var out = [];
+ var firstFrame = ex.frames().first();
+ out.push("Error in "+firstFrame.name());
+ out.push(""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")");
+ var counter = 0;
+ ex.frames().foreach(scalaF1(function(frame) {
+ if (counter++ > 0) {
+ out.push("");
+ out.push("...was called from "+frame.name()+" (line "+frame.errorLine()+"): "+frame.errorContext(0)._3().first());
+ }
+ var r = frame.errorContext(4);
+ var c2 = r._1();
+ r._3().foreach(scalaF1(function(s) {
+ var pre = " ";
+ if (c2 == frame.errorLine())
+ pre = ">";
+ out.push(sprintf("%s %4s | %s", pre, ""+c2, s));
+ c2++;
+ }));
+ }));
+ return out.join("\n");
+}
+
+/* template follows */
+var _tmpl = """<!DOCTYPE HTML PUBLIC
+ "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <title>AppJet Error</title>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <script type="text/javascript" src="http://appjet.com/js/343607636acfee88faa2b638330a3370/jquery-1.2.6.js"></script>
+ <script type="text/javascript">
+function toggleFrameView(frameId) {
+ var hidden = $("#frame"+frameId+":hidden")
+ var visible = $("#frame"+frameId+":visible")
+ if (hidden.length > 0) {
+ hidden.show("normal")
+ $("#image"+frameId).attr("src", "http://appjet.com/img/close-arrow.png")
+ } else {
+ visible.hide("normal")
+ $("#image"+frameId).attr("src", "http://appjet.com/img/open-arrow.png")
+ }
+}
+
+function toggleErrorView() {
+ var hidden = $("#hiddentrace:hidden");
+ var visible = $("#hiddentrace:visible");
+ if (hidden.length > 0) {
+ hidden.slideDown("normal");
+ } else {
+ visible.slideUp("normal");
+ }
+ return false;
+}
+
+function load() {
+ $(".zippy").attr("src", "http://appjet.com/img/open-arrow.png")
+}
+</script>
+<style>
+body {
+ font-family: verdana, helvetica, sans-serif;
+ font-size: 60%;
+ margin: 1em;
+}
+#header { border-bottom: 1px solid red; margin-bottom: 0.8em; }
+#errortitle { font-weight: bold; font-size: 1.6em; margin-bottom: 0.76em;}
+#errormessage { font-size: 1.4em; margin-bottom: 1.0em}
+#errorexplanation {
+ background-color: #ffd; margin: 1em; padding: 0 1em;
+ border: 1px solid #cc9;
+ line-height: 150%;
+}
+#errorexplanation ul, #errorexplanation li { margin: 0; padding: 0; }
+#errorexplanation ul { padding-left: 2em; }
+#errorexplanation { font-size: 9pt; }
+#errorexplanation code { font-size: 10pt; }
+#errorexplanation code { padding: 1px; background: #ddc; margin: 0 5px;
+ white-space:nowrap; }
+#errorexplanation code.quote { background: #fcc; }
+#errorexplanation p, #errorexplanation li { margin: 1em 0 }
+#frame0 { margin-top: 2.0em; }
+.errorframe {
+ margin-bottom: 0.5em;
+ margin-top: 1em;
+ cursor: pointer;
+ color: blue;
+}
+.errordetail {
+ text-decoration: underline;
+}
+.errorframe:hover {
+ color: #c47827;
+}
+.sourceline {
+ font-size: 1.4em;
+ color: black;
+ font-family: monospace;
+}
+#statuscode {
+ float: right;
+ font-size: 2.4em;
+ font-weight: bold;
+}
+.codecontext {
+ border: 1px solid black;
+ font-family: monospace;
+ font-size: 1.4em;
+}
+.codecontext td { padding: 0.1em 0.3em; }
+.codecontext .linecell { border-right: 1px solid #888; }
+.codecontext .offendingline { background-color: #ffcccc; }
+.errotemplate .codecontext .linecell { border-right: 1px solid black; }
+pre {
+ margin: 0px;
+ padding: 0px;
+ border: 0px;
+}
+
+#errorexplanation tt { font-size: 85%; color: #666; }
+</style>
+</head>
+<body onload="load()">
+<%= trace %>
+</body>
+</html>"""
diff --git a/infrastructure/framework-src/modules/execution.js b/infrastructure/framework-src/modules/execution.js
new file mode 100644
index 0000000..1cec418
--- /dev/null
+++ b/infrastructure/framework-src/modules/execution.js
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("jsutils.{scalaF0,scalaF1}");
+
+/**
+ * Asynchronously call a function as soon as the current request completes.
+ **/
+function async(f) {
+ Packages.net.appjet.ajstdlib.execution.runAsync(appjet.context, f);
+}
+
+function initTaskThreadPool(name, poolSize) {
+ Packages.net.appjet.ajstdlib.execution.createNamedTaskThreadPool(name, poolSize);
+}
+
+function scheduleTask(poolName, taskName, delayMillis, args) {
+ return Packages.net.appjet.ajstdlib.execution.scheduleTaskInPool(poolName, taskName, delayMillis, args);
+}
+
+function shutdownAndWaitOnTaskThreadPool(poolName, timeoutMillis) {
+ return Packages.net.appjet.ajstdlib.execution.shutdownAndWaitOnTaskThreadPool(poolName, timeoutMillis);
+}
+
+function fancyAssEval(initCode, mainCode) {
+ function init(runner) {
+ Packages.net.appjet.bodylock.BodyLock.evaluateString(
+ runner.globalScope(),
+ initCode,
+ "eval'd code imports",
+ 1);
+ }
+ var runner = Packages.net.appjet.oui.ScopeReuseManager.getEmpty(scalaF1(init));
+ var ec = new Packages.net.appjet.oui.ExecutionContext(
+ new Packages.net.appjet.oui.RequestWrapper(request.underlying),
+ null, runner);
+ return Packages.net.appjet.oui.ExecutionContextUtils.withContext(ec,
+ scalaF0(function() {
+ return Packages.net.appjet.bodylock.BodyLock.evaluateString(
+ runner.globalScope(),
+ mainCode,
+ "eval'd code main",
+ 1);
+ }));
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/modules/fastJSON.js b/infrastructure/framework-src/modules/fastJSON.js
new file mode 100644
index 0000000..3198b96
--- /dev/null
+++ b/infrastructure/framework-src/modules/fastJSON.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+jimport("net.appjet.oui.FastJSON");
+jimport("java.lang.System.out.println");
+
+function stringify(x) {
+ return String(FastJSON.stringify(x));
+}
+
+function parse(x) {
+ return FastJSON.parse(appjet.context, x);
+}
+
diff --git a/infrastructure/framework-src/modules/faststatic.js b/infrastructure/framework-src/modules/faststatic.js
new file mode 100644
index 0000000..5cca676
--- /dev/null
+++ b/infrastructure/framework-src/modules/faststatic.js
@@ -0,0 +1,318 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview serving static files, including js and css, and cacheing
+ * and minifying.
+ *
+ * Terminology Note:
+ * "path" is confusing because paths can be part of URLs and part
+ * of filesystem paths, and static files have both types of paths
+ * associated with them. Therefore, in this module:
+ *
+ * LOCALDIR or LOCALFILE refers to directories or files on the filesystem.
+ *
+ * HREF is used to describe things that go in a URL.
+ */
+
+import("fileutils.{readFile,readFileBytes}");
+import("yuicompressor");
+import("stringutils");
+import("varz");
+import("ejs.EJS");
+
+jimport("java.lang.System.out.println");
+
+//----------------------------------------------------------------
+// Content Type Guessing
+//----------------------------------------------------------------
+
+var _contentTypes = {
+ 'gif': 'image/gif',
+ 'png': 'image/png',
+ 'jpg': 'image/jpeg',
+ 'jpeg': 'image/jpeg',
+ 'css': 'text/css',
+ 'js': 'application/x-javascript',
+ 'txt': 'text/plain',
+ 'html': 'text/html; charset=utf-8',
+ 'ico': 'image/x-icon',
+ 'swf': 'application/x-shockwave-flash',
+ 'zip': 'application/zip',
+ 'xml': 'application/xml'
+};
+
+var _gzipableTypes = {
+ 'text/css': true,
+ 'application/x-javascript': true,
+ 'text/html; charset=utf-8': true
+};
+
+function _guessContentType(path) {
+ var ext = path.split('.').pop().toLowerCase();
+ return _contentTypes[ext] || 'text/plain';
+}
+
+//----------------------------------------------------------------
+
+function _getCache(name) {
+ var m = 'faststatic';
+ if (!appjet.cache[m]) {
+ appjet.cache[m] = {};
+ }
+ var c = appjet.cache[m];
+ if (!c[name]) {
+ c[name] = {};
+ }
+ return c[name];
+}
+
+var _mtimeCheckInterval = 5000; // 5 seconds
+
+function _getMTime(f) {
+ var mcache = _getCache('mtimes');
+ var now = +(new Date);
+ if (appjet.config.devMode ||
+ !(mcache[f] && (now - mcache[f].lastCheck < _mtimeCheckInterval))) {
+ var jfile = new net.appjet.oui.JarVirtualFile(f);
+ if (jfile.exists() && !jfile.isDirectory()) {
+ mcache[f] = {
+ lastCheck: now,
+ mtime: jfile.lastModified()
+ };
+ } else {
+ mcache[f] = null;
+ }
+ }
+ if (mcache[f]) {
+ return +mcache[f].mtime;
+ } else {
+ return null;
+ }
+}
+
+function _wrapFile(localFile) {
+ return {
+ getPath: function() { return localFile; },
+ getMTime: function() { return _getMTime(localFile); },
+ getContents: function() { return _readFileAndProcess(localFile, 'string'); }
+ };
+}
+
+function _readFileAndProcess(fileName, type) {
+ if (fileName.slice(-8) == "_ejs.css") {
+ // run CSS through EJS
+ var template = readFile(fileName);
+ var ejs = new EJS({text:template, name:fileName});
+ var resultString = ejs.render({});
+ if (type == 'bytes') {
+ return new java.lang.String(resultString).getBytes("UTF-8");
+ }
+ else {
+ return resultString;
+ }
+ }
+ else if (type == 'string') {
+ return readFile(fileName);
+ }
+ else if (type == 'bytes') {
+ return readFileBytes(fileName);
+ }
+}
+
+function _cachedFileBytes(f) {
+ var mtime = _getMTime(f);
+ if (!mtime) { return null; }
+ var fcache = _getCache('file-bytes-cache');
+ if (!(fcache[f] && (fcache[f].mtime == mtime))) {
+ varz.incrementInt("faststatic-file-bytes-cache-miss");
+ var bytes = _readFileAndProcess(f, 'bytes');
+ if (bytes) {
+ fcache[f] = {mtime: mtime, bytes: bytes};
+ };
+ }
+ if (fcache[f] && fcache[f].bytes) {
+ return fcache[f].bytes;
+ } else {
+ return null;
+ }
+}
+
+function _shouldGzip(contentType) {
+ var userAgent = request.headers["User-Agent"];
+ if (! userAgent) return false;
+ if (! (/Firefox/.test(userAgent) || /webkit/i.test(userAgent))) return false;
+ if (! _gzipableTypes[contentType]) return false;
+
+ return request.acceptsGzip;
+}
+
+function _getCachedGzip(original, key) {
+ var c = _getCache("gzipped");
+ if (! c[key] || ! java.util.Arrays.equals(c[key].original, original)) {
+ c[key] = {original: original,
+ gzip: stringutils.gzip(original)};
+ }
+ return c[key].gzip;
+}
+
+function _setGzipHeader() {
+ response.setHeader("Content-Encoding", "gzip");
+}
+
+//----------------------------------------------------------------
+
+/**
+ * Function for serving a single static file.
+ */
+function singleFileServer(localPath, opts) {
+ var contentType = _guessContentType(localPath);
+
+ return function() {
+ (opts.cache ? response.alwaysCache() : response.neverCache());
+ response.setContentType(contentType);
+ var bytes = _cachedFileBytes(localPath);
+ if (bytes) {
+ if (_shouldGzip(contentType)) {
+ bytes = _getCachedGzip(bytes, "file:"+localPath);
+ _setGzipHeader();
+ }
+ response.writeBytes(bytes);
+ return true;
+ } else {
+ return false;
+ }
+ };
+}
+
+/**
+ * valid opts:
+ * alwaysCache: default false
+ */
+function directoryServer(localDir, opts) {
+ if (stringutils.endsWith(localDir, "/")) {
+ localDir = localDir.substr(0, localDir.length-1);
+ }
+ return function(relpath) {
+ if (stringutils.startsWith(relpath, "/")) {
+ relpath = relpath.substr(1);
+ }
+ if (relpath.indexOf('..') != -1) {
+ response.forbid();
+ }
+ (opts.cache ? response.alwaysCache() : response.neverCache());
+ var contentType = _guessContentType(relpath);
+ response.setContentType(contentType);
+ var fullPath = localDir + "/" + relpath;
+ var bytes = _cachedFileBytes(fullPath);
+
+ if (bytes) {
+ if (_shouldGzip(contentType)) {
+ bytes = _getCachedGzip(bytes, "file:"+fullPath);
+ _setGzipHeader();
+ }
+ response.writeBytes(bytes);
+ return true;
+ } else {
+ return false;
+ }
+ };
+}
+
+/**
+ * Serves cat files, which are concatenated versions of many files.
+ */
+function compressedFileServer(opts) {
+ var cfcache = _getCache('compressed-files');
+ return function() {
+ var key = request.path.split('/').slice(-1)[0];
+ var contentType = _guessContentType(request.path);
+ response.setContentType(contentType);
+ response.alwaysCache();
+ var data = cfcache[key];
+ if (data) {
+ if (_shouldGzip(contentType)) {
+ data = _getCachedGzip((new java.lang.String(data)).getBytes(response.getCharacterEncoding()), "comp:"+key);
+ _setGzipHeader();
+ response.writeBytes(data);
+ } else {
+ response.write(data);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ };
+}
+
+function getCompressedFilesKey(type, baseLocalDir, localFileList) {
+ if (stringutils.endsWith(baseLocalDir, '/')) {
+ baseLocalDir = baseLocalDir.substr(0, baseLocalDir.length-1);
+ }
+
+ var fileList = [];
+ // convert passed-in file list into list of our file objects
+ localFileList.forEach(function(f) {
+ if (typeof(f) == 'string') {
+ fileList.push(_wrapFile(baseLocalDir+'/'+f));
+ } else {
+ fileList.push(f);
+ }
+ });
+
+ // have we seen this exact fileset before?
+ var fsId = fileList.map(function(f) { return f.getPath(); }).join('|');
+ var fsMTime = Math.max.apply(this,
+ fileList.map(function(f) { return f.getMTime(); }));
+
+ var kdcache = _getCache('fileset-keydata-cache');
+ if (!(kdcache[fsId] && (kdcache[fsId].mtime == fsMTime))) {
+ //println("cache miss for fileset: "+fsId);
+ //println("compressing fileset...");
+ kdcache[fsId] = {
+ mtime: fsMTime,
+ keyString: _compressFilesAndMakeKey(type, fileList)
+ };
+ }
+ return kdcache[fsId].keyString;
+}
+
+function _compressFilesAndMakeKey(type, fileList) {
+ function _compress(s) {
+ if (type == 'css') {
+ varz.incrementInt("faststatic-yuicompressor-compressCSS");
+ return yuicompressor.compressCSS(s);
+ } else if (type == 'js') {
+ varz.incrementInt("faststatic-yuicompressor-compressJS");
+ return yuicompressor.compressJS(s);
+ } else {
+ throw Error('Dont know how to compress this filetype: '+type);
+ }
+ }
+
+ var fullstr = "";
+ fileList.forEach(function(f) {
+ fullstr += _compress(f.getContents());
+ });
+
+ fullstr = _compress(fullstr);
+
+ var key = stringutils.md5(fullstr) + '.' + type;
+ var cfcache = _getCache('compressed-files');
+ cfcache[key] = fullstr;
+ return key;
+}
+
diff --git a/infrastructure/framework-src/modules/fileutils.js b/infrastructure/framework-src/modules/fileutils.js
new file mode 100644
index 0000000..aaf12e2
--- /dev/null
+++ b/infrastructure/framework-src/modules/fileutils.js
@@ -0,0 +1,108 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @fileOverview misc file functions */
+
+jimport("java.io.File",
+ "java.io.DataInputStream",
+ "java.io.FileInputStream",
+ "java.lang.reflect.Array",
+ "java.lang.Byte",
+ "java.io.FileReader",
+ "java.io.BufferedReader",
+ "net.appjet.oui.JarVirtualFile");
+
+function readFileBytes(path) {
+ var jfile = new JarVirtualFile(path);
+ if (!jfile.exists() || jfile.isDirectory()) {
+ throw 'Not a file: '+path;
+ }
+ return net.appjet.common.util.BetterFile.getStreamBytes(jfile.openStream());
+}
+
+function readFile(path) {
+ var bytes = readFileBytes(path);
+ if (bytes !== null) {
+ return String(new java.lang.String(bytes));
+ } else {
+ return null;
+ }
+}
+
+function fileLastModified(path) {
+ var jfile = new JarVirtualFile(path);
+ if (!jfile.exists()) {
+ throw "Not a file: "+path;
+ }
+ return jfile.lastModified();
+}
+
+//----------------------------------------------------------------
+// real files
+//----------------------------------------------------------------
+
+function readRealFileBytes(path) {
+ var jfile = new File(path);
+ if (!jfile.exists() || jfile.isDirectory()) {
+ throw 'Not a real file: '+path;
+ }
+ var jdata = new DataInputStream(new FileInputStream(jfile));
+ var size = jfile.length();
+ var bytes = Array.newInstance(Byte.TYPE, size);
+ jdata.read(bytes, 0, size);
+ jdata.close();
+ return bytes;
+}
+
+function readRealFile(path) {
+ var bytes = readRealFileBytes(path);
+ if (bytes !== null) {
+ return String(new java.lang.String(bytes));
+ } else {
+ return null;
+ }
+}
+
+function writeRealFile(path, data) {
+ var jf = new Packages.java.io.File(path);
+ var fw = new Packages.java.io.FileWriter(jf);
+ fw.write(data);
+ fw.flush();
+ fw.close();
+}
+
+
+function eachFileLine(file, fn) {
+ var iter = fileLineIterator(file);
+ while (iter.hasNext) {
+ fn(iter.next);
+ }
+}
+
+function fileLineIterator(file) {
+ var reader = new BufferedReader(new FileReader(file));
+ var nextLine = reader.readLine();
+ return {
+ get hasNext() { return nextLine !== null },
+ get next() {
+ var curLine = nextLine;
+ if (this.hasNext) {
+ nextLine = reader.readLine();
+ }
+ return curLine;
+ }
+ };
+}
diff --git a/infrastructure/framework-src/modules/funhtml.js b/infrastructure/framework-src/modules/funhtml.js
new file mode 100644
index 0000000..c27b667
--- /dev/null
+++ b/infrastructure/framework-src/modules/funhtml.js
@@ -0,0 +1,158 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview Functional HTML tag writing.<br/>
+ *
+ * <p>This library allows you to write HTML in the form of nested function
+ * calls. By default, a function is predefined for each tag, with the function
+ * name being in all caps. A dictionary of HTML attributes can optionally be
+ * passed as a first argument to a tag; other arguments become child tags.
+ * Attribute names that conflict with JavaScript
+ * keywords have been renamed; use "className" in place of "class" and
+ * "htmlFor" in place of "for".</p>
+ *
+ * <p>Tag objects inherit from Array, so array methods can be used to
+ * manipulate a tag's list of child tags.</p>
+ *
+ * @example
+print(P({id:"sec3"},"Tags are ",B(I("crazy"))," awesome."));
+ */
+
+import("jsutils.eachProperty");
+import("stringutils");
+import("stringutils.toHTML");
+
+function html(x) {
+ // call out to stringutils.html().
+ var args = Array.prototype.slice.call(arguments);
+ return stringutils.html.apply(this, args);
+};
+
+function toHTML(x) {
+ // call out to stringutils.toHTML().
+ var args = Array.prototype.slice.call(arguments);
+ return stringutils.toHTML.apply(this, args)
+};
+
+//----------------------------------------------------------------
+// tags.
+//----------------------------------------------------------------
+
+var _neverSingletones = {
+ 'TEXTAREA': true,
+ 'SCRIPT': true,
+ 'DIV': true,
+ 'IFRAME': true,
+ 'UL': true,
+ 'TABLE': true
+};
+
+/**
+ * Imports a specified list of tags. All HTML tags are automatically imported
+ * by default, but you may wish to use the tag library to write other kinds
+ * of mark-up. For each tag you want to import, pass in the name (including
+ * any punctuation) with the (upper/lower) case you want to use for the function
+ * (traditionally all uppercase). The function name will have punctuation
+ * replaced with underscores, and the printed tag will be all lowercase.
+ *
+ * @param {object} scopeObj where to define the tags; to define in the global scope, pass <code>this</code> from the top level (not from inside a function)
+ * @param {array} tagArray an array of strings, the tags to import
+ * @example
+importTags(this, ["MEDIA:TITLE"]);
+print(MEDIA_TITLE({type:"html"}, "funny pictures"));
+// prints &lt;media:title type="html"&gt;funny pictures&lt;/media:title&gt;
+ */
+function _importTags(scopeObj, tagArray) {
+ tagArray.forEach(function(arg) {
+ var funcName = arg.replace(/:/g, "_").replace(/-/g, "_");
+ var tagName = arg.toLowerCase();
+ scopeObj[funcName] = function() {
+ var tag = [];
+ tag.name = tagName;
+ var contents = Array.prototype.slice.call(arguments);
+ if (contents.length > 0) {
+ if (contents[0] &&
+ (! contents[0].toHTML) &&
+ ((typeof contents[0]) == "object") &&
+ (! Array.prototype.isPrototypeOf(contents[0])) &&
+ (! Date.prototype.isPrototypeOf(contents[0]))) {
+ // first arg is attributes
+ tag.attribs = contents[0];
+ contents.shift();
+ }
+ else {
+ tag.attribs = {};
+ }
+ contents.forEach(function (content) {
+ tag.push(content);
+ });
+ }
+ else {
+ tag.attribs = {};
+ }
+ tag.toString = function() { return this.toHTML(); }; // this behavior is relied on
+ tag.toHTML = function() {
+ var t = this;
+ var result = [];
+ result.add = function(x) { this.push(x); return this; };
+ result.add('<').add(t.name);
+ if (t.attribs) {
+ eachProperty(t.attribs, function(k,v) {
+ if (k == "className") k = "class";
+ if (k == "htmlFor") k = "for";
+ if (!(v === undefined)) {
+ // escape quotes and newlines in values
+ v = String(v).replace(/\"/g, '\\"').replace(/\n/g, '\\n');
+ result.add(' ').add(k).add('="').add(v).add('"');
+ }
+ });
+ }
+ if ((t.length < 1) && (!(t.name.toUpperCase() in _neverSingletones))) {
+ result.add(' />');
+ }
+ else {
+ result.add('>');
+ t.forEach(function (x) {
+ result.add(toHTML(x));
+ });
+ result.add('</').add(t.name).add('\n>');
+ }
+ return result.join("");
+ };
+ return tag;
+ };
+ });
+}
+
+var _html_tags =
+ ["A", "ABBR", "ACRONYM", "ADDRESS", "APPLET", "AREA", "B",
+ "BASE", "BASEFONT", "BDO", "BIG", "BLOCKQUOTE", "BODY",
+ "BR", "BUTTON", "CAPTION", "CENTER", "CITE", "CODE", "COL",
+ "COLGROUP", "DD", "DEL", "DIR", "DIV", "DFN", "DL", "DT",
+ "EM", "FIELDSET", "FONT", "FORM", "FRAME", "FRAMESET",
+ "H1", "H2", "H3", "H4", "H5", "H6",
+ "HEAD", "HR", "HTML", "I", "IFRAME", "IMG", "INPUT",
+ "INS", "ISINDEX", "KBD", "LABEL", "LEGEND", "LI", "LINK",
+ "MAP", "MENU", "META", "NOFRAMES", "NOSCRIPT", "OBJECT",
+ "OL", "OPTGROUP", "OPTION", "P", "PARAM", "PRE", "Q", "S",
+ "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRIKE",
+ "STRONG", "STYLE", "SUB", "SUP", "TABLE", "TBODY", "TD",
+ "TEXTAREA", "TFOOT", "TH", "THEAD", "TITLE", "TR", "TT",
+ "U", "UL", "VAR", "XMP"];
+
+_importTags(this, _html_tags);
+
diff --git a/infrastructure/framework-src/modules/global/appjet.js b/infrastructure/framework-src/modules/global/appjet.js
new file mode 100644
index 0000000..135ac44
--- /dev/null
+++ b/infrastructure/framework-src/modules/global/appjet.js
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("jsutils.scalaF0");
+
+//----------------------------------------------------------------
+// global static "appjet" object
+//----------------------------------------------------------------
+
+/**
+ * @fileOverview The global appjet object contains access to the AppJet runtime,
+ * app meta-data, and other information.
+ */
+var appjet = {
+
+/**
+ * This is the interface to the execution context. You probably won't need
+ * to use this, but if you do, be careful!
+ * @type object
+ */
+get context() {
+ return net.appjet.oui.ExecutionContextUtils.currentContext();
+},
+
+get executionId() {
+ return this.context.executionId();
+},
+
+// /**
+// * Holds the current request's requestId. (These IDs may be reused!)
+// * @type String
+// */
+// get requestId() {
+// return this.context.requestId();
+// },
+
+/**
+ * Volatile cache that persists between requests. (JavaScript object).
+ */
+get cache() {
+ return Packages.net.appjet.ajstdlib.ajstdlib.attributes()
+ .getOrElseUpdate("cache", scalaF0({}));
+},
+
+get cacheRoot() {
+ return function(name) {
+ return Packages.net.appjet.ajstdlib.ajstdlib.attributes()
+ .getOrElseUpdate("cache-"+(name?name:""), scalaF0({}));
+ };
+},
+
+/**
+ * A global lock for this app (ReentrantLock object).
+ */
+get globalLock() {
+ return net.appjet.ajstdlib.ajstdlib.globalLock();
+},
+
+/**
+ * Per-request cache, cleared between requests.
+ */
+get requestCache() {
+ return this.context.attributes().getOrElseUpdate("requestCache", scalaF0({}))
+},
+
+/**
+ * Per-scope cache, persisted in this "server" instance.
+ */
+get scopeCache() {
+ return this.context.runner().attributes().getOrElseUpdate("scopeCache", scalaF0({}));
+},
+
+/**
+ * config params for app.
+ */
+get config() {
+ return Packages.net.appjet.oui.config.configObject(this.context.runner().globalScope());
+},
+
+/**
+ * tells appjet not to re-use this "scope"/"server"
+ */
+get retireScope() {
+ return function() { this.context.runner().reuseOk_$eq(false); }
+},
+
+/**
+ * How many milliseconds the server has been running for.
+ */
+get uptime() {
+ return Date.now() - Packages.net.appjet.oui.main.startTime().getTime();
+}
+
+}; // end: var appjet = {... \ No newline at end of file
diff --git a/infrastructure/framework-src/modules/global/request.js b/infrastructure/framework-src/modules/global/request.js
new file mode 100644
index 0000000..a4327f9
--- /dev/null
+++ b/infrastructure/framework-src/modules/global/request.js
@@ -0,0 +1,312 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("stringutils.trim");
+import("jsutils.scalaF0")
+
+function _cx() { return appjet.context };
+
+function _addIfNotPresent(obj, key, value) {
+ if (!(key in obj)) obj[key] = value;
+}
+
+var request = {
+
+get isDefined() {
+ return (
+ _cx() != null &&
+ _cx().request() != null &&
+ (! _cx().request().isFake()) &&
+ _cx().request().req() != null
+ );
+},
+
+get cache() {
+ var req = _cx().request().req();
+ if (req.getAttribute("jsCache") == null) {
+ req.setAttribute("jsCache", {});
+ }
+ return req.getAttribute("jsCache");
+},
+
+get continuation() {
+ if (this.isDefined) {
+ var c = Packages.net.appjet.ajstdlib.execution.getContinuation(_cx());
+ var u = this.underlying;
+ return {
+ suspend: function(timeout) {
+ return Packages.net.appjet.ajstdlib.execution.sync(
+ u, scalaF0(function() { return c.suspend(timeout); }));
+ },
+ resume: function() {
+ Packages.net.appjet.ajstdlib.execution.sync(
+ u, scalaF0(function() { c.resume(); }))
+ }
+ }
+ }
+},
+
+get underlying() {
+ if (this.isDefined) {
+ return _cx().request().req();
+ }
+},
+
+/**
+ * The request path following the hostname. For example, if the user
+ * is visiting yourapp.appjet.net/foo, then this will be set to
+ * "/foo".
+ *
+ * This does not include CGI parameters or the domain name, and always
+ * begins with a "/".
+ *
+ * @type string
+ */
+get path() {
+ if (this.isDefined) {
+ return String(_cx().request().path());
+ }
+},
+
+/**
+ * The value request query string.
+ *
+ * For example, if the user visits "yourapp.appjet.net/foo?id=20", then
+ * query will be "id=20".
+ *
+ * @type string
+ */
+get query() {
+ if (this.isDefined) {
+ if (_cx().request().query() != null) {
+ return _cx().request().query();
+ }
+ }
+},
+
+/**
+ * The content of a POST request. Retrieving this value may interfere
+ * with the ability to get post request parameters sent in the body of
+ * a request via the "params" property. Use with care.
+ *
+ * @type string
+ */
+get content() {
+ if (this.isDefined) {
+ if (_cx().request().content() != null) {
+ return _cx().request().content();
+ }
+ }
+},
+
+/**
+ * Either "GET" or "POST" (uppercase).
+ * @type string
+ */
+get method() {
+ if (this.isDefined) {
+ return String(_cx().request().method().toUpperCase());
+ }
+},
+
+/**
+ * Whether the curent HTTP request is a GET request.
+ * @type boolean
+ */
+get isGet() {
+ return (this.method == "GET");
+},
+
+/**
+ * Whether the current HTTP request is a POST request.
+ * @type boolean
+ */
+get isPost() {
+ return (this.method == "POST");
+},
+
+/**
+ * Either "http" or "https" (lowercase).
+ * @type string
+ */
+get scheme() {
+ if (this.isDefined) {
+ return String(_cx().request().scheme());
+ }
+},
+
+/**
+ * Whether the current request arrived using HTTPS.
+ * @type boolean
+ */
+get isSSL() {
+ return (this.scheme == "https");
+},
+
+/**
+ * Holds the IP address of the user making the request.
+ * @type string
+ */
+get clientAddr() {
+ if (this.isDefined) {
+ return String(_cx().request().clientAddr());
+ }
+},
+
+/**
+ * Parameters associated with the request, either from the query string
+ * or from the contents of a POST, e.g. from a form. Parameters are accessible
+ * by name as properties of this object. The property value is either a
+ * string (typically) or an array of strings (if the parameter occurs
+ * multiple times in the request).
+ *
+ * @type object
+ */
+get params() {
+ if (this.isDefined) {
+ var cx = _cx();
+ var req = cx.request();
+ return cx.attributes().getOrElseUpdate("requestParams",
+ scalaF0(function() { return req.params(cx.runner().globalScope()); }));
+ }
+},
+
+/**
+ * Uploaded files associated with the request, from the contents of a POST.
+ *
+ * @type object
+ */
+get files() {
+ if (this.isDefined) {
+ var cx = _cx();
+ var req = cx.request();
+ return cx.attributes().getOrElseUpdate("requestFiles",
+ scalaF0(function() { return req.files(cx.runner().globalScope()); }));
+ }
+},
+
+/**
+ * Used to access the HTTP headers of the current request. Properties are
+ * header names, and each value is either a string (typically) or an
+ * array of strings (if the header occurs multiple times in the request).
+ *
+ * @example
+print(request.headers["User-Agent"]);
+ *
+ * @type object
+ */
+get headers() {
+ if (this.isDefined) {
+ var cx = _cx();
+ var req = cx.request();
+ return cx.attributes().getOrElseUpdate("requestHeaders",
+ scalaF0(function() { return req.headers(cx.runner().globalScope()); }));
+ }
+},
+
+// TODO: this is super inefficient to do each time someone accesses
+// request.cookies.foo. We should probably store _cookies in the requestCache.
+get cookies() {
+ var _cookies = {};
+ var cookieHeaderArray = this.headers['Cookie'];
+ if (!cookieHeaderArray) { return {}; }
+ if (!(cookieHeaderArray instanceof Array))
+ cookieHeaderArray = [cookieHeaderArray];
+ var name, val;
+
+ cookieHeaderArray.forEach(function (cookieHeader) {
+ cookieHeader.split(';').forEach(function(cs) {
+ var parts = cs.split('=');
+ if (parts.length == 2) {
+ name = trim(parts[0]);
+ val = trim(unescape(parts[1]));
+ _addIfNotPresent(_cookies, name, val);
+ }
+ });
+ });
+
+ return _cookies;
+},
+
+/**
+ * Holds the full URL of the request.
+ */
+get url() {
+ if (this.isDefined) {
+ return this.scheme+"://"+this.host+this.path+(this.query ? "?"+this.query : "");
+ }
+},
+
+get host() {
+ if (this.isDefined) {
+ // required by HTTP/1.1 to be present.
+ return String(this.headers['Host']).toLowerCase();
+ }
+},
+
+get domain() {
+ if (this.isDefined) {
+ // like host, but without the port if there is one.
+ return this.host.split(':')[0];
+ }
+},
+
+get uniqueId() {
+ return String(_cx().executionId());
+},
+
+get protocol() {
+ if (this.isDefined) {
+ return String(_cx().request().protocol());
+ }
+},
+
+get userAgent() {
+ if (this.isDefined) {
+ var agentString = (request.headers['User-Agent'] || "?");
+ return {
+ toString: function() { return agentString; },
+ isIPhone: function() { return (agentString.indexOf("(iPhone;") > 0); }
+ };
+ }
+},
+
+get acceptsGzip() {
+ if (this.isDefined) {
+ var headerArray = this.headers["Accept-Encoding"];
+ if (! (headerArray instanceof Array)) {
+ headerArray = [headerArray];
+ }
+ // Want to see if some accept-encoding header OK's gzip.
+ // Starting with: "Accept-Encoding: gzip; q=0.5, deflate; q=1.0"
+ // 1. Split into ["gzip; q=0.5", "delfate; q=1.0"]
+ // 2. See if some entry is gzip with q > 0. (q is optional.)
+ return headerArray.some(function(header) {
+ if (! header) return false;
+ return header.split(/,\s*/).some(function(validEncoding) {
+ if (!validEncoding.indexOf("gzip") == 0) {
+ return false;
+ }
+ if (/q=[0\.]*$/.test(validEncoding)) {
+ return false;
+ }
+ return true;
+ });
+ });
+ }
+}
+
+}; // end: var request = {...
diff --git a/infrastructure/framework-src/modules/global/response.js b/infrastructure/framework-src/modules/global/response.js
new file mode 100644
index 0000000..7236920
--- /dev/null
+++ b/infrastructure/framework-src/modules/global/response.js
@@ -0,0 +1,294 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview Helpers for the HTTP response.
+ */
+
+/** @ignore */
+function _cx() { return appjet.context };
+
+/** @ignore */
+function _cookiestring(c) {
+ var x = '';
+ if (!c.name) { throw new Error('cookie name is required'); }
+ if (!c.value) { c.value = ''; }
+ x += (c.name + '=' + escape(c.value));
+
+ // expires
+ if (c.expires instanceof Date) {
+ x += ('; expires='+_cookiedate(c.expires));
+ }
+ if (typeof(c.expires) == 'number') {
+ var today = (new Date()).valueOf();
+ var d = new Date(today + 86400000*c.expires);
+ x += ('; expires='+_cookiedate(d));
+ }
+
+ // domain
+ if (c.domain) { x += ('; domain='+c.domain); }
+
+ // path
+ if (c.path) { x += ('; path='+c.path); }
+
+ // secure
+ if (c.secure == true) { x += '; secure'; }
+
+ return x;
+};
+
+/** @ignore */
+function _cookiedate(d) {
+ var x = d.toGMTString();
+ var p = x.split(' ');
+ return [p[0], [p[1], p[2], p[3]].join('-'), p[4], p[5]].join(' ');
+};
+
+var response = {
+
+get isDefined() {
+ return _cx().response() != null;
+}
+
+};
+
+/**
+ * Halts the program immediately and returns 403 Forbidden error to the user.
+ */
+response.forbid = function() {
+ _cx().response().error(403, "Forbidden");
+};
+
+/**
+ * Halts the program immediately.
+ *
+ * @param {boolean} renderCurrentPage if false, an empty page will be rendered,
+ * otherwise calls to print() so far will be displayed. Either way, no more
+ * code will be executed.
+ */
+response.stop = function(renderCurrentPage) {
+ _cx().response().stop();
+};
+
+/**
+ * Halts the program immediately and returns a 404 not found error to the user.
+ */
+response.notFound = function() {
+ _cx().response().error(404, "404: Not found");
+};
+
+/**
+ * Halts the program immediately and sends an HTTP redirect response (302),
+ * redirecting to the given path (relative or absolute).
+ *
+ * @param {string} path The new path
+ */
+response.redirect = function(path) {
+ if ((! path) && path != "") {
+ throw new Error("Invalid redirect: "+path);
+ }
+ if (path.indexOf('/') == 0) {
+ // make sure absolute URL has proper host/port
+ path = request.scheme+"://"+request.host+path;
+ }
+ _cx().response().redirect(path);
+};
+
+/**
+ * Sets the status code in the HTTP response.
+ *
+ * @param {number} newCode
+ */
+response.setStatusCode = function(newCode) {
+ _cx().response().setStatusCode(newCode);
+};
+response.getStatusCode = function() {
+ return _cx().response().getStatusCode();
+};
+
+response.sendError = function(errorCode, errorHtml) {
+ _cx().response().error(errorCode, errorHtml);
+};
+
+response.reset = function() {
+ _cx().response().reset();
+};
+
+/**
+ * Sets any header of the HTTP response.
+ *
+ * @example
+response.setHeader('Cache-Control', 'no-cache');
+ *
+ * @param {string} name
+ * @param {string} value
+ */
+response.setHeader = function(name, value) {
+ _cx().response().setHeader(name, value);
+};
+
+/**
+ * Adds the name,value pair to the headers. Useful for headers that are
+ * allowed to repeat, such as Set-Cookie.
+ *
+ * @param {string} name
+ * @param {string} value
+ */
+response.addHeader = function(name, value) {
+ _cx().response().addHeader(name, value);
+};
+
+/**
+ * Returns the value of a previously-set header. Useful in the
+ * postRequestHandler to see values of headers set during normal
+ * request processing.
+ *
+ * @param {string} name
+ * @return {array} An array of header values. Empty array if none set.
+ */
+response.getHeader = function(name) {
+ if (! this.isDefined) {
+ return [];
+ } else {
+ return _cx().response().getHeader(name);
+ }
+};
+
+/**
+ * Removes all instances of a header of the HTTP response.
+ *
+ * @param {string} name
+ */
+response.removeHeader = function(name) {
+ _cx().response().removeHeader(name);
+};
+
+/**
+ * Low-level hook for writing raw data to the response.
+ * @param {string} data will be written, verbatim, to the HTTP resonse.
+ */
+response.write = function(data) {
+ _cx().response().write(data);
+};
+
+/**
+ * Low-level hook for writing raw byte data to the response. Especially
+ * useful for writing the result of a <code>wget</code> of image data,
+ * or writing an uploaded file.
+ * @param {string} data will be written, verbatim, to the HTTP resonse.
+ */
+response.writeBytes = function(data) {
+ _cx().response().writeBytes(data);
+};
+
+//----------------------------------------------------------------
+// Cookies!
+//----------------------------------------------------------------
+
+/**
+ * Set a cookie in the response.
+ *
+ * @example
+response.setCookie({
+ name: "SessionID",
+ value: "25",
+ secure: true,
+ expires: 14 // 14 days
+});
+ *
+ * @param {object} cookieObject This may contain any of the following:
+<ul>
+ <li>name (required): The name of the cookie</li>
+ <li>value (required): The value of the cookie. (Note: this value will be escaped).
+ <li>expires (optional): If an integer, means number of days until it expires;
+ if a Date object, means exact date on which to expire.</li>
+ <li>domain (optional): The cookie domain</li>
+ <li>path (optional): To restrict the cookie to a specific path.</li>
+ <li>secure (optional): Whether this cookie should only be sent securely.</li>
+</ul>
+ */
+response.setCookie = function(cookieObject) {
+ this.addHeader('Set-Cookie', _cookiestring(cookieObject));
+
+ var p3pHeader = this.getHeader("P3P");
+ if ((! p3pHeader) || p3pHeader.length == 0) {
+ // The existence of this "privacy policy" header allows cookies set on
+ // pages inside iframes to be accepted by IE. (This is some kind of
+ // default policy copied from an example online. -- dgreensp)
+ this.setHeader('P3P', 'CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');
+ }
+};
+
+/**
+ * Tells the client to delete the cookie of the given name (by setting
+ * its expiration time to zero).
+ * @param {string} name The name of the cookie to delete.
+ */
+response.deleteCookie = function(name) {
+ this.setCookie({name: name, value: '', expires: 0});
+};
+
+function _trim(s) {
+ return String((new java.lang.String(s)).trim());
+}
+
+response.getCookie = function(name) {
+ var cookieHeaders = this.getHeader('Set-Cookie');
+ if (! cookieHeaders) { return; }
+ for (var i = 0; i < cookieHeaders.length; ++i) {
+ if (_trim(cookieHeaders[i].split("=")[0]) == name)
+ return _trim(cookieHeaders[i].split(";")[0].split("=")[1]);
+ }
+};
+
+/**
+ * Sets the Content-Type header of the response. If the content-type includes
+ * a charset, that charset is used to send the response.
+ * @param {string} contentType the new content-type
+ */
+response.setContentType = function(contentType) {
+ _cx().response().setContentType(contentType);
+};
+
+response.getCharacterEncoding = function() {
+ return _cx().response().getCharacterEncoding();
+}
+
+response.neverCache = function() {
+ // be aggressive about not letting the response be cached.
+ var that = this;
+ function sh(k,v) { that.setHeader(k,v); }
+ sh('Expires', 'Sat, 18 Jun 1983 07:07:07 GMT');
+ sh('Last-Modified', (new Date()).toGMTString());
+ sh('Cache-Control', ('no-store, no-cache, must-revalidate, '+
+ 'post-check=0, pre-check=0'));
+ sh('Pragma', 'no-cache');
+};
+
+response.alwaysCache = function() {
+ var that = this;
+ function sh(k,v) { that.setHeader(k,v); }
+ that.removeHeader('Last-Modified');
+ that.removeHeader('Pragma');
+ var futureDate = new Date();
+ futureDate.setTime(Date.now() + 315360000000);
+ sh('Expires', futureDate.toGMTString());
+ sh('Cache-Control', 'max-age=315360000');
+};
+
+response.setGzip = function(gzip) {
+ _cx().response().setGzip(gzip);
+}
diff --git a/infrastructure/framework-src/modules/image.js b/infrastructure/framework-src/modules/image.js
new file mode 100644
index 0000000..8aec74b
--- /dev/null
+++ b/infrastructure/framework-src/modules/image.js
@@ -0,0 +1,110 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("blob");
+
+jimport("java.awt.image.BufferedImage");
+jimport("org.apache.sanselan.Sanselan");
+jimport("org.apache.sanselan.ImageFormat");
+
+if (java.lang.System.getProperty("java.awt.headless") == null) {
+ // If the system property isn't set either way, then default to "headless" mode,
+ // so that we don't start calling the window manager when the AWT classes
+ // are loaded. For example, on OS X the java process is given a Dock icon
+ // when we create our first BufferedImage.
+ java.lang.System.setProperty("java.awt.headless", "true");
+}
+
+/**
+ * Encodes the given pixel data into an image blob, ready to be served to
+ * the client. Pixels are specified as 32-bit ints in the format AARRGGBB,
+ * and the order is across rows first, then down columns. If useTransparency
+ * is true, then all pixels should have an alpha channel as their
+ * most-significant byte, with 0xff being fully opaque. If useTransparency
+ * is false, all pixels are fully opaque and the high byte is ignored.
+ * Supported formats: GIF.
+ * <p>
+ * For example, to create a GIF image consisting of a green pixel followed
+ * by a transparent pixel to the right of it, use:
+ * imageBlobFromPixels(2, 1, [0xff00ff00, 0x00000000], true, "gif")
+ */
+
+function pixelsToImageBlob(width, height, pixelArrayARGB, useTransparency, format) {
+ var image = _makeBufferedImage(width, height);
+ var array = _makePixelArray(width, height);
+ var alphaMask = (useTransparency ? 0x00000000 : 0xff000000);
+
+ for(var i=0; i<array.length; i++) {
+ // bitwise operations cause a JS number to become a signed 32-bit int
+ array[i] = (pixelArrayARGB[i] | alphaMask);
+ }
+
+ _setImagePixels(image, array);
+
+ if (format.toLowerCase() == "gif") {
+ return _bufferedImage2gifBlob(image);
+ }
+ return null;
+}
+
+/**
+ * Creates a blob of image data in a format readable by a web browser
+ * that consists of a solid, opaque color and has the given width
+ * and height. The sixHexDigits must be a number, such as
+ * 0x12fda3, or a string, such as "12fda3".
+ */
+function solidColorImageBlob(width, height, sixHexDigits) {
+ var image = _makeBufferedImage(width, height);
+ var array = _makePixelArray(width, height);
+
+ var pixel = 0xffffff;
+ if ((typeof sixHexDigits) == "number") {
+ pixel = sixHexDigits;
+ }
+ else if ((typeof sixHexDigits) == "string") {
+ pixel = Number("0x"+sixHexDigits);
+ }
+
+ // bitwise operations cause a JS number to become a signed 32-bit int
+ pixel = ((pixel & 0xffffff) | 0xff000000);
+
+ java.util.Arrays.fill(array, pixel);
+ _setImagePixels(image, array);
+
+ return _bufferedImage2gifBlob(image);
+}
+
+function _makeBufferedImage(width, height) {
+ return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+}
+
+function _makePixelArray(width, height) {
+ return java.lang.reflect.Array.newInstance(java.lang.Integer.TYPE,
+ width*height);
+}
+
+function _setImagePixels(image, array) {
+ var width = image.getWidth();
+ var height = image.getHeight();
+
+ image.setRGB(0, 0, width, height, array, 0, width);
+}
+
+function _bufferedImage2gifBlob(image) {
+ // Use the Apache Sanselan image library because it nails transparent GIFs.
+ var bytes = Sanselan.writeImageToBytes(image, ImageFormat.IMAGE_FORMAT_GIF, null);
+ return blob.byteArrayToBlob("image/gif", bytes);
+}
diff --git a/infrastructure/framework-src/modules/jsutils.js b/infrastructure/framework-src/modules/jsutils.js
new file mode 100644
index 0000000..02f81a2
--- /dev/null
+++ b/infrastructure/framework-src/modules/jsutils.js
@@ -0,0 +1,195 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview A collection of core JavaScript utilities.
+ */
+
+/**
+ * Iterator convenience for JavaScript Objects.
+ *
+ * Note that if func returns false, the iteration will be immediately terminated.
+ * (Returning undefined, or not specifying a return type, does not terminate the iteration).
+ *
+ * @example
+var pastels = {
+ red: "#fcc",
+ green: "#cfc",
+ blue: "#ccf"
+};
+eachProperty(pastels, function(key, value) {
+ print(DIV({style: 'background: '+value+';'}, key));
+});
+ *
+ * @param {object} obj The object over which to iterate.
+ * @param {function} func The function to run on each [key,value] pair.
+ */
+function eachProperty(obj, func) {
+ var r;
+ for (k in obj) {
+ if (!obj.hasOwnProperty || obj.hasOwnProperty(k)) {
+ r = func(k,obj[k]);
+ if (r === false) {
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * Douglas Crockford's "object" function for prototypal inheritance, taken from
+ * http://javascript.crockford.com/prototypal.html
+ *
+ * @param {object} parent The parent object.
+ * @return {object} A new object whose prototype is parent.
+ */
+function object(parent) {
+ function f() {};
+ f.prototype = parent;
+ return new f();
+}
+
+/**
+ * Creates an array of the properties of <code>obj</code>,
+ * <em>not</em> including built-in or inherited properties. If no
+ * argument is given, applies to the global object.
+ *
+ * @example
+// Prints "abc"
+keys({a: 1, b: 2, c: 3}).forEach(function(k) {
+ print(k);
+}
+ *
+ * @example
+// Prints all the functions and object members of the global "appjet" object,
+// one per line.
+print(keys(appjet).join('\n'));
+ *
+ * @param {object} obj
+ */
+function keys(obj) {
+ var array = [];
+ var o = obj;
+ if (o == undefined) {
+ o = this;
+ }
+ for(var k in o) {
+ if (!obj.hasOwnProperty || o.hasOwnProperty(k)) {
+ array.push(k);
+ }
+ }
+ return array;
+}
+
+/**
+ * Comparator that returns -1, +1, or 0 depending on whether a &lt; b, or a &gt; b, or
+ * neither, respectively.
+ * @param {object} a
+ * @param {object} b
+ * @return {number} -1, 0, or +1
+ */
+function cmp(a,b) {
+ if (a < b) {
+ return -1;
+ }
+ if (a > b) {
+ return 1;
+ }
+ return 0;
+}
+
+function arrayToSet(arr) {
+ var set = {};
+ arr.forEach(function(x) {
+ set[x] = true;
+ });
+ return set;
+}
+
+function mergeArrays(mergeFunction, a1, a2, etc) {
+ var len = a1.length;
+ var arrays = Array.prototype.slice.call(arguments, 1);
+ for (var i = 0; i < arrays.length; ++i) {
+ if (arrays[i].length != len) {
+ return;
+ }
+ }
+ out = [];
+ for (var i = 0; i < a1.length; ++i) {
+ out.push(mergeFunction.apply(this, arrays.map(function(array) { return array[i]; })));
+ }
+ return out;
+}
+
+function debug(obj) {
+ if (typeof(obj) == 'object') {
+ var ret = [];
+ if (obj) {
+ eachProperty(obj, function(k, v) {
+ ret.push(k+" -> "+debug(v));
+ });
+ return '['+ret.join(", ")+']';
+ } else {
+ return String(obj);
+ }
+ } else {
+ return String(obj);
+ }
+}
+
+/**
+ * Create a scala function out of the given JS function.
+ */
+function scalaFn(nargs, f) {
+ if (typeof(f) == 'function') {
+ return new Packages.scala['Function'+nargs]({
+ apply: f
+ });
+ } else {
+ return new Packages.scala['Function'+nargs]({
+ apply: function() { return f; }
+ })
+ }
+}
+
+function scalaF0(f) {
+ return scalaFn(0, f);
+}
+
+function scalaF1(f) {
+ return scalaFn(1, f);
+}
+
+/**
+ * Some bonus functions for functional programming.
+ */
+function f_curry(thisPtr, f, arg1, arg2, etc) {
+ var curriedArgs = Array.prototype.slice.call(arguments, 2);
+ return function() {
+ var args = Array.prototype.slice.call(arguments, 0);
+ return f.apply(thisPtr, curriedArgs.concat(args));
+ }
+}
+
+function f_limitArgs(thisPtr, f, n) {
+ return function() {
+ var args = Array.prototype.slice.call(arguments, 0, n);
+ return f.apply(thisPtr, args);
+ }
+}
+
+
+
diff --git a/infrastructure/framework-src/modules/netutils.js b/infrastructure/framework-src/modules/netutils.js
new file mode 100644
index 0000000..6616b76
--- /dev/null
+++ b/infrastructure/framework-src/modules/netutils.js
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview A collection of network-related utilities.
+ */
+
+import("jsutils.eachProperty");
+
+jimport("java.net.InetAddress");
+
+
+function urlPost(url0, params, options) {
+ var url = new java.net.URL(url0);
+
+ var data;
+ if (typeof(params) == 'string') {
+ data = params;
+ } else if (typeof(params) == 'object') {
+ var components = [];
+ eachProperty(params, function(k, v) {
+ components.push(encodeURIComponent(k)+"="+encodeURIComponent(v));
+ });
+ data = components.join('&');
+ }
+ var dataBytes = (new java.lang.String(data)).getBytes("UTF-8");
+ var conn = url.openConnection();
+ conn.setInstanceFollowRedirects(true);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
+ conn.setRequestProperty("Content-Length", dataBytes.length);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setConnectTimeout(30*1000);
+ conn.setReadTimeout(30*1000);
+ conn.getOutputStream().write(dataBytes);
+ var content = conn.getContent();
+ var responseCode = conn.getResponseCode();
+ var contentType = conn.getContentType();
+ var contentEncoding = conn.getContentEncoding();
+
+ if ((content instanceof java.io.InputStream) && (new java.lang.String(contentType)).startsWith("text/")) {
+ if (! contentEncoding) {
+ var encoding = contentType.split(/;\s*/);
+ if (encoding.length > 1) {
+ encoding = encoding[1].split("=");
+ if (encoding[0] == "charset")
+ contentEncoding = encoding[1];
+ }
+ }
+ content = net.appjet.common.util.BetterFile.getStreamBytes(content);
+ if (contentEncoding) {
+ content = (new java.lang.String(content, contentEncoding));
+ }
+ }
+
+ return {
+ content: content,
+ status: responseCode,
+ contentType: contentType,
+ contentEncoding: contentEncoding
+ };
+}
+
+function getHostnameFromIp(ip) {
+ var ret = null;
+ try {
+ var addr = InetAddress.getByName(ip);
+ ret = addr.getHostName();
+ } catch (ex) { }
+ return ret;
+}
+
+
+
diff --git a/infrastructure/framework-src/modules/process.js b/infrastructure/framework-src/modules/process.js
new file mode 100644
index 0000000..48ab62e
--- /dev/null
+++ b/infrastructure/framework-src/modules/process.js
@@ -0,0 +1,91 @@
+/**
+ * Simple way to execute external commands through javascript
+ *
+ * @example
+ cmd = exec("cat");
+ System.out.println("First: " +cmd.write("this is a loop.").read(Process.READ_AVAILABLE)); // prints "this is a loop."
+ System.out.println("Second: " +cmd.writeAndClose(" hi there").result()); // prints "this is a loop. hi there"
+ *
+ */
+
+jimport("java.lang.Runtime");
+jimport("java.io.BufferedInputStream");
+jimport("java.io.BufferedOutputStream");
+jimport("java.lang.System");
+
+/* returns a process */
+function exec(process) {
+ return new Process(process);
+};
+
+function Process(cmd) {
+ this.cmd = cmd;
+ this.proc = Runtime.getRuntime().exec(cmd);
+ this.resultText = "";
+ this.inputStream = new BufferedInputStream(this.proc.getInputStream());
+ this.errorStream = new BufferedInputStream(this.proc.getErrorStream());
+ this.outputStream = new BufferedOutputStream(this.proc.getOutputStream());
+}
+
+Process.CHUNK_SIZE = 1024;
+Process.READ_ALL = -1;
+Process.READ_AVAILABLE = -2;
+
+Process.prototype.write = function(stdinText) {
+ this.outputStream.write(new java.lang.String(stdinText).getBytes());
+ this.outputStream.flush();
+ return this;
+};
+
+Process.prototype.writeAndClose = function(stdinText) {
+ this.write(stdinText);
+ this.outputStream.close();
+ return this;
+};
+
+/* Python file-like behavior: read specified number of bytes, else until EOF*/
+Process.prototype.read = function(nbytesToRead, stream) {
+ var inputStream = stream || this.inputStream;
+ var availBytes = inputStream.available();
+ if (!availBytes) return null;
+
+ var result = "";
+ var nbytes = nbytesToRead || Process.READ_ALL;
+ var readAll = (nbytes == Process.READ_ALL);
+ var readAvailable = (nbytes == Process.READ_AVAILABLE);
+ while (nbytes > 0 || readAll || readAvailable) {
+ var chunkSize = readAll ? Process.CHUNK_SIZE :
+ readAvailable ? Process.CHUNK_SIZE : nbytes;
+
+ // allocate a java byte array
+ var bytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, chunkSize);
+
+ var len = inputStream.read(bytes, 0, chunkSize);
+
+ // at end of stream, or when we run out of data, stop reading in chunks.
+ if (len == -1) break;
+ if (nbytes > 0) nbytes -= len;
+
+ result += new java.lang.String(bytes);
+
+ if (readAvailable && inputStream.available() == 0) break;
+ }
+
+ this.resultText += new String(result);
+ return new String(result);
+};
+
+Process.prototype.result = function() {
+ this.outputStream.close();
+ this.proc.waitFor();
+ this.read(Process.READ_ALL, this.inputStream);
+ return new String(this.resultText);
+};
+
+Process.prototype.resultOrError = function() {
+ this.proc.waitFor();
+ this.read(Process.READ_ALL, this.inputStream);
+ var result = this.resultText;
+ if(!result || result == "") result = this.read(Process.READ_ALL, this.errorStream);
+ return result || "";
+};
diff --git a/infrastructure/framework-src/modules/profiler.js b/infrastructure/framework-src/modules/profiler.js
new file mode 100644
index 0000000..223c197
--- /dev/null
+++ b/infrastructure/framework-src/modules/profiler.js
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @fileDescription
+ * Sosme profiling functions.
+ */
+var time = function() {
+ return Packages.net.appjet.oui.profiler.time();
+}
+
+var record = function(op, time) {
+ Packages.net.appjet.oui.profiler.record(op, time);
+}
+
+var recordCumulative = function(op, time) {
+ Packages.net.appjet.oui.profiler.recordCumulative(op, time);
+}
+
+var reset = function() {
+ Packages.net.appjet.oui.profiler.reset();
+}
+
+var print = function() {
+ Packages.net.appjet.oui.profiler.print();
+}
+
+var rcb = function(op, cumulative) {
+ var start = time();
+ return function() {
+ var end = time();
+ (cumulative ? recordCumulative : record)(op, end-start);
+ }
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/modules/sessions.js b/infrastructure/framework-src/modules/sessions.js
new file mode 100644
index 0000000..3d0041b
--- /dev/null
+++ b/infrastructure/framework-src/modules/sessions.js
@@ -0,0 +1,156 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("dateutils");
+import("fastJSON");
+import("fileutils");
+import("jsutils.{eachProperty,keys}");
+import("stringutils.{randomHash,startsWith,endsWith}");
+import("sync");
+
+jimport("net.appjet.common.util.ExpiringMapping");
+
+//----------------------------------------------------------------
+
+var _DEFAULT_COOKIE_NAME = "SessionID";
+var _DEFAULT_SERVER_EXPIRATION = 3*24*60*60*1000; // 72 hours
+
+function getSessionId(cookieName, createIfNotPresent, domain) {
+ if (request.isComet || request.isCron) {
+ return null;
+ }
+
+ if (request.cookies[cookieName]) {
+ return request.cookies[cookieName];
+ }
+
+ if (!createIfNotPresent) {
+ return null;
+ }
+
+ // Keep sessionId in requestCache so this function can be called multiple
+ // times per request without multiple calls to setCookie().
+ if (!appjet.requestCache.sessionId) {
+ var sessionId = randomHash(16);
+
+ response.setCookie({
+ name: cookieName,
+ value: sessionId,
+ path: "/",
+ domain: (domain || undefined)
+ });
+
+ appjet.requestCache.sessionId = sessionId;
+ }
+
+ return appjet.requestCache.sessionId;
+}
+
+function _getExpiringSessionMap(db) {
+ sync.callsyncIfTrue(db,
+ function() { return (!db.map); },
+ function() { db.map = new ExpiringMapping(_DEFAULT_SERVER_EXPIRATION); });
+ return db.map;
+}
+
+function _getCachedDb() {
+ return appjet.cacheRoot("net.appjet.ajstdlib.session");
+}
+
+//----------------------------------------------------------------
+
+function getSession(opts) {
+ // Session options.
+ if (!opts) { opts = {}; }
+ var cookieName = opts.cookieName || _DEFAULT_COOKIE_NAME;
+
+ // get cookie ID (sets response cookie if necessary)
+ var sessionId = getSessionId(cookieName, true, opts.domain);
+
+ // get expiring session map
+ var db = _getCachedDb();
+ var map = _getExpiringSessionMap(db);
+
+ // get session data object
+ var domainKey = (opts.domain ? opts.domain : "");
+ var dataKey = [domainKey, sessionId].join('$');
+
+ var sessionData = map.get(dataKey);
+ if (!sessionData) {
+ sessionData = {};
+ map.put(dataKey, sessionData);
+ }
+ else {
+ map.touch(dataKey);
+ }
+
+ return sessionData;
+}
+
+function writeSessionsToDisk() {
+ var dateString = dateutils.dateFormat(new Date(), "yyyy-MM-dd");
+ var dataFile = new Packages.java.io.File(appjet.config.sessionStoreDir+"/sessions-"+dateString+".jslog");
+ dataFile.getParentFile().mkdirs();
+ var writer = new java.io.FileWriter(dataFile);
+ var map = _getCachedDb().map;
+ if (! map) { return; }
+ var keyIterator = map.listAllKeys().iterator();
+ while (keyIterator.hasNext()) {
+ var key = keyIterator.next();
+ var session = map.get(key);
+ if (keys(session).length == 0) { continue; }
+ var obj = { key: key, session: session };
+ var json = fastJSON.stringify(obj);
+ writer.write(json);
+ writer.write("\n");
+ }
+ writer.flush();
+ writer.close();
+}
+
+function _extractDate(fname) {
+ var datePart = fname.substr("sessions-".length, "2009-09-24".length);
+ return Number(datePart.split("-").join(""));
+}
+
+function readLatestSessionsFromDisk() {
+ var dir = new Packages.java.io.File(appjet.config.sessionStoreDir);
+ if (! dir.exists()) { return; }
+ var files = dir.listFiles(new Packages.java.io.FilenameFilter({
+ accept: function(dir, name) {
+ return startsWith(name, "sessions") && endsWith(name, ".jslog")
+ }
+ }));
+ if (files.length == 0) { return; }
+ var latestFile = files[0];
+ for (var i = 1; i < files.length; ++i) {
+ if (_extractDate(files[i].getName()) > _extractDate(latestFile.getName())) {
+ latestFile = files[i];
+ }
+ }
+ var map = _getExpiringSessionMap(_getCachedDb());
+ fileutils.eachFileLine(latestFile, function(json) {
+ try {
+ var obj = fastJSON.parse(json);
+ var key = obj.key;
+ var session = obj.session;
+ map.put(key, session);
+ } catch (err) {
+ Packages.java.lang.System.out.println("Error reading sessions file on line '"+json+"': "+String(err));
+ }
+ });
+ latestFile.renameTo(new Packages.java.io.File(latestFile.getParent()+"/used-"+latestFile.getName()));
+}
diff --git a/infrastructure/framework-src/modules/sqlbase/persistent_vars.js b/infrastructure/framework-src/modules/sqlbase/persistent_vars.js
new file mode 100644
index 0000000..1c4cc95
--- /dev/null
+++ b/infrastructure/framework-src/modules/sqlbase/persistent_vars.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import("sqlbase.sqlobj");
+import("sqlbase.sqlcommon");
+
+jimport("java.lang.System.out.println");
+
+// TODO: add caching?
+
+// Curently supports:
+// Strings
+
+function get(name) {
+ if (!sqlcommon.doesTableExist('persistent_vars')) {
+ return undefined;
+ }
+ var r = sqlobj.selectSingle('persistent_vars', {name: name});
+ if (!r) {
+ return undefined;
+ }
+ return r.stringVal;
+}
+
+function put(name, val) {
+ if (typeof(val) != 'string') {
+ throw Error("unsupported type for persistent_vars: "+typeof(val));
+ }
+
+ var r = sqlobj.selectSingle('persistent_vars', {name: name});
+ if (r) {
+ sqlobj.updateSingle('persistent_vars', {id: r.id}, {stringVal: val});
+ } else {
+ sqlobj.insert('persistent_vars', {name: name, stringVal: val});
+ }
+}
+
+function remove(name) {
+ var r = sqlobj.selectSingle('persistent_vars', {name: name});
+ if (r) {
+ sqlobj.deleteRows('persistent_vars', {id: r.id});
+ }
+}
diff --git a/infrastructure/framework-src/modules/sqlbase/sqlbase.js b/infrastructure/framework-src/modules/sqlbase/sqlbase.js
new file mode 100644
index 0000000..3df1a0f
--- /dev/null
+++ b/infrastructure/framework-src/modules/sqlbase/sqlbase.js
@@ -0,0 +1,205 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("jsutils.*");
+import("sqlbase.sqlcommon");
+import("fastJSON");
+import("timer");
+
+jimport("java.lang.System.out.println");
+
+function _sqlbase() {
+ return sqlcommon.getSqlBase();
+}
+
+/**
+ * Creates a SQL table suitable for storing a mapping from String to JSON value.
+ * Maximum key length is 128 characters. Has no effect if the table already exists.
+ */
+function createJSONTable(tableName) {
+ _sqlbase().createJSONTable(String(tableName));
+}
+
+/**
+ * Retrieves a JavaScript object or value from a table. Returns undefined
+ * if there is no mapping for the given string key. Requires that the table
+ * exist.
+ */
+function getJSON(tableName, stringKey) {
+ var result = _sqlbase().getJSON(String(tableName), String(stringKey));
+ if (result) {
+
+ return fastJSON.parse(String(result))['x'];
+
+ /* performance-testing JSON
+ var obj1 = timer.time("JSON.parse (json2)", function() {
+ return JSON.parse(String(result))['x'];
+ });
+ var obj2 = timer.time("JSON.parse (fastJSON)", function() {
+ return fastJSON.parse(String(result))['x'];
+ });
+ return obj2;
+ */
+ }
+ return undefined;
+}
+
+function getAllJSON(tableName, start, count) {
+ var result = _sqlbase().getAllJSON(String(tableName), Number(start), Number(count));
+ return Array.prototype.map.call(result, function(x) {
+ return {id: x.id(), value: fastJSON.parse(String(x.value()))['x']};
+ })
+}
+
+function getAllJSONKeys(tableName) {
+ var result = _sqlbase().getAllJSONKeys(String(tableName));
+ return Array.prototype.map.call(result, function(x) { return String(x); });
+}
+
+/**
+ * Assigns a JavaScript object or primitive value to a string key in a table.
+ * Maximum key length is 128 characters. Requires that the table exist.
+ */
+function putJSON(tableName, stringKey, objectOrValue) {
+ var obj = ({x:objectOrValue});
+
+ var json = fastJSON.stringify(obj);
+
+ /* performance-testing JSON
+
+ var json1 = timer.time("JSON.stringify (json2)", function() {
+ return JSON.stringify(obj);
+ });
+ var json2 = timer.time("JSON.stringify (fastJSON)", function() {
+ return fastJSON.stringify(obj);
+ });
+
+ if (json1 != json2) {
+ println("json strings do not match!");
+ println("\n\n");
+ println(json1);
+ println("\n");
+ println(json2);
+ println("\n\n");
+ }*/
+
+ _sqlbase().putJSON(String(tableName), String(stringKey), json);
+}
+
+/**
+ * Removes the mapping for a string key from a table. Requires that the table
+ * exist.
+ */
+function deleteJSON(tableName, stringKey) {
+ _sqlbase().deleteJSON(String(tableName), String(stringKey));
+}
+
+/**
+ * Creates a SQL table suitable for storing a mapping from (key,n) to string.
+ * The mapping may be sparse, but storage is most efficient when n are consecutive.
+ * The "length" of the array is not stored and must be externally maintained.
+ * Maximum key length is 128 characters. This call has no effect if the table
+ * already exists.
+ */
+function createStringArrayTable(tableName) {
+ _sqlbase().createStringArrayTable(String(tableName));
+}
+
+/**
+ * Assigns a string value to a (key,n) pair in a StringArray table. Maximum key length
+ * is 128 characters. Requires that the table exist.
+ */
+function putStringArrayElement(tableName, stringKey, n, value) {
+ _sqlbase().putStringArrayElement(String(tableName), String(stringKey),
+ Number(n), String(value));
+}
+
+/**
+ * Equivalent to a series of consecutive puts of the elements of valueArray, with the first
+ * one going to n=startN, the second to n=startN+1, and so on, but much more efficient.
+ */
+function putConsecutiveStringArrayElements(tableName, stringKey, startN, valueArray) {
+ var putter = _sqlbase().putMultipleStringArrayElements(String(tableName), String(stringKey));
+ for(var i=0;i<valueArray.length;i++) {
+ putter.put(Number(startN)+i, String(valueArray[i]));
+ }
+ putter.finish();
+}
+
+/**
+ * Equivalent to a series of puts of the (key,value) entries of the JavaScript object
+ * nToValue, using as few database operations as possible.
+ */
+function putDictStringArrayElements(tableName, stringKey, nToValue) {
+ var nArray = [];
+ for(var n in nToValue) {
+ nArray.push(n);
+ }
+ nArray.sort(function(a,b) { return Number(a) - Number(b); });
+
+ var putter = _sqlbase().putMultipleStringArrayElements(String(tableName), String(stringKey));
+ nArray.forEach(function(n) {
+ putter.put(Number(n), String(nToValue[n]));
+ });
+ putter.finish();
+}
+
+/**
+ * Retrieves a string value from a StringArray table. Returns undefined
+ * if there is no mapping for the given (key,n) pair. Requires that the table
+ * exist.
+ */
+function getStringArrayElement(tableName, stringKey, n) {
+ var result = _sqlbase().getStringArrayElement(String(tableName),
+ String(stringKey), Number(n));
+ if (result) {
+ return String(result);
+ }
+ return undefined;
+}
+
+/**
+ * Retrieves all values from the database page that contains the mapping for n.
+ * Properties are added to destMap for n, if present in the database, and any other
+ * numeric entries in the same page. No return value.
+ */
+function getPageStringArrayElements(tableName, stringKey, n, destMap) {
+ var array = _sqlbase().getPageStringArrayElements(String(tableName), String(stringKey), n);
+ for(var i=0;i<array.length;i++) {
+ var entry = array[i];
+ destMap[entry.index()] = String(entry.value());
+ }
+}
+
+/**
+ * Removes the mapping for a (key,n) pair from a StringArray table. Requires that the table
+ * exist.
+ */
+function deleteStringArrayElement(tableName, stringKey, n) {
+ _sqlbase().putStringArrayElement(String(tableName), String(stringKey), Number(n), null);
+}
+
+/**
+ * Removes all mappings and metadata associated with a given key in a table.
+ */
+function clearStringArray(tableName, stringKey) {
+ _sqlbase().clearStringArray(String(tableName), stringKey);
+}
+
+function getStringArrayAllKeys(tableName) {
+ var result = _sqlbase().getStringArrayAllKeys(String(tableName));
+ return Array.prototype.map.call(result, function(x) { return String(x); });
+}
diff --git a/infrastructure/framework-src/modules/sqlbase/sqlcommon.js b/infrastructure/framework-src/modules/sqlbase/sqlcommon.js
new file mode 100644
index 0000000..360f5e2
--- /dev/null
+++ b/infrastructure/framework-src/modules/sqlbase/sqlcommon.js
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("jsutils.scalaF1")
+import("stringutils.startsWith");
+
+jimport("net.appjet.ajstdlib.SQLBase");
+jimport("java.lang.System.out.println");
+
+function _sqlbase() { return appjet.cache.sqlbase };
+
+function init(driver, url, username, password) {
+ var dbName = url.split(":")[1];
+ println("Using "+dbName+" database type.");
+
+ appjet.cache.sqlbase = new SQLBase(driver, url, username, password);
+
+ // Test the connection
+ println("Establishing "+dbName+" connection (this may take a minute)...");
+ try {
+ withConnection(function() {
+ return;
+ });
+ } catch (ex) {
+ println("Error establishing "+dbName+" connection:");
+ println(ex.toString().split('\n')[0]);
+ if (_sqlbase().isMysql()) {
+ println("Perhaps mysql server is not running, or you did not specify "+
+ "proper database credentials with --etherpad.SQL_PASSWORD "+
+ "and --etherpad.SQL_USERNAME?");
+ }
+ if (_sqlbase().isDerby()) {
+ println("Perhaps database directory "+appjet.config.derbyHome+
+ " is not writable?");
+ }
+ println("Exiting...");
+ Packages.java.lang.System.exit(1);
+ }
+ println(dbName+" connection established.");
+}
+
+function onShutdown() {
+ _sqlbase().close();
+}
+
+function withConnection(f) {
+ return _sqlbase().withConnection(scalaF1(f));
+}
+
+function inTransaction(f) {
+ return _sqlbase().inTransaction(scalaF1(f));
+}
+
+function closing(s, f) {
+ if (s instanceof java.sql.Connection) {
+ throw new java.lang.IllegalArgumentException("Don't want to use 'closing()' on a sql connection!");
+ }
+ try {
+ return f();
+ }
+ finally {
+ s.close();
+ }
+}
+
+function doesTableExist(table) {
+ return withConnection(function(conn) {
+ return _sqlbase().doesTableExist(conn, table);
+ });
+}
+
+function autoIncrementClause() {
+ return _sqlbase().autoIncrementClause();
+}
+
+function createTableOptions() {
+ return _sqlbase().createTableOptions();
+}
+
+function btquote(x) { return _sqlbase().quoteIdentifier(x); }
+
+function getSqlBase() { return _sqlbase(); }
+
+function isMysql() { return _sqlbase().isMysql(); }
+function isDerby() { return _sqlbase().isDerby(); }
+
diff --git a/infrastructure/framework-src/modules/sqlbase/sqlobj.js b/infrastructure/framework-src/modules/sqlbase/sqlobj.js
new file mode 100644
index 0000000..4bc1263
--- /dev/null
+++ b/infrastructure/framework-src/modules/sqlbase/sqlobj.js
@@ -0,0 +1,505 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("cache_utils.syncedWithCache");
+import("sqlbase.sqlcommon.*");
+import("jsutils.*");
+
+jimport("java.lang.System.out.println");
+jimport("java.sql.Statement");
+
+function _withCache(name, fn) {
+ return syncedWithCache('sqlobj.'+name, fn);
+}
+
+function getIdColspec() {
+ return ('INT NOT NULL '+autoIncrementClause()+' PRIMARY KEY');
+}
+
+function getLongtextColspec(extra) {
+ var spec = getSqlBase().longTextType();
+ if (extra) {
+ spec = (spec + " " + extra);
+ }
+ return spec;
+}
+
+function getBoolColspec(extra) {
+ var spec;
+ if (isMysql()) {
+ spec = 'TINYINT(1)';
+ } else {
+ spec = 'SMALLINT';
+ }
+ if (extra) {
+ spec = (spec + " " + extra);
+ }
+ return spec;
+}
+
+function getDateColspec(extra) {
+ var spec;
+ if (isMysql()) {
+ spec = 'DATETIME';
+ } else {
+ spec = 'TIMESTAMP';
+ }
+ if (extra) {
+ spec = (spec + " " + extra);
+ }
+ return spec;
+}
+
+function _bq(x) { return btquote(x); }
+
+/*
+ * for debugging queries
+ */
+function _qdebug(q) {
+ if (appjet.config.debugSQL) {
+ println(q);
+ }
+}
+
+/** executeFn is either "execute" or "executeUpdate" "executeQuery" */
+function _execute(stmnt, executeFn) {
+ if (!executeFn) {
+ executeFn = 'execute';
+ }
+ return withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt);
+ return closing(pstmnt, function() {
+ _qdebug(stmnt);
+ return pstmnt[executeFn]();
+ });
+ });
+}
+
+function _executeUpdate(stmnt) {
+ return _execute(stmnt, 'executeUpdate');
+}
+
+function _executeQuery(stmnt) {
+ return _execute(stmnt, 'executeQuery');
+}
+
+/*
+ * Not all SQL/JS types supported.
+ */
+function _getJsValFromResultSet(rs, type, colName) {
+ var r;
+ if (type == java.sql.Types.VARCHAR ||
+ type == java.sql.Types.LONGVARCHAR ||
+ type == java.sql.Types.CHAR) {
+ r = String(rs.getString(colName));
+ } else if (type == java.sql.Types.TIMESTAMP) {
+ var t = rs.getTimestamp(colName);
+ if (t) {
+ r = new Date(t.getTime());
+ } else {
+ r = null;
+ }
+ } else if (type == java.sql.Types.INTEGER ||
+ type == java.sql.Types.SMALLINT ||
+ type == java.sql.Types.TINYINT) {
+ r = rs.getInt(colName);
+ } else if (type == java.sql.Types.BIT) {
+ r = rs.getBoolean(colName);
+ } else {
+ throw Error("Cannot fetch sql type ID "+type+" (columnName = "+colName+")");
+ }
+
+ if (rs.wasNull()) {
+ r = null;
+ }
+ return r;
+}
+
+function _lookupColumnType(tableName, columnName) {
+ return withConnection(function(conn) {
+ var metadata = conn.getMetaData();
+ var rs = metadata.getColumns(null, null, tableName, columnName);
+ if (!rs) {
+ throw Error("Table '"+tableName+"' does not appear to have colum '"+columnName+"'.");
+ }
+ var rsmd = rs.getMetaData();
+ var colCount = rsmd.getColumnCount();
+// rs.first();
+ rs.next();
+ var type = rs.getInt("DATA_TYPE");
+ return type;
+ });
+}
+
+/* cached, on misses calls _lookuParameterType */
+function _getParameterType(tableName, columnName) {
+ var key = [tableName, columnName].join(".");
+ return _withCache('column-types', function(cache) {
+ if (!cache[key]) {
+ cache[key] = _lookupColumnType(tableName, columnName);
+ }
+ return cache[key];
+ });
+}
+
+/*
+ * Not all SQL/JS types supported.
+ */
+function _setPreparedValues(tableName, pstmnt, keyList, obj, indexOffset) {
+ if (!indexOffset) { indexOffset = 0; }
+
+ for (var i = 1; i <= keyList.length; i++) {
+ var k = keyList[i-1];
+ var v = obj[k];
+ var j = i + indexOffset;
+
+ if (v === undefined) {
+ throw Error("value is undefined for key "+k);
+ }
+
+ if (v === null) {
+ var type = _getParameterType(tableName, k);
+ pstmnt.setNull(j, type);
+ } else if (typeof(v) == 'string') {
+ pstmnt.setString(j, v);
+ } else if (typeof(v) == 'number') {
+ pstmnt.setInt(j, v);
+ } else if (typeof(v) == 'boolean') {
+ pstmnt.setBoolean(j, v);
+ } else if (v.valueOf && v.getDate && v.getHours) {
+ pstmnt.setTimestamp(j, new java.sql.Timestamp(+v));
+ } else {
+ throw Error("Cannot insert this type of javascript object: "+typeof(v)+" (key="+k+", value = "+v+")");
+ }
+ }
+}
+
+function _resultRowToJsObj(resultSet) {
+ var resultObj = {};
+
+ var metaData = resultSet.getMetaData();
+ var colCount = metaData.getColumnCount();
+ for (var i = 1; i <= colCount; i++) {
+ var colName = metaData.getColumnName(i);
+ var type = metaData.getColumnType(i);
+ resultObj[colName] = _getJsValFromResultSet(resultSet, type, colName);
+ }
+
+ return resultObj;
+}
+
+/*
+ * Inserts the object into the given table, and returns auto-incremented ID if any.
+ */
+function insert(tableName, obj) {
+ var keyList = keys(obj);
+
+ var stmnt = "INSERT INTO "+_bq(tableName)+" (";
+ stmnt += keyList.map(function(k) { return _bq(k); }).join(', ');
+ stmnt += ") VALUES (";
+ stmnt += keyList.map(function(k) { return '?'; }).join(', ');
+ stmnt += ")";
+
+ return withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt, Statement.RETURN_GENERATED_KEYS);
+ return closing(pstmnt, function() {
+ _setPreparedValues(tableName, pstmnt, keyList, obj, 0);
+ _qdebug(stmnt);
+ pstmnt.executeUpdate();
+ var rs = pstmnt.getGeneratedKeys();
+ if (rs != null) {
+ return closing(rs, function() {
+ if (rs.next()) {
+ return rs.getInt(1);
+ }
+ });
+ }
+ });
+ });
+};
+
+/*
+ * Selects a single object given the constraintMap. If there are more
+ * than 1 objects that match, it will return a single one of them
+ * (unspecified which one). If no objects match, returns null.
+ *
+ * constraints is a javascript object of column names to values.
+ * Currently only supports string equality of constraints.
+ */
+function selectSingle(tableName, constraints) {
+ var keyList = keys(constraints);
+
+ var stmnt = "SELECT * FROM "+_bq(tableName)+" WHERE (";
+ stmnt += keyList.map(function(k) { return '('+_bq(k)+' = '+'?)'; }).join(' AND ');
+ stmnt += ')';
+ if (isMysql()) {
+ stmnt += ' LIMIT 1';
+ }
+
+ return withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt);
+ return closing(pstmnt, function() {
+ _setPreparedValues(tableName, pstmnt, keyList, constraints, 0);
+ _qdebug(stmnt);
+ var resultSet = pstmnt.executeQuery();
+ return closing(resultSet, function() {
+ if (!resultSet.next()) {
+ return null;
+ }
+ return _resultRowToJsObj(resultSet);
+ });
+ });
+ });
+}
+
+function _makeConstraintString(key, value) {
+ if (typeof(value) != 'object' || ! (value instanceof Array)) {
+ return '('+_bq(key)+' = ?)';
+ } else {
+ var comparator = value[0];
+ return '('+_bq(key)+' '+comparator+' ?)';
+ }
+}
+
+function _preparedValuesConstraints(constraints) {
+ var c = {};
+ eachProperty(constraints, function(k, v) {
+ c[k] = (typeof(v) != 'object' || ! (v instanceof Array) ? v : v[1]);
+ });
+ return c;
+}
+
+function selectMulti(tableName, constraints, options) {
+ if (!options) {
+ options = {};
+ }
+
+ var constraintKeys = keys(constraints);
+
+ var stmnt = "SELECT * FROM "+_bq(tableName)+" ";
+
+ if (constraintKeys.length > 0) {
+ stmnt += "WHERE (";
+ stmnt += constraintKeys.map(function(key) {
+ return _makeConstraintString(key, constraints[key]);
+ }).join(' AND ');
+ stmnt += ')';
+ }
+
+ if (options.orderBy) {
+ var orderEntries = [];
+ options.orderBy.split(",").forEach(function(orderBy) {
+ var asc = "ASC";
+ if (orderBy.charAt(0) == '-') {
+ orderBy = orderBy.substr(1);
+ asc = "DESC";
+ }
+ orderEntries.push(_bq(orderBy)+" "+asc);
+ });
+ stmnt += " ORDER BY "+orderEntries.join(", ");
+ }
+
+ if (options.limit) {
+ stmnt += " LIMIT "+options.limit;
+ }
+
+ return withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt);
+ return closing(pstmnt, function() {
+ _setPreparedValues(
+ tableName, pstmnt, constraintKeys,
+ _preparedValuesConstraints(constraints), 0);
+
+ _qdebug(stmnt);
+ var resultSet = pstmnt.executeQuery();
+ var resultArray = [];
+
+ return closing(resultSet, function() {
+ while (resultSet.next()) {
+ resultArray.push(_resultRowToJsObj(resultSet));
+ }
+
+ return resultArray;
+ });
+ });
+ });
+}
+
+/* returns number of rows updated */
+function update(tableName, constraints, obj) {
+ var objKeys = keys(obj);
+ var constraintKeys = keys(constraints);
+
+ var stmnt = "UPDATE "+_bq(tableName)+" SET ";
+ stmnt += objKeys.map(function(k) { return ''+_bq(k)+' = ?'; }).join(', ');
+ stmnt += " WHERE (";
+ stmnt += constraintKeys.map(function(k) { return '('+_bq(k)+' = ?)'; }).join(' AND ');
+ stmnt += ')';
+
+ return withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt);
+ return closing(pstmnt, function() {
+ _setPreparedValues(tableName, pstmnt, objKeys, obj, 0);
+ _setPreparedValues(tableName, pstmnt, constraintKeys, constraints, objKeys.length);
+ _qdebug(stmnt);
+ return pstmnt.executeUpdate();
+ });
+ });
+}
+
+function updateSingle(tableName, constraints, obj) {
+ var count = update(tableName, constraints, obj);
+ if (count != 1) {
+ throw Error("save count != 1. instead, count = "+count);
+ }
+}
+
+function deleteRows(tableName, constraints) {
+ var constraintKeys = keys(constraints);
+ var stmnt = "DELETE FROM "+_bq(tableName)+" WHERE (";
+ stmnt += constraintKeys.map(function(k) { return '('+_bq(k)+' = ?)'; }).join(' AND ');
+ stmnt += ')';
+ withConnection(function(conn) {
+ var pstmnt = conn.prepareStatement(stmnt);
+ closing(pstmnt, function() {
+ _setPreparedValues(tableName, pstmnt, constraintKeys, constraints);
+ _qdebug(stmnt);
+ pstmnt.executeUpdate();
+ });
+ })
+}
+
+//----------------------------------------------------------------
+// table management
+//----------------------------------------------------------------
+
+/*
+ * Create a SQL table, specifying column names and types with a
+ * javascript object.
+ */
+function createTable(tableName, colspec, indices) {
+ if (doesTableExist(tableName)) {
+ return;
+ }
+
+ var stmnt = "CREATE TABLE "+_bq(tableName)+ " (";
+ stmnt += keys(colspec).map(function(k) { return (_bq(k) + ' ' + colspec[k]); }).join(', ');
+ if (indices) {
+ stmnt += ', ' + keys(indices).map(function(k) { return 'INDEX (' + _bq(k) + ')'; }).join(', ');
+ }
+ stmnt += ')'+createTableOptions();
+ _execute(stmnt);
+}
+
+function dropTable(tableName) {
+ _execute("DROP TABLE "+_bq(tableName));
+}
+
+function dropAndCreateTable(tableName, colspec, indices) {
+ if (doesTableExist(tableName)) {
+ dropTable(tableName);
+ }
+
+ return createTable(tableName, colspec, indices);
+}
+
+function renameTable(oldName, newName) {
+ _executeUpdate("RENAME TABLE "+_bq(oldName)+" TO "+_bq(newName));
+}
+
+function modifyColumn(tableName, columnName, newSpec) {
+ _executeUpdate("ALTER TABLE "+_bq(tableName)+" MODIFY "+_bq(columnName)+" "+newSpec);
+}
+
+function alterColumn(tableName, columnName, alteration) {
+ var q = "ALTER TABLE "+_bq(tableName)+" ALTER COLUMN "+_bq(columnName)+" "+alteration;
+ _executeUpdate(q);
+}
+
+function changeColumn(tableName, columnName, newSpec) {
+ var q = ("ALTER TABLE "+_bq(tableName)+" CHANGE COLUMN "+_bq(columnName)
+ +" "+newSpec);
+ _executeUpdate(q);
+}
+
+function addColumns(tableName, colspec) {
+ inTransaction(function(conn) {
+ eachProperty(colspec, function(name, definition) {
+ var stmnt = "ALTER TABLE "+_bq(tableName)+" ADD COLUMN "+_bq(name)+" "+definition;
+ _executeUpdate(stmnt);
+ });
+ });
+}
+
+function dropColumn(tableName, columnName) {
+ var stmnt = "ALTER TABLE "+_bq(tableName)+" DROP COLUMN "+_bq(columnName);
+ _executeUpdate(stmnt);
+}
+
+function listTables() {
+ return withConnection(function(conn) {
+ var metadata = conn.getMetaData();
+ var resultSet = metadata.getTables(null, null, null, null);
+ var resultArray = [];
+
+ return closing(resultSet, function() {
+ while (resultSet.next()) {
+ resultArray.push(resultSet.getString("TABLE_NAME"));
+ }
+ return resultArray;
+ });
+ });
+}
+
+function setTableEngine(tableName, engineName) {
+ var stmnt = "ALTER TABLE "+_bq(tableName)+" ENGINE="+_bq(engineName);
+ _executeUpdate(stmnt);
+}
+
+function getTableEngine(tableName) {
+ if (!isMysql()) {
+ throw Error("getTableEngine() only supported by MySQL database type.");
+ }
+
+ var tableEngines = {};
+
+ withConnection(function(conn) {
+ var stmnt = "show table status";
+ var pstmnt = conn.prepareStatement(stmnt);
+ closing(pstmnt, function() {
+ _qdebug(stmnt);
+ var resultSet = pstmnt.executeQuery();
+ closing(resultSet, function() {
+ while (resultSet.next()) {
+ var n = resultSet.getString("Name");
+ var eng = resultSet.getString("Engine");
+ tableEngines[n] = eng;
+ }
+ });
+ });
+ });
+
+ return tableEngines[tableName];
+}
+
+function createIndex(tableName, columns) {
+ var indexName = "idx_"+(columns.join("_"));
+ var stmnt = "CREATE INDEX "+_bq(indexName)+" on "+_bq(tableName)+" (";
+ stmnt += columns.map(_bq).join(", ");
+ stmnt += ")";
+ _executeUpdate(stmnt);
+}
+
diff --git a/infrastructure/framework-src/modules/stringutils.js b/infrastructure/framework-src/modules/stringutils.js
new file mode 100644
index 0000000..3fe5611
--- /dev/null
+++ b/infrastructure/framework-src/modules/stringutils.js
@@ -0,0 +1,399 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @fileOverview A collection of various string utilities.
+ */
+
+// TODO: uncomment with import works with *
+
+import("funhtml.{TABLE,TR,TH,TD,OL,LI}");
+import("jsutils.{object,eachProperty}");
+
+//import("funhtml.*");
+
+jimport("java.util.Random");
+jimport("java.lang.System.currentTimeMillis");
+
+
+/**
+ * Removes leading and trailing whitespace from a string.
+ * @param {string} str
+ * @return {string} The trimmed string.
+ */
+function trim(str) {
+ return str.replace(/^\s+|\s+$/g, "");
+}
+
+//----------------------------------------------------------------
+// String prototype enhancements.
+// TODO: should we move this to a new library "enhancedstring"?
+//----------------------------------------------------------------
+startsWith = function(s, prefix) {
+ return (s.indexOf(prefix) == 0);
+};
+endsWith = function(s, suffix) {
+ return (s.substr(s.length - suffix.length) == suffix);
+};
+contains = function(s, x) {
+ return (s.indexOf(x) != -1);
+};
+makeTitle = function(s) {
+ if (! s) return;
+ return s.split(" ").map(function(x) {
+ return x[0].toUpperCase() + x.substr(1)
+ }).join(" ");
+}
+repeat = function(s, n) {
+ var out = [];
+ while (n-- > 0) {
+ out.push(s);
+ }
+ return out.join('');
+}
+
+/*
+ * Helper function that converts a raw string to an HTML string, with
+ * character entities replaced by appropriate HTML codes, and newlines
+ * rentered as BRs.
+ *
+ * <p>A more general version of this function is toHTML(), which can operate
+ * on not just strings, but any object.
+ *
+ * @param {string} str the raw string
+ * @return {string} HTML-formatted string
+ */
+function _stringToHTML(str) {
+ return String(net.appjet.oui.Util.stringToHTML(str));
+}
+
+// used to convert an object to HTML when the object does not have a
+// toHTML method.
+//
+function _coerceObjectToHTML(obj) {
+ var t = TABLE({border: 1, cellpadding: 2, cellspacing: 0});
+ eachProperty(obj, function(name, value) {
+ t.push(TR(TH(String(name)), TD(String(value))));
+ });
+ return toHTML(t);
+}
+
+// Converts an array to an HTML list by listing its properties and
+// recursively converting the values to HTML by calling toHTML() on
+// each of them.
+function _objectToOL(obj) {
+ var l = OL();
+ eachProperty(obj, function(name, value) {
+ l.push(LI({value: name}, value));
+ });
+ return l;
+}
+
+function _sameProperties(obj1, obj2) {
+ if (typeof(obj1) != 'object' || typeof(obj2) != 'object')
+ return typeof(obj1) == typeof(obj2);
+
+ var mismatch = 0;
+ eachProperty(obj1, function(name) {
+ if (! obj2.hasOwnProperty(name)) {
+ mismatch++;
+ }});
+ eachProperty(obj2, function(name) {
+ if (! obj1.hasOwnProperty(name)) {
+ mismatch++;
+ }});
+ return mismatch < 2;
+}
+
+//
+// for pretty-printing arrays. needs a lot of work.
+//
+function _arrayToHTML(a) {
+ if (a.length === 0) {
+ return "";
+ }
+ if (typeof(a[0]) != 'object') {
+ return toHTML(_objectToOL(a));
+ } else if (! _sameProperties(a[0], a[1])) {
+ return toHTML(_objectToOL(a));
+ } else {
+ return _likeObjectsToHTML(function (f) {
+ a.forEach(function(value, i) {
+ f({index: i}, value, {});
+ });}, null);
+ }
+}
+
+/** @ignore */
+
+// a foreaching function that takes three arguments: properties to put first,
+// properties to put in the middle, and properties to put at the end.
+// and a table header (with large colspan)
+function _likeObjectsToHTML(forEachFunction, tophead) {
+ objs = [];
+ prepnames = new StringSet();
+ objpnames = new StringSet();
+ postpnames = new StringSet();
+ rows = [];
+
+ var t = TABLE({border: 1, cellpadding: 2, cellspacing: 0});
+ var head = TR();
+ if (tophead)
+ t.push(tophead);
+ t.push(head);
+
+ var butWaitTheresMore = false;
+ var howManyMore = 0;
+
+ forEachFunction(function(pre, o, post) {
+ if (objs.length >= 10) {
+ butWaitTheresMore = true;
+ howManyMore++;
+ return;
+ }
+ objs.push({pre: pre, o: o, post: post});
+ var tr = TR();
+ rows.push(tr);
+ t.push(tr);
+
+ eachProperty(pre, function(name) { prepnames.add(name); });
+ eachProperty(o, function(name) { objpnames.add(name); });
+ eachProperty(post, function(name) { postpnames.add(name); });
+ });
+ var numpnames = 0;
+ var appendTDsForPropName = function (where) {
+ return function(name) {
+ numpnames++;
+ head.push(TH(name));
+ for (var j = 0; j < objs.length; ++j) {
+ if (! (objs[j][where] === undefined) && ! (objs[j][where][name] === undefined))
+ rows[j].push(TD(String(objs[j][where][name])));
+ else
+ rows[j].push(TD());
+ }
+ };
+ };
+ prepnames.forEach(appendTDsForPropName("pre"));
+ objpnames.forEach(appendTDsForPropName("o"));
+ postpnames.forEach(appendTDsForPropName("post"));
+ if (butWaitTheresMore) {
+ t.push(TR(TD({colspan: numpnames}, "..."+howManyMore+
+ " additional element"+(howManyMore == 1 ? "" : "s")+" omitted...")));
+ }
+ return toHTML(t);
+}
+
+/**
+ * Returns a string with any number of variables substituted in, as
+ * popularized by C's function of the same name. Some common substitutions:
+ *
+ * <ul><li>%d - an integer</li><li>%f - a floating-point number</li><li>%b - a boolean</li>
+ * <li>%s - a string</li></ul>
+ *
+ * <p>Each time one of these "slot" appears in your format string, the next argument is displayed
+ * according to the type of slot you specified.
+ *
+ * <p>AppJet supports <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html">
+ * Java's specification of printf</a>, which has a ton of features, including selecting
+ * arguments out of order, formatting dates and times, and specifying how many characters
+ * wide each slot should be.
+ *
+ * @example
+var x = 5;
+response.write(sprintf("an integer: %d", x));
+response.write(sprintf("Two strings: [%s] and [%s].", "string one", "string two"));
+ *
+ * @param {string} formatString
+ * @param {*} arg1
+ * @param {*} arg2
+ * @param {*} arg3 ...
+ */
+function sprintf(formatString, arg1, arg2, etc) {
+ if (typeof(formatString) != 'string') {
+ throw new Error('printf takes a string as the first argument.');
+ }
+ var argList = java.lang.reflect.Array.newInstance(java.lang.Object, arguments.length-1);
+ for (var i = 1; i < arguments.length; i++) {
+ if (arguments[i] instanceof Date)
+ argList[i-1] = arguments[i].getTime();
+ else
+ argList[i-1] = arguments[i];
+ }
+ return String(net.appjet.ajstdlib.printf.printf(formatString, argList));
+};
+
+/**
+ * Replaces keys of data found in string with their corresponding values.
+ *
+ * <p>(Inspired by http://javascript.crockford.com/remedial.html)
+ *
+ * @example
+var data = {name: "Aaron", age: 25, today: new Date()};
+print(supplant(data, """
+
+{name}'s age is {age} years, as of {today}.
+
+"""));
+
+ * @param {object} data dictionary of values
+ * @param {string} str
+ * @return {string} str with keys of data replaced by their values
+ */
+function supplant(data, str) {
+ var s = str;
+ var o = data;
+ function rep(a, b) {
+ var r = o[b];
+ if (typeof(r) != 'undefined') {
+ return r;
+ } else {
+ return a;
+ }
+ }
+ return s.replace(/{([^{}]*)}/g, rep);
+};
+
+//----------------------------------------------------------------
+// raw printing
+//----------------------------------------------------------------
+var _raw_prototype;
+
+/**
+ * Used for printing un-escaped HTML, such as your own HTML tags.
+ *
+ * <p>Normally, printing a string will cause it to be translated
+ * so that it appears the same on the screen as it did in your code.
+ * If you're writing your own HTML, you don't want it to be processed
+ * this way. Wrapping a string in html(...) by-passes normal printing behavior,
+ * so that print(html(" -- html goes here ---")) will write the HTML
+ * directly to the page.
+ *
+ * <p>If you want to mix your own HTML code with HTML code generated from a
+ * tag object, you can get the HTML for the tag by calling its toHTML(...) method.
+ *
+ * <p>Multiple arguments to html(...) will be concatenated into one string.
+ *
+ * @example
+print(html("""
+&lt;br /&gt;
+&lt;br /&gt;
+&lt;div&gt;&lt;p&gt;Here is some text inside a P inside a DIV.&lt;/p&gt;
+&lt;/div&gt;
+&lt;br /&gt;
+"""));
+ *
+ * @param {string} text the raw text
+ * @return {object} an object which, when printed, prints the raw html text
+ */
+function html(text) {
+ if (!_raw_prototype) {
+ _raw_prototype = object(Object.prototype);
+ _raw_prototype.toString = function() { return this._text; };
+ _raw_prototype.toHTML = function() { return this._text; };
+ }
+ var rawObj = object(_raw_prototype);
+ rawObj._text = Array.prototype.map.call(arguments, String).join('');
+ return rawObj;
+}
+
+/**
+ * This function is used by print(...) to convert a string or object
+ * into nice-looking printable HTML. It may be useful in conjunction
+ * with html(...) if you wish to work directly with HTML.
+ *
+ * <p>You can control how toHTML(...) (and therefore print(...)) behave on an object
+ * by giving that object a .toHTML() function.
+ *
+ * @param {*} x any javascript variable
+ * @return {string} html-formatted string
+ */
+function toHTML(x) {
+ if (typeof(x) == 'undefined') {
+ return 'undefined';
+ }
+ if (x === null) {
+ return 'null';
+ }
+ if (typeof x == "string" || (x instanceof java.lang.String)) {
+ return _stringToHTML(x);
+ }
+ if (typeof(x.toHTML) == "function") {
+ return x.toHTML();
+ }
+ if (typeof(x) == "xml") {
+ return _stringToHTML(x.toSource());
+ }
+ if (x instanceof Array) {
+ return _arrayToHTML(x);
+ }
+ if (x instanceof Date) {
+ var pieces = x.toString().split(" ");
+ return pieces.slice(0, 5).join(' ') + ' ' + pieces[6];
+ }
+ if (typeof(x) == "object") {
+ return _coerceObjectToHTML(x);
+ }
+ // TODO: add more types to auto-printing, such as functions,
+ // numbers, what else?
+ return _stringToHTML(""+x);
+}
+
+
+/**
+ * Generates a random string of specified length using upper-case letters, lower-case letters, and numbers.
+ */
+
+var _jrand = new Random(currentTimeMillis());
+
+function randomString(nchars) {
+ var result = '';
+
+ // 48-58 or 65-91 or 97-123 (inclusive-exclusive)
+ // 0-10 or 0-26 or 0-26
+ // 0-62
+
+ for (var i = 0; i < nchars; i++) {
+ var x = _jrand.nextInt(62);
+ var code;
+ if (x < 10) { code = x + 48; }
+ if (x >= 10 && x < 36) { code = x - 10 + 65/*a*/; }
+ if (x >= 36) { code = x - 36 + 97/*A*/; }
+ result += String.fromCharCode(code);
+ }
+ return result;
+}
+
+function md5(x) {
+ return net.appjet.ajstdlib.md5.md5(x);
+}
+
+function randomHash(len) {
+ var x = md5(""+_jrand.nextDouble()*1e12+_jrand.nextDouble()*1e12);
+ if (len) {
+ return String(x).substr(0,len);
+ } else {
+ return x;
+ }
+}
+
+function gzip(x) {
+ return net.appjet.oui.Util.gzip(x)
+}
+
+function isNumeric(x) {
+ return !!(/^\d+$/.test(x));
+}
+
diff --git a/infrastructure/framework-src/modules/sync.js b/infrastructure/framework-src/modules/sync.js
new file mode 100644
index 0000000..a222ea0
--- /dev/null
+++ b/infrastructure/framework-src/modules/sync.js
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+jimport("java.util.concurrent.locks.ReentrantLock");
+jimport("net.appjet.oui.GlobalSynchronizer");
+
+/**
+ * synchronously calls a no-argument function.
+ * f may have return values.
+ */
+function callsync(obj, f) {
+ if (!obj._LOCK) {
+ try {
+ appjet.globalLock.lock();
+ if (! obj._LOCK) {
+ obj._LOCK = new ReentrantLock();
+ }
+ } finally {
+ appjet.globalLock.unlock();
+ }
+ }
+ try {
+ obj._LOCK.lock();
+ return f();
+ } finally {
+ obj._LOCK.unlock();
+ }
+}
+
+/**
+ * synchronously calls a no-argument function iff
+ * condition() is true. condition may be called
+ * twice and shouldn't have side-effects.
+ */
+function callsyncIfTrue(obj, condition, f) {
+ if (condition()) {
+ callsync(obj, function() {
+ if (condition()) {
+ f();
+ }
+ });
+ }
+}
+
+/**
+ * returns a function that synchronously calls
+ * f with its own arguments
+ */
+function wrapsync(obj, f, thisArg) {
+ return function() {
+ var args = Array.prototype.slice.call(arguments);
+ var wrapper = function() {
+ return f.apply(thisArg, args);
+ }
+ callsync(obj, wrapper);
+ }
+}
+
+function doWithStringLock(lockName, fn) {
+ GlobalSynchronizer.acquire(lockName);
+ try {
+ return fn();
+ }
+ finally {
+ GlobalSynchronizer.release(lockName);
+ }
+}
+
diff --git a/infrastructure/framework-src/modules/timer.js b/infrastructure/framework-src/modules/timer.js
new file mode 100644
index 0000000..01be175
--- /dev/null
+++ b/infrastructure/framework-src/modules/timer.js
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("jsutils.*");
+
+jimport("net.appjet.ajstdlib.timer");
+
+function time(name, f) {
+ var t = timer.start(name);
+ try {
+ return f();
+ } finally {
+ t.done();
+ }
+}
+
diff --git a/infrastructure/framework-src/modules/varz.js b/infrastructure/framework-src/modules/varz.js
new file mode 100644
index 0000000..0e55d20
--- /dev/null
+++ b/infrastructure/framework-src/modules/varz.js
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+jimport("java.util.concurrent.atomic.AtomicInteger");
+
+import("sync");
+
+function varz() {
+ sync.callsyncIfTrue(appjet.cache,
+ function() { return ! appjet.cache.varz; },
+ function() { appjet.cache.varz = {}; });
+ return appjet.cache.varz;
+}
+
+function _getInteger(name) {
+ sync.callsyncIfTrue(varz(),
+ function() { return ! varz()[name] },
+ function() { varz()[name] = new AtomicInteger(0) });
+ return varz()[name];
+}
+
+function incrementInt(name) {
+ _getInteger(name).getAndIncrement();
+}
+
+function addToInt(name, count) {
+ _getInteger(name).getAndAdd(count);
+}
+
+function getSnapshot() {
+ var ret = {};
+ for (var k in varz()) {
+ if (k[0] == '_') {
+ continue;
+ }
+ ret[k] = varz()[k].toString();
+ }
+ return ret;
+}
diff --git a/infrastructure/framework-src/modules/yuicompressor.js b/infrastructure/framework-src/modules/yuicompressor.js
new file mode 100644
index 0000000..572cc0d
--- /dev/null
+++ b/infrastructure/framework-src/modules/yuicompressor.js
@@ -0,0 +1,85 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+jimport("java.lang.System.err")
+jimport("yuicompressor.org.mozilla.javascript.ErrorReporter");
+jimport("com.yahoo.platform.yui.compressor.JavaScriptCompressor")
+jimport("com.yahoo.platform.yui.compressor.CssCompressor")
+jimport("java.io.StringReader");
+jimport("java.io.StringWriter");
+
+/**
+ * Compresses the given JavaScript code into an equivalent, shorter string of code using
+ * YUICompressor. In addition to removing white-space and comments, YUICompressor
+ * does a full semantic parse of the code and renames non-global variables to have
+ * very short names. Scopes that are visible to "eval" and "with" are excluded from
+ * variable renaming, making the operation very safe.
+ * <p>
+ * For example,
+ * yuicompressor.compressJS("function foo() { var longVariableName = 3; return longVariableName }");
+ * produces
+ * "function foo(){var A=3;return A;}"
+ */
+
+function compressJS(code) {
+ function getComplaint(message, sourceName, line, lineSource, lineOffset) {
+ if (line < 0) return message;
+ else return (line+":"+lineOffset+":"+message);
+ }
+ function complaintHandler(func) {
+ return function(message, sourceName, line, lineSource, lineOffset) {
+ return func(getComplaint(message, sourceName, line, lineSource, lineOffset));
+ }
+ }
+ var myErrorReporter = new JavaAdapter(ErrorReporter, {
+ warning: complaintHandler(function (msg) {
+ if (msg.indexOf("Try to use a single 'var' statement per scope.") >= 0)
+ return;
+ err.println("yuicompressor.compressJS warning: "+msg);
+ }),
+ error: complaintHandler(function (msg) {
+ throw new Error("yuicompressor.compressJS error: "+msg);
+ }),
+ runtimeError: complaintHandler(function (msg) {
+ throw new Error("yuicompressor.compressJS error: "+msg);
+ })
+ });
+
+ var munge = true;
+ var verbose = false;
+ var optimize = true;
+ var wrapPos = 100; // characters, no wrap == -1
+ var compressor = new JavaScriptCompressor(new StringReader(code), myErrorReporter);
+ var writer = new StringWriter();
+ compressor.compress(writer, 100, munge, verbose, true, !optimize);
+ return String(writer.toString());
+}
+
+/**
+ * Compresses the given CSS code into an equivalent, shorter string of code using
+ * YUICompressor. Besides removing unnecessary white-space and comments, the operation
+ * performs an assortment of semantics-preserving optimizations. The operation attempts
+ * to preserve common "hacks" that take advantage of browser differences in parsing.
+ */
+
+function compressCSS(code) {
+ var compressor = new CssCompressor(new StringReader(code));
+ var wrapPos = 100; // characters, no wrap == -1
+ var writer = new StringWriter();
+ compressor.compress(writer, wrapPos);
+ return String(writer.toString());
+}
diff --git a/infrastructure/framework-src/oncomet.js b/infrastructure/framework-src/oncomet.js
new file mode 100644
index 0000000..b6aeda5
--- /dev/null
+++ b/infrastructure/framework-src/oncomet.js
@@ -0,0 +1,38 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.cometHandler === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No comet handler defined!");
+}
+
+function _ga(k) {
+ return String(appjet.context.attributes().apply(k));
+}
+
+var _op = String(_ga("cometOperation"));
+switch (_op) {
+ case "connect":
+ serverhandlers.cometHandler("connect", _ga("cometId"));
+ break;
+ case "disconnect":
+ serverhandlers.cometHandler("disconnect", _ga("cometId"));
+ break;
+ case "message":
+ serverhandlers.cometHandler("message", _ga("cometId"), _ga("cometData"));
+ break;
+ default:
+ throw new Packages.net.appjet.oui.ExecutionException("Unknown comet operation: '"+_op+"'");
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/onerror.js b/infrastructure/framework-src/onerror.js
new file mode 100644
index 0000000..f19a85f
--- /dev/null
+++ b/infrastructure/framework-src/onerror.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.errorHandler === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No error handler defined!");
+}
+
+// default content type for request
+response.setContentType('text/html; charset=utf-8');
+
+serverhandlers.errorHandler(appjet.context.attributes().apply("error"));
diff --git a/infrastructure/framework-src/onprint.js b/infrastructure/framework-src/onprint.js
new file mode 100644
index 0000000..8e334fe
--- /dev/null
+++ b/infrastructure/framework-src/onprint.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.postRequestHandler !== undefined) {
+ serverhandlers.postRequestHandler();
+}
diff --git a/infrastructure/framework-src/onrequest.js b/infrastructure/framework-src/onrequest.js
new file mode 100644
index 0000000..d76c8db
--- /dev/null
+++ b/infrastructure/framework-src/onrequest.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.requestHandler === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No request handler defined!");
+}
+
+// default content type for request
+response.setContentType('text/html; charset=utf-8');
+
+serverhandlers.requestHandler();
diff --git a/infrastructure/framework-src/onreset.js b/infrastructure/framework-src/onreset.js
new file mode 100644
index 0000000..24b000a
--- /dev/null
+++ b/infrastructure/framework-src/onreset.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.resetHandler !== undefined) {
+ serverhandlers.resetHandler();
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/onsars.js b/infrastructure/framework-src/onsars.js
new file mode 100644
index 0000000..31dc8ca
--- /dev/null
+++ b/infrastructure/framework-src/onsars.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.sarsHandler === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No SARS handler defined.");
+}
+
+if (serverhandlers.sarsHandler !== undefined) {
+ (function() {
+ var ret = serverhandlers.sarsHandler(appjet.context.attributes().apply("sarsRequest"));
+ if (ret)
+ appjet.context.attributes().update("sarsResponse", ret);
+ })()
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/onscheduledtask.js b/infrastructure/framework-src/onscheduledtask.js
new file mode 100644
index 0000000..810c3b5
--- /dev/null
+++ b/infrastructure/framework-src/onscheduledtask.js
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function() {
+ if (serverhandlers.tasks === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No task handlers defined!");
+ }
+ var taskName = appjet.context.attributes().apply("taskName");
+ if (serverhandlers.tasks[taskName] === undefined) {
+ throw new Packages.net.appjet.oui.NoHandlerException("No handler defined for task: "+taskName);
+ }
+ var taskArgs = appjet.context.attributes().apply("taskArguments");
+ var argsArray = [];
+ if (taskArgs != null) {
+ for (var i = 0; i < taskArgs.length; ++i) {
+ argsArray.push(taskArgs[i]);
+ }
+ }
+ return serverhandlers.tasks[taskName].apply(null, argsArray);
+})(); \ No newline at end of file
diff --git a/infrastructure/framework-src/onshutdown.js b/infrastructure/framework-src/onshutdown.js
new file mode 100644
index 0000000..0243bf6
--- /dev/null
+++ b/infrastructure/framework-src/onshutdown.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.shutdownHandler !== undefined) {
+ serverhandlers.shutdownHandler();
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/onstartup.js b/infrastructure/framework-src/onstartup.js
new file mode 100644
index 0000000..61feff7
--- /dev/null
+++ b/infrastructure/framework-src/onstartup.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (serverhandlers.startupHandler !== undefined) {
+ serverhandlers.startupHandler();
+} \ No newline at end of file
diff --git a/infrastructure/framework-src/onsyntaxerror.js b/infrastructure/framework-src/onsyntaxerror.js
new file mode 100644
index 0000000..7129a16
--- /dev/null
+++ b/infrastructure/framework-src/onsyntaxerror.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+printSyntaxError(); \ No newline at end of file
diff --git a/infrastructure/framework-src/postamble.js b/infrastructure/framework-src/postamble.js
new file mode 100644
index 0000000..76fa766
--- /dev/null
+++ b/infrastructure/framework-src/postamble.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+_appjethidden_.finishImports();
+
diff --git a/infrastructure/framework-src/preamble.js b/infrastructure/framework-src/preamble.js
new file mode 100644
index 0000000..40f6845
--- /dev/null
+++ b/infrastructure/framework-src/preamble.js
@@ -0,0 +1,325 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// appjetContext.cache_requestCache()._t_start = (new Date()).valueOf();
+var _appjethidden_ = {};
+var serverhandlers = { tasks: {} };
+
+/*
+ * @overview
+ *
+ * AppJet standard library preamble.
+ *
+ * This is run at the beginning of every request, right after all
+ * native calls are loaded into appjetContext. This file is run
+ * in the same scope as the app, the global scope, which is also
+ * accessible from all modules.
+ */
+
+//----------------------------------------------------------------
+// delete pesky rhino built-in string stuff
+//----------------------------------------------------------------
+(function() {
+ // rhino strings come with a bunch of random "html helpers"
+ // that we don't want
+ var htmlStuff = ["bold", "italics", "fixed", "strike",
+ "small", "big", "sub", "fontsize", "fontcolor", "link",
+ "anchor", "sup", "blink"];
+ for(var i in htmlStuff) {
+ delete String.prototype[htmlStuff[i]];
+ }
+})();
+
+//----------------------------------------------------------------
+// module implementation
+//----------------------------------------------------------------
+
+(function(globalScope) {
+
+ //----------------------------------------------------------------
+ // Utility Functions
+ //----------------------------------------------------------------
+ function appjetContext() {
+ return net.appjet.oui.ExecutionContextUtils.currentContext();
+ }
+ function internalError(m) {
+ throw new Error("AppJet Internal Error: "+m);
+ }
+ function apiError(m) {
+ throw new Error("AppJet API Error: "+m);
+ }
+ function newScope() {
+ var o = new Object();
+ o.__parent__ = null;
+ o.__proto__ = globalScope;
+ return o;
+ }
+ _appjethidden_._debugMessage = function(m) {
+ //java.lang.System.out.println(m);
+ };
+ var debug = _appjethidden_._debugMessage;
+ function copySymbol(srcName, symName, src, dst, dstSymName) {
+ if (!src.hasOwnProperty(symName)) {
+ apiError("Import error: module \""+srcName+"\" does not contain the symbol \""+symName+"\".");
+ }
+ if (symName.charAt(0) == '_') {
+ apiError("Import error: cannot import symbol \""+symName+"\" because it is private (begins with _)");
+ }
+ debug(" | copying symbol ["+symName+"]");
+ dst[dstSymName || symName] = src[symName];
+ }
+ function copyPublicSymbols(src, dst) {
+ for (k in src) {
+ if (src.hasOwnProperty(k) && (k.length > 0) && (k.charAt(0) != '_')) {
+ copySymbol('', k, src, dst);
+ }
+ }
+ }
+
+ // Module import cache... hidden from other scopes.
+ var moduleObjects = {};
+ var modulesBeingLoaded = {};
+
+ /*--------------------------------------------------------------------------------
+ * loadModule():
+ * Evaluates moduleName in its own private scope, then copies its public identifiers
+ * into a new scope. This new scope is stored in moduleObjects[moduleName] for future use
+ * by import()s.
+ *
+ * If moduleName is currently being loaded (because we are in the middle of another loadModule()
+ * higher in the call stack), then this function does noething, on the assumption
+ * that moduleName will eventually be loaded anyway. Therefore, it cannot be assumed that
+ * moduleName is done being loaded when loadModule() returns, only that it eventually will be
+ * loaded when all loadModule calls return up the call stack.
+ *--------------------------------------------------------------------------------*/
+ function loadModule(moduleName) {
+ if (modulesBeingLoaded[moduleName]) {
+ // This is OK. The module will be loaded eventually.
+ return;
+ }
+ if (moduleObjects[moduleName]) {
+ return;
+ }
+ modulesBeingLoaded[moduleName] = true;
+ try {
+ debug("loadModule: "+moduleName);
+
+ var modulePrivateScope =
+ Packages.net.appjet.ajstdlib.ajstdlib.runModuleInNewScope(
+ appjetContext(), moduleName.split('.').join('/'));
+
+ if (!modulePrivateScope) {
+ // moduleName is not a module. This is normal, because when someone calls
+ // import("foo.bar"), we dont know if bar is a module or an identifier in the foo module.
+ delete modulesBeingLoaded[moduleName];
+ return;
+ }
+ // Thinking this could be useful:
+ // modulePrivateScope['__MODULE_NAME__'] = moduleName;
+ var moduleObj = newScope();
+ copyPublicSymbols(modulePrivateScope, moduleObj);
+ moduleObjects[moduleName] = moduleObj;
+ } finally {
+ delete modulesBeingLoaded[moduleName];
+ }
+ }
+
+ /*--------------------------------------------------------------------------------
+ * importSingleModule():
+ *
+ * Takes a single moduleName (like "etherpad.foo.bar.baz") and creates the identifier "baz"
+ * in dstScope, referencing the module etherpad.foo.bar.baz.
+ *
+ * This function is called one or more times by importPath(). Note that importPath() is more like
+ * the import() function that modules ses.
+ *--------------------------------------------------------------------------------*/
+ function importSingleModule(moduleName, dstScope) {
+ debug("importSingleModule: "+moduleName);
+ if (typeof(moduleName) != 'string') {
+ apiError("modules should be referred to with string, not "+typeof(moduleName));
+ }
+
+ var moduleObj = moduleObjects[moduleName]; // public module scope
+ if (!moduleObj) {
+ return false;
+ }
+
+ var importedName = moduleName;
+ if (importedName.indexOf(".") != -1) {
+ importedName = importedName.split(".").slice(-1)[0];
+ }
+ dstScope[importedName] = moduleObj;
+ return true;
+ }
+
+ /*--------------------------------------------------------------------------------
+ * importPath():
+ * takes a modulePath (like "a.b.c.{d,e,f}" or "a.b.*" or just "a.b" or "a") and
+ * repeatedly calls importSingleModule() as necessary, copying public symbols into dst.
+ *--------------------------------------------------------------------------------*/
+ function importPath(modulePath, dst) {
+ debug("importPath: "+modulePath);
+
+ // Two possibilties:
+ // 1. import the exact module and that's it.
+ //
+ // 2. module contains a "." and we need to import up to the
+ // last ., and then import a name (or set of names) from it.
+
+ // first try case 1:
+ var ok = importSingleModule(modulePath, dst);
+ if (ok) {
+ return;
+ }
+
+ if (modulePath.indexOf(".") == -1) {
+ throw new Error("Module does not exist: "+modulePath);
+ }
+
+ // now try case 2:
+ var tempDst = newScope();
+ var moduleName = modulePath.split('.').slice(0, -1).join('.');
+ var importedName = modulePath.split('.').slice(-1)[0];
+ var lastName = modulePath.split('.').slice(-2, -1)[0];
+
+ ok = importSingleModule(moduleName, tempDst);
+ if (!ok) {
+ throw new Error("Neither module exists: "+moduleName+", "+modulePath);
+ }
+
+ if (!tempDst[lastName]) {
+ internalError("import failed for "+moduleName+"|"+importedName+". This could be an appjet bug.");
+ }
+ if (importedName == "*") {
+ copyPublicSymbols(tempDst[lastName], dst);
+ } else if (importedName.match(/^\{.*\}$/)) {
+ importedName.slice(1,-1).split(',').forEach(function(sym) {
+ if (sym.match(/^.*=>.*$/)) {
+ copySymbol(moduleName, sym.split("=>")[0], tempDst[lastName], dst, sym.split("=>")[1]);
+ } else {
+ copySymbol(moduleName, sym, tempDst[lastName], dst);
+ }
+ });
+ } else {
+ copySymbol(moduleName, importedName, tempDst[lastName], dst);
+ }
+ }
+
+ //----------------------------------------------------------------
+ // scheduling
+ //----------------------------------------------------------------
+
+ var scheduledImports = [];
+
+ function scheduleImportPath(p, dst) {
+ scheduledImports.push([p, dst]);
+ }
+
+ function runScheduledImports() {
+ scheduledImports.forEach(function(x) {
+ importPath(x[0], x[1]);
+ });
+ }
+
+ //----------------------------------------------------------------
+ // The global import function
+ //----------------------------------------------------------------
+
+ _appjethidden_.importsAllowed = true;
+
+ globalScope['import'] = function(path1, path2, etc) {
+ if (!_appjethidden_.importsAllowed) {
+ throw Error("Imports are finished. No more imports are allowed.");
+ }
+
+ var dstScope = this;
+ if (arguments.length < 1) {
+ apiError("importModule() takes the name of at least one module as an argument.");
+ }
+ for (var i = 0; i < arguments.length; i++) {
+ var path = arguments[i];
+ debug("scheduling import: "+path);
+ scheduleImportPath(path, dstScope);
+ // evaluate all modules in this path.
+ var parts = path.split('.');
+ for (var j = 0; j < parts.length; j++) {
+ var moduleName = parts.slice(0,j+1).join('.');
+ loadModule(moduleName);
+ }
+ }
+ };
+
+ _appjethidden_.finishImports = function() {
+ debug("Running scheduled imports...");
+ runScheduledImports();
+ _appjethidden_.importsAllowed = false;
+ };
+
+ //----------------------------------------------------------------
+ // jimport
+ //----------------------------------------------------------------
+ function _jimportSinglePackage(pname, dstScope) {
+ //_appjethidden_._debugMessage("_jimportSinglePackage: "+pname);
+ // TODO: support "*" and "{}" syntax like scala.
+ var src = Packages;
+ var srcParent = null;
+ var localName = pname.split(".").pop();
+ var soFar = '';
+
+ pname.split(".").forEach(function(x) {
+ soFar += x+'.';
+ if (!src[x]) {
+ throw ('Could not find java package/class: '+soFar);
+ } else {
+ //_appjethidden_._debugMessage("descenting into "+src+"["+x+"]");
+ srcParent = src;
+ src = src[x];
+ }
+ });
+
+ if (String(src).indexOf('function') == 0) {
+ // TODO: checking String(src).indexOf('function') is rather brittle.
+ // is there a cleaner way?
+ // TODO: this only works on static functions... so make sure
+ // src[x] is a static function!
+ dstScope[localName] = function() {
+ return src.apply(srcParent, Array.prototype.slice.call(arguments));
+ };
+ } else {
+ // importing a regular java class
+ dstScope[localName] = src;
+ }
+ }
+
+ /**
+ * Import a java package over LiveConnect.
+ */
+ globalScope['jimport'] = function() {
+ var dstScope = this;
+ for (var i = 0; i < arguments.length; i++) {
+ var pname = arguments[i].split(".").pop();
+ _jimportSinglePackage(arguments[i], dstScope);
+ }
+ };
+
+ //----------------------------------------------------------------
+ // {appjet, request, response} imported by default
+ //----------------------------------------------------------------
+ globalScope['import'].call(globalScope,
+ "global.appjet.appjet", "global.request.request", "global.response.response");
+
+})(this);
+
diff --git a/infrastructure/framework-src/syntaxerror.js b/infrastructure/framework-src/syntaxerror.js
new file mode 100644
index 0000000..801066b
--- /dev/null
+++ b/infrastructure/framework-src/syntaxerror.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("exceptionutils");
+
+function printSyntaxError() {
+ var ex = appjet.context.attributes().apply("error");
+
+ //java.lang.System.out.println("Syntax error: "+ex);
+
+ if (response.isDefined) {
+ response.reset();
+ response.setContentType('text/html; charset=utf-8');
+ response.write(exceptionutils.getStackTraceFullpage(ex));
+ } else {
+ java.lang.System.out.println("Syntax error: "+exceptionutils.getStackTracePlain(ex));
+ }
+}
+
diff --git a/infrastructure/lib/activation.jar b/infrastructure/lib/activation.jar
new file mode 100644
index 0000000..29a59a9
--- /dev/null
+++ b/infrastructure/lib/activation.jar
Binary files differ
diff --git a/infrastructure/lib/c3p0-0.9.1.2.jar b/infrastructure/lib/c3p0-0.9.1.2.jar
new file mode 100644
index 0000000..0f42d60
--- /dev/null
+++ b/infrastructure/lib/c3p0-0.9.1.2.jar
Binary files differ
diff --git a/infrastructure/lib/commons-lang-2.4.jar b/infrastructure/lib/commons-lang-2.4.jar
new file mode 100644
index 0000000..532939e
--- /dev/null
+++ b/infrastructure/lib/commons-lang-2.4.jar
Binary files differ
diff --git a/infrastructure/lib/derby-10.5.1.1.jar b/infrastructure/lib/derby-10.5.1.1.jar
new file mode 100644
index 0000000..2820dbd
--- /dev/null
+++ b/infrastructure/lib/derby-10.5.1.1.jar
Binary files differ
diff --git a/infrastructure/lib/derbytools.jar b/infrastructure/lib/derbytools.jar
new file mode 100644
index 0000000..4aa76e1
--- /dev/null
+++ b/infrastructure/lib/derbytools.jar
Binary files differ
diff --git a/infrastructure/lib/dnsjava-2.0.6.jar b/infrastructure/lib/dnsjava-2.0.6.jar
new file mode 100644
index 0000000..e41f9b0
--- /dev/null
+++ b/infrastructure/lib/dnsjava-2.0.6.jar
Binary files differ
diff --git a/infrastructure/lib/jetty-6.1.20.jar b/infrastructure/lib/jetty-6.1.20.jar
new file mode 100644
index 0000000..8f45db9
--- /dev/null
+++ b/infrastructure/lib/jetty-6.1.20.jar
Binary files differ
diff --git a/infrastructure/lib/jetty-sslengine-6.1.20.jar b/infrastructure/lib/jetty-sslengine-6.1.20.jar
new file mode 100644
index 0000000..6f7d232
--- /dev/null
+++ b/infrastructure/lib/jetty-sslengine-6.1.20.jar
Binary files differ
diff --git a/infrastructure/lib/jetty-util-6.1.20.jar b/infrastructure/lib/jetty-util-6.1.20.jar
new file mode 100644
index 0000000..96c0979
--- /dev/null
+++ b/infrastructure/lib/jetty-util-6.1.20.jar
Binary files differ
diff --git a/infrastructure/lib/json.jar b/infrastructure/lib/json.jar
new file mode 100644
index 0000000..5ab955c
--- /dev/null
+++ b/infrastructure/lib/json.jar
Binary files differ
diff --git a/infrastructure/lib/mail.jar b/infrastructure/lib/mail.jar
new file mode 100644
index 0000000..e6f7083
--- /dev/null
+++ b/infrastructure/lib/mail.jar
Binary files differ
diff --git a/infrastructure/lib/manifest b/infrastructure/lib/manifest
new file mode 100644
index 0000000..b91a5a7
--- /dev/null
+++ b/infrastructure/lib/manifest
@@ -0,0 +1,2 @@
+Manifest-Version: 0.1
+Main-Class: com.etherpad.main
diff --git a/infrastructure/lib/rhino-js-1.7r1.jar b/infrastructure/lib/rhino-js-1.7r1.jar
new file mode 100644
index 0000000..79f8529
--- /dev/null
+++ b/infrastructure/lib/rhino-js-1.7r1.jar
Binary files differ
diff --git a/infrastructure/lib/sanselan-0.94aj.jar b/infrastructure/lib/sanselan-0.94aj.jar
new file mode 100644
index 0000000..0fd8c96
--- /dev/null
+++ b/infrastructure/lib/sanselan-0.94aj.jar
Binary files differ
diff --git a/infrastructure/lib/servlet-api-2.5-20081211.jar b/infrastructure/lib/servlet-api-2.5-20081211.jar
new file mode 100644
index 0000000..f1bfa12
--- /dev/null
+++ b/infrastructure/lib/servlet-api-2.5-20081211.jar
Binary files differ
diff --git a/infrastructure/lib/tagsoup-1.2.jar b/infrastructure/lib/tagsoup-1.2.jar
new file mode 100644
index 0000000..af27803
--- /dev/null
+++ b/infrastructure/lib/tagsoup-1.2.jar
Binary files differ
diff --git a/infrastructure/lib/yuicompressor-2.4-appjet.jar b/infrastructure/lib/yuicompressor-2.4-appjet.jar
new file mode 100644
index 0000000..b5bdfc1
--- /dev/null
+++ b/infrastructure/lib/yuicompressor-2.4-appjet.jar
Binary files differ
diff --git a/infrastructure/net.appjet.ajstdlib/ajstdlib.scala b/infrastructure/net.appjet.ajstdlib/ajstdlib.scala
new file mode 100644
index 0000000..8d285af
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/ajstdlib.scala
@@ -0,0 +1,253 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.ajstdlib;
+
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.{ScheduledThreadPoolExecutor, Callable};
+import scala.collection.mutable.{HashMap, SynchronizedMap};
+
+import org.mozilla.javascript.{Context, ScriptableObject, Function, RhinoException, Scriptable};
+
+import net.appjet.oui.{SpecialJarOrNotFile, DiskLibrary, FixedDiskLibrary, VariableDiskLibrary, ExecutionContext, ExecutionContextUtils, ScopeReuseManager, config, exceptionlog};
+import net.appjet.bodylock.{BodyLock, ExecutionException};
+import net.appjet.common.util.LenientFormatter;
+
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.util.ajax.ContinuationSupport;
+
+object ajstdlib {
+ def runModuleInNewScope(cx: ExecutionContext, moduleName: String): Any = {
+ val newScope = BodyLock.subScope(cx.runner.globalScope);
+ if (! libraryExists(moduleName))
+ return Context.getUndefinedValue(); // unfortunately, returning "false" doesn't really do the right thing here.
+ try {
+ libraryExecutable(moduleName).execute(newScope);
+ } catch {
+ case e: ExecutionException => throw e;
+ case e => throw new ExecutionException("Error occurred while running module: "+moduleName, e);
+ // TODO: There was code here to print errors to the response if something didn't compile. Replace this code?
+ }
+ newScope;
+ }
+
+ private val modules = new HashMap[String, DiskLibrary] with SynchronizedMap[String, DiskLibrary];
+ private def library(name: String) = modules.getOrElseUpdate(name+".js", new VariableDiskLibrary(name+".js"));
+ private def libraryExists(name: String) = {
+ val lib = library(name);
+ // ScopeReuseManager.watch(lib);
+ lib.exists;
+ }
+ private def libraryExecutable(name: String) = {
+ val lib = library(name);
+ // ScopeReuseManager.watch(lib);
+ lib.executable;
+ }
+
+ val globalLock = new ReentrantLock();
+ val attributes = new HashMap[String, Any] with SynchronizedMap[String, Any];
+
+ def init() {
+ // any other ajstdlib initialization goes here.
+ Comet.init();
+ }
+}
+
+object printf {
+ def printf(format: String, list: Array[Object]): String = {
+// val list: Array[Object] = new Array[Object](argList.getLength)
+// for (i <- List.range(0, list.length))
+// list(i) = argList.getElement(i).getOrElse(null) match {
+// case AppVM.JSNumber(n) => n
+// case AppVM.JSString(s) => s
+// case AppVM.JSBoolean(b) => b
+// case _ => null
+// }
+ val args = list.map(x => Context.jsToJava(x, classOf[Object]));
+ try {
+ val fmt = new LenientFormatter()
+ fmt.format(format, args: _*)
+ fmt.toString()
+ } catch {
+ case e: java.util.IllegalFormatException =>
+ throw new ExecutionException("String Format Error: <tt>printf</tt> error: "+e.getMessage(), e)
+ }
+ }
+}
+
+
+import java.security.MessageDigest;
+
+object md5 {
+ def md5(input: String): String = {
+ val bytes = input.getBytes("UTF-8");
+ md5(bytes);
+ }
+ def md5(bytes: Array[byte]): String = {
+ var md = MessageDigest.getInstance("MD5");
+ var digest = md.digest(bytes);
+ var builder = new StringBuilder();
+ for (b <- digest) {
+ builder.append(Integer.toString((b >> 4) & 0xf, 16));
+ builder.append(Integer.toString(b & 0xf, 16));
+ }
+ builder.toString();
+ }
+}
+
+object execution {
+ def runAsync(ec: ExecutionContext, f: Function) {
+ ec.asyncs += f;
+ }
+
+ def executeCodeInNewScope(parentScope: Scriptable,
+ code: String, name: String,
+ startLine: Int): Scriptable = {
+ val ec = ExecutionContextUtils.currentContext;
+ val executable =
+ try {
+ BodyLock.compileString(code, name, startLine);
+ } catch {
+ case e: RhinoException =>
+ throw new ExecutionException(
+ "Failed to execute code in new scope.", e);
+ }
+ if (ec == null || ec.runner == null) {
+ Thread.dumpStack();
+ }
+ val scope = BodyLock.subScope(
+ if (parentScope != null) parentScope
+ else ec.runner.mainScope);
+ scope.setParentScope(ec.runner.mainScope);
+ executable.execute(scope);
+ scope;
+ }
+
+ def runTask(taskName: String, args: Array[Object]): AnyRef = {
+ val ec = net.appjet.oui.execution.runOutOfBand(
+ net.appjet.oui.execution.scheduledTaskExecutable,
+ "Task "+taskName,
+ Some(Map("taskName" -> taskName,
+ "taskArguments" -> args)),
+ { error =>
+ error match {
+ case e: Throwable => exceptionlog(e);
+ case _ => exceptionlog(error.toString);
+ }
+ });
+ ec.result;
+ }
+
+ def runTaskSimply(taskName: String, args: Array[Object]): AnyRef = {
+ net.appjet.oui.execution.runOutOfBandSimply(
+ net.appjet.oui.execution.scheduledTaskExecutable,
+ Some(Map("taskName" -> taskName,
+ "taskArguments" -> args)));
+ }
+
+ def wrapRunTask(taskName: String, args: Array[Object],
+ returnType: Class[_]): Function0[AnyRef] = {
+ new Function0[AnyRef] {
+ def apply = Context.jsToJava(runTaskSimply(taskName, args), returnType);
+ }
+ }
+
+ val threadpools = new HashMap[String, ScheduledThreadPoolExecutor]
+ with SynchronizedMap[String, ScheduledThreadPoolExecutor];
+
+ def createNamedTaskThreadPool(name: String, poolSize: Int) {
+ threadpools.put(name, new ScheduledThreadPoolExecutor(poolSize));
+ }
+
+ class TaskRunner(val taskName: String, args: Array[Object]) extends Callable[AnyRef] {
+ def call(): AnyRef = {
+ runTask(taskName, args);
+ }
+ }
+
+ def scheduleTaskInPool(poolName: String, taskName: String, delayMillis: Long, args: Array[Object]) = {
+ val pool = threadpools.getOrElse(poolName, throw new RuntimeException("No such task threadpool: "+poolName));
+ pool.schedule(new TaskRunner(taskName, args), delayMillis, java.util.concurrent.TimeUnit.MILLISECONDS);
+ }
+
+ def shutdownAndWaitOnTaskThreadPool(poolName: String, timeoutMillis: Long) = {
+ val pool = threadpools.getOrElse(poolName, throw new RuntimeException("No such task threadpool: "+poolName));
+ pool.shutdown();
+ pool.awaitTermination(timeoutMillis, java.util.concurrent.TimeUnit.MILLISECONDS);
+ }
+
+ def getContinuation(ec: ExecutionContext) = {
+ val req = ec.request.req;
+ ContinuationSupport.getContinuation(req, req).asInstanceOf[SelectChannelConnector.RetryContinuation];
+ }
+
+ def sync[T](obj: AnyRef)(block: => T): T = {
+ obj.synchronized {
+ block;
+ }
+ }
+}
+
+import javax.mail._;
+import javax.mail.internet._;
+import java.util.Properties;
+
+object email {
+ def sendEmail(toAddr: Array[String], fromAddr: String, subject: String, headers: Scriptable, content: String): String = {
+ try {
+ val badAddresses = for (a <- toAddr if (a.indexOf("@") == -1)) yield a;
+ if (badAddresses.length > 0) {
+ "The email address"+(if (badAddresses.length > 1) "es" else "")+" "+
+ badAddresses.mkString("\"", "\", \"", "\"")+" do"+(if (badAddresses.length == 1) "es" else "")+
+ " not appear to be valid.";
+ } else {
+ val debug = false;
+
+ val props = new Properties;
+ props.put("mail.smtp.host", config.smtpServerHost);
+ props.put("mail.smtp.port", config.smtpServerPort.toString());
+ if (config.smtpUser != "")
+ props.put("mail.smtp.auth", "true");
+
+ val session = Session.getInstance(props, if (config.smtpUser != "") new Authenticator {
+ override def getPasswordAuthentication() =
+ new PasswordAuthentication(config.smtpUser, config.smtpPass);
+ } else null);
+ session.setDebug(debug);
+
+ val msg = new MimeMessage(session);
+ val fromIAddr = new InternetAddress(fromAddr);
+ msg.setFrom(fromIAddr);
+ val toIAddr: Array[Address] = toAddr.map(x => (new InternetAddress(x))); // new InternetAddress(toAddr);
+ msg.setRecipients(Message.RecipientType.TO, toIAddr);
+
+ if (headers != null)
+ for (o <- headers.getIds() if o.isInstanceOf[String]) {
+ val k = o.asInstanceOf[String]
+ msg.addHeader(k, headers.get(k, headers).asInstanceOf[String]);
+ }
+
+ msg.setSubject(subject);
+ msg.setContent(content, "text/plain");
+ Transport.send(msg);
+ "";
+ }
+ } catch {
+ case e: MessagingException => { exceptionlog(e); e.printStackTrace() ; "Messaging exception: "+e.getMessage+"."; }
+ case e: Exception => { exceptionlog(e); e.printStackTrace(); "Unknown error."; }
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.ajstdlib/sqlbase.scala b/infrastructure/net.appjet.ajstdlib/sqlbase.scala
new file mode 100644
index 0000000..047c086
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/sqlbase.scala
@@ -0,0 +1,563 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.ajstdlib;
+
+import scala.collection.mutable.ArrayBuffer;
+
+import java.sql.{DriverManager, SQLException, Statement};
+import net.appjet.oui.{profiler, config, NoninheritedDynamicVariable};
+import com.mchange.v2.c3p0._;
+
+class SQLBase(driverClass: String, url: String, userName: String, password: String) {
+
+ def isMysql:Boolean = (url.startsWith("jdbc:mysql:"));
+ def isDerby:Boolean = (url.startsWith("jdbc:derby:"));
+
+ if (isDerby) {
+ System.setProperty("derby.system.home", config.derbyHome);
+ val f = new java.io.File(config.derbyHome);
+ if (! f.exists) {
+ if (! f.mkdirs())
+ throw new RuntimeException("Couldn't create internal database storage directory: "+config.derbyHome);
+ }
+ if (! f.isDirectory)
+ throw new RuntimeException("Internal database storage directory is not a directory: "+config.derbyHome);
+ if (! f.canWrite)
+ throw new RuntimeException("Can't write to internal database storage directory: "+config.derbyHome);
+ }
+
+ val cpds = new ComboPooledDataSource();
+ cpds.setDriverClass(driverClass);
+ cpds.setJdbcUrl(url+(if (isMysql) "?useUnicode=true&characterEncoding=utf8" else ""));
+
+ // derby does not require a password
+ if (!isDerby) {
+ cpds.setUser(userName);
+ cpds.setPassword(password);
+ }
+
+ cpds.setMaxPoolSize(config.jdbcPoolSize);
+ cpds.setMaxConnectionAge(6*60*60); // 6 hours
+ if (config.devMode) {
+ cpds.setAutomaticTestTable("cpds_testtable");
+ cpds.setTestConnectionOnCheckout(true);
+ }
+
+// {
+// // register db driver
+// try {
+// new JDCConnectionDriver(driverClass, url+"?useUnicode=true&characterEncoding=utf8", userName, password);
+// } catch {
+// case e => {
+// e.printStackTrace();
+// Runtime.getRuntime.halt(1);
+// }
+// }
+// }
+
+ private def getConnectionFromPool = {
+ val c = cpds.getConnection();
+ c.setAutoCommit(true);
+ c;
+ }
+
+ // Creates a dynamic variable whose .value depends on the innermost
+ // .withValue(){} on the call-stack.
+ private val currentConnection = new NoninheritedDynamicVariable[Option[java.sql.Connection]](None);
+
+ def withConnection[A](block: java.sql.Connection=>A): A = {
+ currentConnection.value match {
+ case Some(c) => {
+ block(c);
+ }
+ case None => {
+ val t1 = profiler.time;
+ val c = getConnectionFromPool;
+ profiler.recordCumulative("getConnection", profiler.time-t1);
+ try {
+ currentConnection.withValue(Some(c)) {
+ block(c);
+ }
+ } finally {
+ c.close;
+ }
+ }
+ }
+ }
+
+ private val currentlyInTransaction = new NoninheritedDynamicVariable(false);
+
+ def inTransaction[A](block: java.sql.Connection=>A): A = {
+ withConnection(c => {
+ if (currentlyInTransaction.value) {
+ return block(c);
+ } else {
+ currentlyInTransaction.withValue(true) {
+ c.setAutoCommit(false);
+ c.setTransactionIsolation(java.sql.Connection.TRANSACTION_REPEATABLE_READ);
+
+ try {
+ val result = block(c);
+ c.commit();
+ c.setAutoCommit(true);
+ result;
+ } catch {
+ case e@net.appjet.oui.AppGeneratedStopException => {
+ c.commit();
+ c.setAutoCommit(true);
+ throw e;
+ }
+ case (e:org.mozilla.javascript.WrappedException) if (e.getWrappedException ==
+ net.appjet.oui.AppGeneratedStopException) => {
+ c.commit();
+ c.setAutoCommit(true);
+ throw e;
+ }
+ case e => {
+ //println("inTransaction() caught error:");
+ //e.printStackTrace();
+ try {
+ c.rollback();
+ c.setAutoCommit(true);
+ } catch {
+ case ex => {
+ println("Could not rollback transaction because: "+ex.toString());
+ }
+ }
+ throw e;
+ }
+ }
+ }
+ }
+ });
+ }
+
+ def closing[A](closable: java.sql.Statement)(block: =>A): A = {
+ try { block } finally { closable.close(); }
+ }
+
+ def closing[A](closable: java.sql.ResultSet)(block: =>A): A = {
+ try { block } finally { closable.close(); }
+ }
+
+ def tableName(t: String) = id(t);
+
+ val identifierQuoteString = withConnection(_.getMetaData.getIdentifierQuoteString);
+ def quoteIdentifier(s: String) = identifierQuoteString+s+identifierQuoteString;
+ private def id(s: String) = quoteIdentifier(s);
+
+ def longTextType = if (isDerby) "CLOB" else "MEDIUMTEXT";
+
+ // derby seems to do things intelligently w.r.t. case-sensitivity and unicode support.
+ def createTableOptions = if (isMysql) " ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin" else "";
+
+ // creates table if it doesn't exist already
+ def createJSONTable(table: String) {
+ withConnection { c=>
+ val s = c.createStatement;
+ if (! doesTableExist(c, table)) {
+ closing(s) {
+ s.execute("CREATE TABLE "+tableName(table)+" ("+
+ id("ID")+" VARCHAR(128) PRIMARY KEY NOT NULL, "+
+ id("JSON")+" "+longTextType+" NOT NULL"+
+ ")"+createTableOptions);
+ }
+ }
+ }
+ }
+
+ // requires: table exists
+ // returns null if key doesn't exist
+ def getJSON(table: String, key: String): String = {
+ withConnection { c=>
+ val s = c.prepareStatement("SELECT "+id("JSON")+" FROM "+tableName(table)+" WHERE "+id("ID")+" = ?");
+ closing(s) {
+ s.setString(1, key);
+ var resultSet = s.executeQuery();
+ closing(resultSet) {
+ if (! resultSet.next()) {
+ null;
+ }
+ else {
+ resultSet.getString(1);
+ }
+ }
+ }
+ }
+ }
+
+ def getAllJSON(table: String, start: Int, count: Int): Array[Object] = {
+ withConnection { c =>
+ val s = c.prepareStatement("SELECT "+id("ID")+","+id("JSON")+" FROM "+tableName(table)+
+ " ORDER BY "+id("ID")+" DESC"+
+ " LIMIT ? OFFSET ?");
+ closing(s) {
+ s.setInt(2, start);
+ s.setInt(1, count);
+ var resultSet = s.executeQuery();
+ var output = new ArrayBuffer[Object];
+ closing(resultSet) {
+ while (resultSet.next()) {
+ output += new { val id = resultSet.getString(1); val value = resultSet.getString(2) };
+ }
+ output.toArray;
+ }
+ }
+ }
+ }
+
+ def getAllJSONKeys(table: String): Array[String] = {
+ withConnection { c =>
+ val s = c.prepareStatement("SELECT "+id("ID")+" FROM "+tableName(table));
+ closing(s) {
+ var resultSet = s.executeQuery();
+ var output = new ArrayBuffer[String];
+ closing(resultSet) {
+ while (resultSet.next()) {
+ output += resultSet.getString(1);
+ }
+ output.toArray;
+ }
+ }
+ }
+ }
+
+ // requires: table exists
+ // inserts key if it doesn't exist
+ def putJSON(table: String, key: String, json: String) {
+ withConnection { c=>
+ val update = c.prepareStatement("UPDATE "+tableName(table)+" SET "+id("JSON")+"=? WHERE "+id("ID")+"=?");
+ closing(update) {
+ update.setString(1, json);
+ update.setString(2, key);
+ update.executeUpdate();
+ if (update.getUpdateCount == 0) {
+ val insert = c.prepareStatement(
+ "INSERT INTO "+tableName(table)+" ("+id("ID")+", "+id("JSON")+") values (?,?)");
+ closing(insert) {
+ insert.setString(1, key);
+ insert.setString(2, json);
+ insert.executeUpdate();
+ }
+ }
+ }
+ }
+ }
+
+ def deleteJSON(table: String, key: String) {
+ // requires: table exists
+ withConnection { c=>
+ val update = c.prepareStatement("DELETE FROM "+tableName(table)+" WHERE "+id("ID")+"=?");
+ closing(update) {
+ update.setString(1, key);
+ update.executeUpdate();
+ }
+ }
+ }
+
+ private def metaName(table: String) = table+"_META";
+ private def metaTableName(table: String) = tableName(metaName(table));
+ private def textTableName(table: String) = tableName(table+"_TEXT");
+ private def escapeSearchString(dbm: java.sql.DatabaseMetaData, s: String): String = {
+ val e = dbm.getSearchStringEscape();
+ s.replace("_", e+"_").replace("%", e+"%");
+ }
+
+ private final val PAGE_SIZE = 20;
+
+ def doesTableExist(connection: java.sql.Connection, table: String): Boolean = {
+ val databaseMetadata = connection.getMetaData;
+ val tables = databaseMetadata.getTables(null, null,
+ escapeSearchString(databaseMetadata, table), null);
+ closing(tables) {
+ tables.next();
+ }
+ }
+
+ def autoIncrementClause = if (isDerby) "GENERATED BY DEFAULT AS IDENTITY" else "AUTO_INCREMENT";
+
+ // creates table if it doesn't exist already
+ def createStringArrayTable(table: String) {
+ withConnection { c=>
+ if (! doesTableExist(c, metaName(table))) { // check to see if the *_META table exists
+ // create tables and indices
+ val s = c.createStatement;
+ closing(s) {
+ s.execute("CREATE TABLE "+metaTableName(table)+" ("+
+ id("ID")+" VARCHAR(128) PRIMARY KEY NOT NULL, "+
+ id("NUMID")+" INT UNIQUE "+autoIncrementClause+" "+
+ ")"+createTableOptions);
+ val defaultOffsets = (1 to PAGE_SIZE).map(x=>"").mkString(",");
+ s.execute("CREATE TABLE "+textTableName(table)+" ("+
+ ""+id("NUMID")+" INT, "+id("PAGESTART")+" INT, "+id("OFFSETS")+" VARCHAR(256) NOT NULL DEFAULT '"+defaultOffsets+
+ "', "+id("DATA")+" "+longTextType+" NOT NULL"+
+ ")"+createTableOptions);
+ s.execute("CREATE INDEX "+id(table+"-NUMID-PAGESTART")+" ON "+textTableName(table)+"("+id("NUMID")+", "+id("PAGESTART")+")");
+ }
+ }
+ }
+ }
+
+ // requires: table exists
+ // returns: null if key or (key,index) doesn't exist, else the value
+ def getStringArrayElement(table: String, key: String, index: Int): String = {
+ val (pageStart, offset) = getPageStartAndOffset(index);
+ val page = new StringArrayPage(table, key, pageStart, true);
+ page.data(offset);
+ }
+
+ // requires: table exists
+ // returns: an array of the mappings present in the page that should hold the
+ // particular (key,index) mapping. the array may be empty or otherwise not
+ // contain the given (key,index).
+ def getPageStringArrayElements(table: String, key: String, index: Int): Array[IndexValueMapping] = {
+ val (pageStart, offset) = getPageStartAndOffset(index);
+ val page = new StringArrayPage(table, key, pageStart, true);
+ val buf = new scala.collection.mutable.ListBuffer[IndexValueMapping];
+
+ for(i <- 0 until page.data.length) {
+ val s = page.data(i);
+ if (s ne null) {
+ val n = pageStart + i;
+ buf += IndexValueMapping(n, s);
+ }
+ }
+
+ buf.toArray;
+ }
+
+ // requires: table exists
+ // creates key if doesn't exist
+ // value may be null
+ def putStringArrayElement(table: String, key: String, index: Int, value: String) {
+ val (pageStart, offset) = getPageStartAndOffset(index);
+ val page = new StringArrayPage(table, key, pageStart, false);
+ page.data(offset) = value;
+ page.updateDB();
+ }
+
+ def putMultipleStringArrayElements(table: String, key: String): Multiputter = new Multiputter {
+ var currentPage = None:Option[StringArrayPage];
+ def flushPage() {
+ if (currentPage.isDefined) {
+ val page = currentPage.get;
+ page.updateDB();
+ currentPage = None;
+ }
+ }
+ def finish() {
+ flushPage();
+ }
+ def put(index: Int, value: String) {
+ try {
+ val (pageStart, offset) = getPageStartAndOffset(index);
+ if (currentPage.isEmpty || currentPage.get.pageStart != pageStart) {
+ flushPage();
+ currentPage = Some(new StringArrayPage(table, key, pageStart, false));
+ }
+ currentPage.get.data(offset) = value;
+ }
+ catch {
+ case e => { e.printStackTrace; throw e }
+ }
+ }
+ }
+
+ trait Multiputter {
+ def put(index: Int, value: String);
+ def finish();
+ }
+
+ case class IndexValueMapping(index: Int, value: String);
+
+ def clearStringArray(table: String, key: String) {
+ withConnection { c=>
+ val numid = getStringArrayNumId(c, table, key, false);
+ if (numid >= 0) {
+ {
+ val s = c.prepareStatement("DELETE FROM "+textTableName(table)+" WHERE "+id("NUMID")+"=?");
+ closing(s) {
+ s.setInt(1, numid);
+ s.executeUpdate();
+ }
+ }
+ {
+ val s = c.prepareStatement("DELETE FROM "+metaTableName(table)+" WHERE "+id("NUMID")+"=?");
+ closing(s) {
+ s.setInt(1, numid);
+ s.executeUpdate();
+ }
+ }
+ }
+ }
+ }
+
+ private def getPageStartAndOffset(index: Int): (Int,Int) = {
+ val pageStart = (index / PAGE_SIZE) * PAGE_SIZE;
+ (pageStart, index - pageStart);
+ }
+
+ // requires: table exists
+ // returns: numid of new string array
+ private def newStringArray(c: java.sql.Connection, table: String, key: String): Int = {
+ val s = c.prepareStatement("INSERT INTO "+metaTableName(table)+" ("+id("ID")+") VALUES (?)",
+ Statement.RETURN_GENERATED_KEYS);
+ closing(s) {
+ s.setString(1, key);
+ s.executeUpdate();
+ val resultSet = s.getGeneratedKeys;
+ if (resultSet == null)
+ error("No generated numid for insert");
+ closing(resultSet) {
+ if (! resultSet.next()) error("No generated numid for insert");
+ resultSet.getInt(1);
+ }
+ }
+ }
+
+ def getStringArrayNumId(c: java.sql.Connection, table: String, key: String, creating: Boolean): Int = {
+ val s = c.prepareStatement("SELECT "+id("NUMID")+" FROM "+metaTableName(table)+" WHERE "+id("ID")+"=?");
+ closing(s) {
+ s.setString(1, key);
+ val resultSet = s.executeQuery();
+ closing(resultSet) {
+ if (! resultSet.next()) {
+ if (creating) {
+ newStringArray(c, table, key);
+ }
+ else {
+ -1
+ }
+ }
+ else {
+ resultSet.getInt(1);
+ }
+ }
+ }
+ }
+
+ def getStringArrayAllKeys(table: String): Array[String] = {
+ withConnection { c=>
+ val s = c.prepareStatement("SELECT "+id("ID")+" FROM "+metaTableName(table));
+ closing(s) {
+ val resultSet = s.executeQuery();
+ closing(resultSet) {
+ val buf = new ArrayBuffer[String];
+ while (resultSet.next()) {
+ buf += resultSet.getString(1);
+ }
+ buf.toArray;
+ }
+ }
+ }
+ }
+
+ private class StringArrayPage(table: String, key: String, val pageStart: Int, readonly: Boolean) {
+
+ val data = new Array[String](PAGE_SIZE);
+
+ private val numid = withConnection { c=>
+ val nid = getStringArrayNumId(c, table, key, ! readonly);
+
+ if (nid >= 0) {
+ val s = c.prepareStatement(
+ "SELECT "+id("OFFSETS")+","+id("DATA")+" FROM "+textTableName(table)+" WHERE "+id("NUMID")+"=? AND "+id("PAGESTART")+"=?");
+ closing(s) {
+ s.setInt(1, nid);
+ s.setInt(2, pageStart);
+ val resultSet = s.executeQuery();
+ closing(resultSet) {
+ if (! resultSet.next()) {
+ if (! readonly) {
+ val insert = c.prepareStatement("INSERT INTO "+textTableName(table)+
+ " ("+id("NUMID")+", "+id("PAGESTART")+", "+id("DATA")+") VALUES (?,?,'')");
+ closing(insert) {
+ insert.setInt(1, nid);
+ insert.setInt(2, pageStart);
+ insert.executeUpdate();
+ }
+ }
+ }
+ else {
+ val offsetsField = resultSet.getString(1);
+ val dataField = resultSet.getString(2);
+ val offsetStrings = offsetsField.split(",", -1);
+ var i = 0;
+ var idx = 0;
+ while (i < PAGE_SIZE) {
+ val nstr = offsetStrings(i);
+ if (nstr != "") {
+ val n = nstr.toInt;
+ data(i) = dataField.substring(idx, idx+n);
+ idx += n;
+ }
+ i += 1;
+ }
+ }
+ }
+ }
+ }
+ nid;
+ }
+
+ def updateDB() {
+ if (readonly) {
+ error("this is a readonly StringArrayPage");
+ }
+ // assert: the relevant row of the TEXT table exists
+ if (data.find(_ ne null).isEmpty) {
+ withConnection { c=>
+ val update = c.prepareStatement("DELETE FROM "+textTableName(table)+
+ " WHERE "+id("NUMID")+"=? AND "+id("PAGESTART")+"=?");
+ closing(update) {
+ update.setInt(1, numid);
+ update.setInt(2, pageStart);
+ update.executeUpdate();
+ }
+ }
+ }
+ else {
+ val offsetsStr = data.map(s => if (s eq null) "" else s.length.toString).mkString(",");
+ val dataStr = data.map(s => if (s eq null) "" else s).mkString("");
+ withConnection { c=>
+ val s = c.prepareStatement("UPDATE "+textTableName(table)+
+ " SET "+id("OFFSETS")+"=?, "+id("DATA")+"=? WHERE "+id("NUMID")+"=? AND "+id("PAGESTART")+"=?");
+ closing(s) {
+ s.setString(1, offsetsStr);
+ s.setString(2, dataStr);
+ s.setInt(3, numid);
+ s.setInt(4, pageStart);
+ s.executeUpdate();
+ }
+ }
+ }
+ }
+ }
+
+ def close {
+ if (isDerby) {
+ cpds.close();
+ try {
+ DriverManager.getConnection("jdbc:derby:;shutdown=true");
+ } catch {
+ case e: SQLException => if (e.getErrorCode() != 50000) throw e
+ }
+ }
+ }
+}
+
+
diff --git a/infrastructure/net.appjet.ajstdlib/streaming-client.js b/infrastructure/net.appjet.ajstdlib/streaming-client.js
new file mode 100644
index 0000000..3bfa227
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/streaming-client.js
@@ -0,0 +1,920 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var host = window.location.host;
+
+function WebSocket(id) {
+ var self = this;
+ var socket = this;
+ var version = 2;
+
+ var timeouts = {};
+
+ this.onopen = function() { }
+ this.onclosed = function() { }
+ this.onmessage = function() { }
+ this.onhiccup = function() { }
+ this.onlogmessage = function() { }
+ this.CONNECTING = 0;
+ this.OPEN = 1;
+ this.CLOSED = 2;
+ this.readyState = -1;
+
+ var hiccupsLastMinute = 0;
+ var hiccupResetInterval = setInterval(function() {
+ hiccupsLastMinute = 0;
+ if (self.readyState == self.CLOSED)
+ clearInterval(hiccupResetInterval);
+ }, 60*1000);
+
+ var isHiccuping = false;
+ function hiccup(channel) {
+ if (channel != officialChannel && channel != self) return;
+ if (isHiccuping) return;
+ log("hiccup: "+channel.name);
+ if (hiccupsLastMinute++ > 10) {
+ doDisconnect({reconnect: true, reason: "Too many hiccups!"});
+ return;
+ }
+ closeAllChannels();
+ timeout(timeouts, "hiccup", 15000, function() {
+ isHiccuping = false;
+ doDisconnect({reconnect: false, reason: "Couldn't contact server to hiccup."});
+ });
+ isHiccuping = true;
+ function tryHiccup() {
+ if (! isHiccuping) return;
+ self.onhiccup({connected: false});
+ log("trying hiccup");
+ timeout(timeouts, "singleHiccup", 5000, function() {
+ tryHiccup();
+ });
+ simpleXhr('post', postPath(), true, [{key: "oob", value: "hiccup"}], function(sc, msg) {
+ if (! isHiccuping) return;
+ if (msg.substring(0, "restart-fail".length) == "restart-fail") {
+ doDisconnect({reconnect: true, reason: "Server restarted or socket timed out on server."});
+ } else if (sc != 200 || msg.substring(0, 2) != "ok") {
+ log("Failed to hiccup with error: "+sc+" / "+msg);
+ setTimeout(tryHiccup, 500);
+ } else {
+ isHiccuping = false;
+ timeouts.singleHiccup();
+ timeouts.hiccup();
+ doConnect();
+ }
+ });
+ }
+ tryHiccup();
+ }
+ function closeAllChannels() {
+ for (var i in activeChannels) {
+ if (activeChannels.hasOwnProperty(i)) {
+ activeChannels[i].disconnect();
+ }
+ }
+ officialChannel = undefined;
+ }
+
+ function doDisconnect(obj, silent, sync) {
+ log("disconnected: "+obj.reason+" / "+(obj.data !== undefined ? "data: "+obj.data : ""));
+ logAll();
+ closeAllChannels();
+ if (longPollingIFrame && longPollingIFrame.div) {
+ longPollingIFrame.div.innerHTML = "";
+ }
+ if (self.readyState != self.CLOSED) {
+ self.readyState = self.CLOSED;
+ if (! silent) {
+ postSingleMessageNow(true, "kill:"+obj.reason, sync, true);
+ }
+ self.onclosed(obj);
+ }
+ }
+
+ this.disconnect = function(sync) {
+ doDisconnect({reason: "Closed by client."}, false, sync);
+ }
+
+
+ function doBasicConnect() {
+ var type = getBasicChannel();
+ log("basic connect on type: "+type);
+ var channel = activeChannels[type] = new channelConstructors[type]();
+ channel.connect();
+ }
+
+ function doOtherConnect() {
+ var channels = getOtherChannels();
+ var channel; var type;
+ for (var i = 0; i < channels.length; ++i) {
+ type = channels[i];
+ log("other connect on type: "+type);
+ channel = activeChannels[type] = new channelConstructors[type]();
+ channel.connect();
+ }
+ }
+ function doConnect() {
+ log("doing connect!");
+ timeout(timeouts, "connect", 15000, function() {
+ doDisconnect({reconnect: false, reason: "Timeout connecting to server: no channel type was able to connect."});
+ });
+ doBasicConnect();
+ }
+
+ this.connect = function() {
+ log("socket connecting: "+id);
+ doConnect();
+ }
+
+ // util
+ function nicetime() { return Math.floor((new Date()).valueOf() / 100) % 10000000; }
+ function log(s) { self.onlogmessage("(comet @t: "+nicetime()+") "+s); }
+ function logAll() {
+ log(self.describe())
+ }
+ this.describe = function() {
+ function describeChannels() {
+ out = [];
+ for (var i in activeChannels) {
+ if (activeChannels.hasOwnProperty(i)) {
+ out.push(i+": "+activeChannels[i].describe());
+ }
+ }
+ return "[ "+out.join(", ")+" ]";
+ }
+ return ("socket state: { id: "+id+", readyState: "+self.readyState+", isHiccuping: "+isHiccuping+", timeouts: "+describeTimeouts(timeouts)+", officialChannel: "+(officialChannel?officialChannel.name:"none")+", channels: "+describeChannels()+", isPosting: "+isPosting+", lastReceivedSeqNumber: "+lastReceivedSeqNumber+", lastPost: "+lastPost+", postTimeouts: "+describeTimeouts(postTimeouts)+", channelSeq: "+channelSeq+" }");
+ }
+
+ function wrapMethod(obj, method) {
+ return function() {
+ var arr = [];
+ for (var i=0; i < arguments.length; i++) {
+ arr.push(arguments[i]);
+ }
+ method.apply(obj, arr);
+ }
+ }
+ var _wm = wrapMethod;
+
+ // cb should take statusCode, responseText, and optionally request
+ function simpleXhr(method, uri, async, params, cb, makeXhr) {
+// log("making simple Xhr: "+[method, uri, async, params].join(", "));
+ var request = (makeXhr || newRequestObject)();
+ request.open(method, uri, async);
+ if (async) {
+ request.onreadystatechange = function() {
+ if (request.readyState != 4) return;
+ var status;
+ var responseText;
+ try {
+ status = request.status;
+ responseText = request.responseText;
+ } catch (e) { /* absorb ff error accessing request properties */ }
+ cb(status, responseText, request);
+ }
+ }
+ var data = null;
+ if (params) {
+ data = [];
+ for (var i = 0; i < params.length; ++i) {
+ data.push(encodeURIComponent(params[i].key)+"="+encodeURIComponent(params[i].value));
+ }
+ data = data.join("&");
+ request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
+ }
+ try {
+ request.send(data);
+ } catch (e) { request.abort(); cb(500, "Error sending data!", request); }
+ if (! async) {
+ var status;
+ var responseText;
+ try {
+ status = request.status;
+ responseText = request.responseText;
+ } catch (e) { /* absorb ff error accessing request properties */ }
+ cb(status, responseText, request);
+ }
+ return request;
+ }
+
+ var timeout_noop = function() { }
+ function timeout(timeoutObject, timeoutName, millis, timeoutCallback) {
+ function clearIt(timeoutObject, timeoutName) {
+ if (timeoutObject[timeoutName]) {
+ timeoutObject[timeoutName]();
+ timeoutObject[timeoutName] = timeout_noop;
+ }
+ }
+ var timeoutId = setTimeout(function() { clearIt(timeoutObject, timeoutName); timeoutCallback(); }, millis);
+ var f = function() {
+ clearTimeout(timeoutId);
+ }
+ clearIt(timeoutObject, timeoutName);
+ timeoutObject[timeoutName] = f;
+ return f;
+ }
+
+ // handling messages
+ var lastReceivedSeqNumber = 0;
+
+ function dataHandler(msg) {
+ if (msg.seqNumber > lastReceivedSeqNumber+1) {
+ log("bad sequence number. expecting: "+(lastReceivedSeqNumber+1)+", got: "+msg.seqNumber);
+ hiccup(self);
+ return false;
+ }
+ if (msg.seqNumber < lastReceivedSeqNumber+1) return true;
+ lastReceivedSeqNumber = msg.seqNumber;
+ if (! msg.isControl) {
+ self.onmessage({ data: msg.content });
+ return true;
+ } else {
+ if (msg.content == "kill") {
+ doDisconnect({reconnect: false, reason: "Killed by server."});
+ return false;
+ }
+ }
+ }
+
+ // client-server comm
+ var postPath = function() {
+ return "%contextPath%/post?r="+randomVar()+"&v="+version+"&id="+id+"&seq="+lastReceivedSeqNumber;
+ }
+
+ function SimpleQueue() {
+ var base = [];
+ var head = 0;
+ var tail = 0;
+ this.offer = function(data) {
+ base[tail++] = data;
+ }
+ this.poll = function() {
+ if (this.length() > 0) {
+ var n = base[head];
+ delete base[head++];
+ return n;
+ }
+ }
+ this.clear = function() {
+ head = 0;
+ tail = 0;
+ var oldBase = base;
+ base = [];
+ return oldBase;
+ }
+ this.length = function() {
+ return tail - head;
+ }
+ }
+ var outgoingMessageQueue = new SimpleQueue();
+ var isPosting = false;
+ var postTimeouts = {};
+ var lastPost;
+
+ function postSingleMessageNow(isControl, data, sync, force, cb) {
+ doPostMessages([{oob: isControl, data: data, cb: cb}], sync, force)
+ }
+
+ function doPostMessages(messages, sync, force, cb) {
+ if (! force && self.readyState == self.CLOSED) return;
+ if (messages.length == 0) {
+ if (cb) cb();
+ return;
+ }
+ var data = [];
+ var callbacks = [];
+ for (var i = 0; i < messages.length; ++i) {
+ data.push({key: (messages[i].oob ? "oob" : "m"),
+ value: messages[i].data});
+ if (messages[i].cb)
+ callbacks.push(messages[i].cb);
+ }
+ function postFailed(sc, msg, req, src) {
+ var str = "";
+ try {
+ str = sc + ": "+req.statusText+" - "+msg+" ("+src+")";
+ } catch (e) { /* absorb potential Firefox error accessing req */ }
+ doDisconnect({reconnect: true, reason: "Posting message failed.", data: str});
+ for (var i = 0; i < callbacks.length; ++i) {
+ callbacks[i](false, str);
+ }
+ }
+ function postCallback(sc, msg, request) {
+ postTimeouts.post();
+ if (sc != 200 || msg.substring(0, 2) != "ok") {
+ postFailed(sc, msg, request, "1");
+ } else {
+ for (var i = 0; i < callbacks.length; ++i) {
+ callbacks[i](true);
+ }
+ if (cb) cb();
+ }
+ }
+ timeout(postTimeouts, "post", 15000, function() {
+ doDisconnect({reconnect: true, reason: "Posting message timed out."});
+ });
+ simpleXhr('post', postPath(), ! sync, data, postCallback);
+ }
+
+ function postPendingMessages() {
+ if (isPosting == true)
+ return;
+ var messages = outgoingMessageQueue.clear();
+ if (messages.length == 0) {
+ return;
+ }
+ isPosting = true;
+ doPostMessages(messages, false, false, function() { isPosting = false; setTimeout(postPendingMessages, 0); });
+ lastPost = nicetime();
+ }
+ this.postMessage = function(data, cb) {
+ if (self.readyState != self.OPEN) {
+ return;
+ }
+ outgoingMessageQueue.offer({data: data, cb: cb});
+ setTimeout(function() { postPendingMessages() }, 0);
+ }
+
+ // transports
+ function getValidChannels() {
+ var channels = [];
+ for (var i = 0; i < validChannels.length; ++i) {
+ var type = validChannels[i];
+ if (window.location.hash.length > 0) {
+ if (window.location.hash != "#"+type) {
+ continue;
+ }
+ }
+ if ($ && $.browser.opera && type != 'shortpolling' && type != 'streaming') {
+ continue;
+ }
+ channels.push(type);
+ }
+ return channels;
+ }
+ function getBasicChannel() {
+ return getValidChannels()[0];
+ }
+
+ function getOtherChannels() {
+ return getValidChannels().slice(1);
+ }
+
+ var officialChannel;
+ this.getTransportType = function() {
+ return (officialChannel ? officialChannel.name : "none");
+ }
+ var validChannels = "%acceptableChannelTypes%";
+ var canUseSubdomains = "%canUseSubdomains%";
+ var activeChannels = {};
+ var channelConstructors = {
+ shortpolling: ShortPollingChannel,
+ longpolling: LongPollingChannel,
+ streaming: StreamingChannel
+ }
+
+ function describeTimeouts(timeouts) {
+ var out = [];
+ for (var i in timeouts) {
+ if (timeouts.hasOwnProperty(i)) {
+ out.push(i+": "+(timeouts[i] == timeout_noop ? "unset" : "set"));
+ }
+ }
+ return "{ "+out.join(", ")+" }";
+ }
+
+ var channelSeq = 1;
+ function notifyConnect(channel) {
+ timeouts.connect();
+ if (! officialChannel || channel.weight > officialChannel.weight) {
+ log("switching to use channel: "+channel.name);
+ var oldChannel = officialChannel;
+ officialChannel = channel;
+ setTimeout(function() {
+ postSingleMessageNow(true, "useChannel:"+(channelSeq++)+":"+channel.name, false, false, function(success, msg) {
+ if (success) {
+ if (oldChannel) {
+ oldChannel.disconnect();
+ } else {
+ // there was no old channel, so try connecting the other channels.
+ doOtherConnect();
+ }
+ if (self.readyState != self.OPEN) {
+ self.readyState = self.OPEN;
+ self.onopen({});
+ } else {
+ self.onhiccup({connected: true});
+ }
+ } else {
+ doDisconnect({reconnect: true, reason: "Failed to select channel on server.", data: msg});
+ }
+ });
+ }, 0);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function randomVar() {
+ return String(Math.round(Math.random()*1e12));
+ }
+
+ function channelPath() {
+ return "%contextPath%/channel?v="+version+"&r="+randomVar()+"&id="+id;
+ }
+
+ function newRequestObject() {
+ var xmlhttp=false;
+ try {
+ xmlhttp = (window.ActiveXObject && new ActiveXObject("Msxml2.XMLHTTP"))
+ } catch (e) {
+ try {
+ xmlhttp = (window.ActiveXObject && new ActiveXObject("Microsoft.XMLHTTP"));
+ } catch (E) {
+ xmlhttp = false;
+ }
+ }
+ if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
+ try {
+ xmlhttp = new XMLHttpRequest();
+ } catch (e) {
+ xmlhttp=false;
+ }
+ }
+ if (!xmlhttp && window.createRequest) {
+ try {
+ xmlhttp = window.createRequest();
+ } catch (e) {
+ xmlhttp=false;
+ }
+ }
+ return xmlhttp
+ }
+
+ function DataFormatError(message) {
+ this.message = message;
+ }
+
+ function readMessage(data, startIndex) {
+ if (! startIndex) startIndex = 0;
+ var sep = data.indexOf(":", startIndex);
+ if (sep < 0) return; // don't have all the bytes for this yet.
+ var chars = Number(data.substring(startIndex, sep));
+ if (isNaN(chars))
+ throw new DataFormatError("Bad length: "+data.substring(startIndex, sep));
+ if (data.length < sep+1+chars) return; // don't have all the bytes for this yet.
+ var msg = data.substr(sep+1, chars);
+ return { message: msg, lastConsumedChar: sep+1+chars }
+ }
+
+ function iframeReader(data, startIndex) {
+ if (startIndex == 0)
+ return { message: data, lastConsumedChar: data.length }
+ }
+
+ function parseWireFormat(data, startIndex, reader) {
+ if (! startIndex) startIndex = 0;
+ var msgs = [];
+ var readThroughIndex = startIndex;
+ while (true) {
+ var msgObj = (reader || readMessage)(data, readThroughIndex)
+ if (! msgObj) break;
+ readThroughIndex = msgObj.lastConsumedChar;
+ var msg = msgObj.message;
+ var split = msg.split(":");
+ if (split[0] == 'oob') {
+ msgs.push({oob: split.slice(1).join(":")});
+ continue;
+ }
+ var seq = Number(split[0]);
+ if (isNaN(seq))
+ throw new DataFormatError("Bad sequence number: "+split[0]);
+ var control = Number(split[1]);
+ if (isNaN(control))
+ throw new DataFormatError("Bad control: "+split[1]);
+ var msgContent = split.slice(2).join(":");
+ msgs.push({seqNumber: seq, isControl: (control == 1), content: msgContent});
+ }
+ return { messages: msgs, lastConsumedChar: readThroughIndex }
+ }
+
+ function handleMessages(data, cursor, channel, reader) {
+ try {
+ messages = parseWireFormat(data, cursor, reader);
+ } catch (e) {
+ if (e instanceof DataFormatError) {
+ log("Data format error: "+e.message);
+ hiccup(channel);
+ return;
+ } else {
+ log(e.toString()+" on line: "+e.lineNumber);
+ }
+ }
+ for (var i=0; i < messages.messages.length; i++) {
+ var oob = messages.messages[i].oob;
+ if (oob) {
+ if (oob == "restart-fail") {
+ doDisconnect({reconnect: true, reason: "Server restarted or socket timed out on server."});
+ return;
+ }
+ } else {
+ if (! dataHandler(messages.messages[i]))
+ break;
+ }
+ }
+ return messages.lastConsumedChar;
+ }
+
+ function ShortPollingChannel() {
+ this.weight = 0;
+ this.name = "shortpolling";
+
+ this.isConnected = false;
+ this.isClosed = false;
+ this.request;
+ this.clearRequest = function() {
+ if (this.request) {
+ this.request.abort();
+ this.request = null;
+ }
+ }
+ this.timeouts = {};
+
+ this.describe = function() {
+ return "{ isConnected: "+this.isConnected+", isClosed: "+this.isClosed+", timeouts: "+describeTimeouts(this.timeouts)+", request: "+(this.request?"set":"not set")+" }"
+ }
+
+ this.pollDataHandler = function(sc, response, request) {
+ if (request.readyState != 4) return;
+ if (this.timeouts.poll) this.timeouts.poll();
+ var messages;
+ if (! this.isConnected) {
+ this.timeouts.connectAttempt();
+ if (sc != 200) {
+ log(this.name+" connect failed: "+sc+" / "+response);
+ setTimeout(_wm(this, this.attemptConnect), 500);
+ return;
+ }
+ var msg = (response ? readMessage(response) : undefined);
+ if (msg && msg.message == "oob:ok") {
+ this.timeouts.initialConnect();
+ this.isConnected = true;
+ log(this.name+" transport connected!");
+ if (! notifyConnect(this)) {
+ // there are better options connected.
+ log(this.name+" transport not chosen for activation.");
+ this.disconnect();
+ return;
+ }
+ this.doPoll();
+ return;
+ } else {
+ log(this.name+" connect didn't get ok: "+sc+" / "+response);
+ setTimeout(_wm(this, this.attemptConnect), 500);
+ return;
+ }
+ }
+ var chars = handleMessages(request.responseText, 0, this);
+ if (sc != 200 || ((! chars) && this.emptyResponseBad)) {
+ hiccup(this);
+ }
+ setTimeout(_wm(this, this.doPoll), this.pollDelay);
+ this.clearRequest();
+ }
+
+ this.keepRetryingConnection = true;
+ this.cancelConnect = function() {
+ this.clearRequest();
+ this.keepRetryingConnection = false;
+ }
+ this.cancelPoll = function() {
+ this.clearRequest();
+ log("poll timed out.");
+ hiccup(this);
+ }
+
+ this.doPoll = function() {
+ if (this.isClosed) return;
+ timeout(this.timeouts, "poll", this.pollTimeout, _wm(this, this.cancelPoll));
+ this.request =
+ simpleXhr('GET',
+ channelPath()+"&channel="+this.name+"&seq="+lastReceivedSeqNumber+this.pollParams(),
+ true, undefined, _wm(this, this.pollDataHandler), this.xhrGenerator);
+ }
+
+ this.pollParams = function() {
+ return "";
+ }
+ this.pollTimeout = 5000;
+ this.pollDelay = 500;
+
+ this.attemptConnect = function() {
+ if (! this.keepRetryingConnection) return;
+ log(this.name+" attempting connect");
+ this.clearRequest();
+ timeout(this.timeouts, "connectAttempt", 5000, _wm(this, this.attemptConnect));
+ this.request = simpleXhr('GET', channelPath()+"&channel="+this.name+"&new=yes&create="+(socket.readyState == socket.OPEN ? "no" : "yes")+"&seq="+lastReceivedSeqNumber,
+ true, undefined, _wm(this, this.pollDataHandler), this.xhrGenerator);
+ }
+ this.connect = function() {
+ this.attemptConnect();
+ timeout(this.timeouts, "initialConnect", 15000, _wm(this, this.cancelConnect));
+ }
+ this.disconnect = function() {
+ log(this.name+" disconnected");
+ this.isClosed = true;
+ this.clearRequest();
+ }
+ }
+
+ function StreamingChannel() {
+ this.weight = 2;
+ this.name = "streaming";
+ var self = this;
+
+ var isConnected = false;
+ var request;
+ function clearRequest() {
+ if (request) {
+ request.abort();
+ request = null;
+ if (theStream) theStream = null;
+ if (ifrDiv) {
+ ifrDiv.innerHTML = "";
+ ifrDiv = null;
+ }
+ }
+ }
+ var isClosed = false;
+ var timeouts = {};
+ var cursor = 0;
+
+ this.describe = function() {
+ return "{ isConnected: "+isConnected+", isClosed: "+isClosed+", timeouts: "+describeTimeouts(timeouts)+", request: "+(request?"set":"not set")+", cursor: "+cursor+" }";
+ };
+
+ function connectOk() {
+ isConnected = true;
+ timeouts.initialConnect();
+ if (! notifyConnect(self)) {
+ log("streaming transport not chosen for activation");
+ self.disconnect();
+ return;
+ }
+ }
+
+ function streamDataHandler() {
+ if (timeouts.data) timeouts.data();
+ if (isClosed) return;
+ try {
+ if (! request.responseText) return;
+ } catch (e) { return; }
+ if (! isConnected) {
+ var msg = readMessage(request.responseText, cursor);
+ if (! msg) return;
+ cursor = msg.lastReceivedSeqNumber;
+ if (msg.message == "oob:ok") {
+ connectOk();
+ } else {
+ log("stream: incorrect channel connect message:"+msg.message);
+ self.disconnect();
+ return;
+ }
+ } else {
+ cursor = handleMessages(request.responseText, cursor, self);
+ }
+ if (! request || request.readyState == 4) {
+ clearRequest();
+ if (isConnected) {
+ log("stream connection unexpectedly closed.");
+ hiccup(self);
+ return;
+ }
+ }
+ timeout(timeouts, "data", 60*1000, function() { hiccup(self); });
+ }
+
+ function iframeDataHandler(data) {
+ if (isClosed) return;
+ if (! isConnected) {
+ if (data == "oob:ok") {
+ connectOk();
+ } else {
+ log("iframe stream: unexpected data on connect - "+data);
+ }
+ } else {
+ handleMessages(data, 0, self, iframeReader);
+ }
+ }
+
+ function cancelConnect() {
+ isClosed = true;
+ clearRequest();
+ log("stream: failed to connect.");
+ }
+
+ // IE Stuff.
+ var theStream;
+ var ifrDiv;
+ var iframeTestCount = 0;
+ function testIframe() {
+ var state;
+ try {
+ state = ifrDiv.firstChild.readyState;
+ } catch (e) {
+ hiccup(self);
+ return;
+ }
+ if (state == 'interactive' || iframeTestCount > 10) {
+ try { var tmp = ifrDiv.firstChild.contentWindow.document.getElementById("thebody") }
+ catch (e) { hiccup(self); }
+ } else {
+ iframeTestCount++;
+ setTimeout(testIframe, 500);
+ }
+ }
+
+ this.connect = function() {
+ timeout(timeouts, "initialConnect", 15000, cancelConnect)
+
+ if (canUseSubdomains) {
+ var streamurl = "//"+randomVar()+".comet."+host+channelPath()+"&channel=streaming&type=iframe&new=yes&create="+(socket.readyState == socket.OPEN ? "no" : "yes")+"&seq="+lastReceivedSeqNumber;
+ log("stream to: "+streamurl);
+ if ($ && $.browser.opera) {
+ // set up the opera stream; requires jquery because, why not?
+ ifrDiv = $('<div style="display: none;"></div>').get(0);
+ $('body').append(ifrDiv);
+ window.comet = {
+ pass_data: iframeDataHandler,
+ disconnect: function() { hiccup(self); }
+ }
+ $(ifrDiv).append($("<iframe src='"+streamurl+"'></iframe>"));
+ iframeTestCount = 0;
+ setTimeout(testIframe, 2000);
+ // if event-source supported disconnect notifications, fuck yeah we'd use it.
+// theStream = $('<event-source>');
+// var streamurl = channelPath()+"&channel=streaming&type=opera&new=yes&create="+(socket.readyState == socket.OPEN ? "no" : "yes")+"&seq="+lastReceivedSeqNumber;
+// theStream.get(0).addEventListener('message', function(event) {
+// iframeDataHandler(event.data);
+// }, false);
+// theStream.attr('src', streamurl);
+ log("stream connect sent!");
+ return;
+ }
+ try { // TODO: remove reference to both theStream and ifrDiv on unload!
+ theStream = (window.ActiveXObject && new ActiveXObject("htmlfile"));
+ if (theStream) {
+ theStream.open();
+ theStream.write("<html><head><title>f<\/title><\/head><body>")
+ theStream.write("<s"+"cript>document.domain='"+document.domain+"';<\/s"+"cript>")
+ theStream.write("<\/body><\/html>")
+ theStream.close();
+ ifrDiv = theStream.createElement("div")
+ theStream.appendChild(ifrDiv)
+ theStream.parentWindow.comet = {
+ pass_data: iframeDataHandler,
+ disconnect: function() { hiccup(self); }
+ }
+ ifrDiv.innerHTML = "<iframe src='"+streamurl+"'></iframe>";
+ iframeTestCount = 0;
+ setTimeout(testIframe, 2000);
+ }
+ } catch (e) {
+ theStream = false
+ }
+ } else if ($ && $.browser.opera) {
+ // opera thinks it can do a normal stream, but it can't.
+ log("opera - not trying xhr");
+ return;
+ }
+ // End IE Stuff.
+ if (! theStream) {
+ request = newRequestObject();
+ request.open('get', channelPath()+"&channel=streaming&new=yes&create="+(socket.readyState == socket.OPEN ? "no" : "yes")+"&seq="+lastReceivedSeqNumber);
+ request.onreadystatechange = streamDataHandler;
+ try {
+ request.send(null);
+ } catch (e) { }
+ }
+ log("stream connect sent!");
+ }
+
+ this.disconnect = function() {
+ log("stream disconnected");
+ isClosed = true;
+ clearRequest();
+ }
+ log("new streamchannel");
+ }
+
+ // long-polling related stuff.
+ function iframePath(key) {
+ return "//"+key+".comet."+host+"%contextPath%/xhrXdFrame";
+ }
+
+ function createHiddenDiv() {
+ if (! document.getElementById('newcomethidden')) {
+ var d = document.createElement('div');
+ d.setAttribute('id', 'newcomethidden');
+ d.style.display = 'none';
+ document.body.appendChild(d);
+ }
+ return document.getElementById('newcomethidden');
+ }
+
+ function ExtHostXHR(iframe) {
+ this.open = function(method, uri, async) {
+ this.method = method;
+ this.uri = uri;
+ this.async = async;
+ }
+ var headers = {};
+ this.setRequestHeader = function(name, value) {
+ headers[name] = value;
+ }
+ this.send = function(data) {
+ var self = this;
+ this.xhr = iframe.iframe.contentWindow.doAction(this.method, this.uri, this.async, headers, data || null, function(status, response) {
+ self.readyState = 4;
+ self.status = status;
+ self.responseText = response;
+ self.onreadystatechange();
+ });
+ }
+ this.abort = function() {
+ if (this.xhr)
+ iframe.contentWindow.doAbort(this.xhr);
+ }
+ }
+
+ function createRequestIframe(cb) {
+ var randomKey = randomVar();
+ try {
+ var activeXControl = (window.ActiveXObject && new ActiveXObject("htmlfile"));
+ var htmlfileDiv;
+ if (activeXControl) {
+ activeXControl.open();
+ activeXControl.write('<html><head><title>f</title></head><body>');
+ activeXControl.write('<scr'+'ipt>document.domain=\''+document.domain+'\';</scr'+'ipt>');
+ activeXControl.write('</body></html>');
+ activeXControl.close();
+ htmlfileDiv = activeXControl.createElement('div');
+ activeXControl.appendChild(htmlfileDiv);
+ activeXControl.parentWindow["done_"+randomKey] = cb;
+ htmlfileDiv.innerHTML = "<iframe src='"+iframePath(randomKey)+"'></iframe>";
+ return {iframe: htmlfileDiv.firstChild /* should be an iframe */, axc: activeXControl, div: htmlfileDiv};
+ }
+ } catch (e) {
+ activeXControl = false;
+ }
+ log("Not using IE setup.");
+ var requestIframe = document.createElement('iframe');
+ createHiddenDiv().appendChild(requestIframe);
+ window["done_"+randomKey] = function() { try { delete window["done_"+randomKey]; } catch (e) { }; cb(); }
+ requestIframe.src = iframePath(randomKey);
+ return {iframe: requestIframe};
+ }
+
+ function createIframeRequestObject() {
+ if (! longPollingIFrame) throw Error("WebSocket isn't properly set up!");
+ return new ExtHostXHR(longPollingIFrame);
+ }
+
+ var longPollingIFrame;
+ function LongPollingChannel() {
+ ShortPollingChannel.apply(this); // sets up other state.
+ this.weight = 1;
+ this.name = "longpolling";
+
+ this.pollDelay = 0;
+ this.pollTimeout = 15000;
+ this.pollParams = function() {
+ return "&timeout="+(this.pollTimeout-5000);
+ }
+ var connect = this.connect;
+ this.connect = function() {
+ if (! longPollingIFrame) {
+ longPollingIFrame =
+ createRequestIframe(_wm(this, connect)); // specifically *not* this.connect. we want the old one!
+ } else {
+ connect.apply(this);
+ }
+ }
+ this.xhrGenerator = createIframeRequestObject;
+ this.emptyResponseBad = true;
+ }
+} \ No newline at end of file
diff --git a/infrastructure/net.appjet.ajstdlib/streaming-iframe.html b/infrastructure/net.appjet.ajstdlib/streaming-iframe.html
new file mode 100644
index 0000000..3bdb5c4
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/streaming-iframe.html
@@ -0,0 +1,76 @@
+<html>
+<head>
+<script>
+function createRequestObject() {
+ var xmlhttp=false;
+ /*@cc_on @*/
+ /*@if (@_jscript_version >= 5)
+ try {
+ xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (E) {
+ xmlhttp = false;
+ }
+ }
+ @end @*/
+ if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
+ try {
+ xmlhttp = new XMLHttpRequest();
+ } catch (e) {
+ xmlhttp=false;
+ }
+ }
+ if (!xmlhttp && window.createRequest) {
+ try {
+ xmlhttp = window.createRequest();
+ } catch (e) {
+ xmlhttp=false;
+ }
+ }
+ return xmlhttp
+}
+var host = window.location.host;
+var oldDomain = document.domain;
+var newDomain = oldDomain.substring(oldDomain.indexOf(".", oldDomain.indexOf(".")+1)+1);
+
+function doAction(method, uri, async, headers, body, cb) {
+ try {
+ document.domain = oldDomain;
+ } catch (e) { }
+ var req = createRequestObject();
+ req.open(method, '//'+host+uri, async);
+ for (var i in headers) {
+ req.setRequestHeader(i, headers[i]);
+ }
+ req.onreadystatechange = function() {
+ if (req.readyState == 4) {
+ try {
+ document.domain = newDomain;
+ cb(req.status, req.responseText);
+ } catch (e) {
+ // yikes. well, hopefully a timeout will notice this error.
+ }
+ }
+ }
+ req.send(body);
+}
+function doAbort(xhr) {
+ try {
+ document.domain = oldDomain;
+ } catch (e) { }
+ xhr.abort();
+}
+document.domain = newDomain;
+window.onload = function() {
+ var doneKey = 'done_'+oldDomain.split(".", 2)[0];
+ setTimeout(function() {
+ window.parent[doneKey]();
+ }, 0);
+}
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/infrastructure/net.appjet.ajstdlib/streaming.scala b/infrastructure/net.appjet.ajstdlib/streaming.scala
new file mode 100644
index 0000000..fbff137
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/streaming.scala
@@ -0,0 +1,892 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.ajstdlib;
+
+import scala.collection.mutable.{Queue, HashMap, SynchronizedMap, ArrayBuffer};
+import javax.servlet.http.{HttpServletRequest, HttpServletResponse, HttpServlet};
+import org.mortbay.jetty.servlet.{ServletHolder, Context};
+import org.mortbay.jetty.{HttpConnection, Handler, RetryRequest};
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.io.nio.SelectChannelEndPoint;
+import org.mortbay.util.ajax.{ContinuationSupport, Continuation};
+
+import java.util.{Timer, TimerTask};
+import java.lang.ref.WeakReference;
+
+import org.mozilla.javascript.{Context => JSContext, Scriptable};
+
+import net.appjet.oui._;
+import net.appjet.oui.Util.enumerationToRichEnumeration;
+import net.appjet.common.util.HttpServletRequestFactory;
+
+trait SocketConnectionHandler {
+ def message(sender: StreamingSocket, data: String, req: HttpServletRequest);
+ def connect(socket: StreamingSocket, req: HttpServletRequest);
+ def disconnect(socket: StreamingSocket, req: HttpServletRequest);
+}
+
+object SocketManager {
+ val sockets = new HashMap[String, StreamingSocket] with SynchronizedMap[String, StreamingSocket];
+ val handler = new SocketConnectionHandler {
+ val cometLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "oncomet.js"));
+ def cometExecutable = cometLib.executable;
+
+ def message(socket: StreamingSocket, data: String, req: HttpServletRequest) {
+ val t1 = profiler.time;
+// println("Message from: "+socket.id+": "+data);
+ val runner = ScopeReuseManager.getRunner;
+ val ec = ExecutionContext(new RequestWrapper(req), new ResponseWrapper(null), runner);
+ ec.attributes("cometOperation") = "message";
+ ec.attributes("cometId") = socket.id;
+ ec.attributes("cometData") = data;
+ ec.attributes("cometSocket") = socket;
+ net.appjet.oui.execution.execute(
+ ec,
+ (sc: Int, msg: String) =>
+ throw new HandlerException(sc, msg, null),
+ () => {},
+ () => { ScopeReuseManager.freeRunner(runner); },
+ Some(cometExecutable));
+ cometlatencies.register(((profiler.time-t1)/1000).toInt);
+ }
+ def connect(socket: StreamingSocket, req: HttpServletRequest) {
+// println("Connect on: "+socket);
+ val runner = ScopeReuseManager.getRunner;
+ val ec = ExecutionContext(new RequestWrapper(req), new ResponseWrapper(null), runner);
+ ec.attributes("cometOperation") = "connect";
+ ec.attributes("cometId") = socket.id;
+ ec.attributes("cometSocket") = socket;
+ net.appjet.oui.execution.execute(
+ ec,
+ (sc: Int, msg: String) =>
+ throw new HandlerException(sc, msg, null),
+ () => {},
+ () => { ScopeReuseManager.freeRunner(runner); },
+ Some(cometExecutable));
+ }
+ def disconnect(socket: StreamingSocket, req: HttpServletRequest) {
+ val toRun = new Runnable {
+ def run() {
+ val runner = ScopeReuseManager.getRunner;
+ val ec = ExecutionContext(new RequestWrapper(req), new ResponseWrapper(null), runner);
+ ec.attributes("cometOperation") = "disconnect";
+ ec.attributes("cometId") = socket.id;
+ ec.attributes("cometSocket") = socket;
+ net.appjet.oui.execution.execute(
+ ec,
+ (sc: Int, msg: String) =>
+ throw new HandlerException(sc, msg, null),
+ () => {},
+ () => { ScopeReuseManager.freeRunner(runner); },
+ Some(cometExecutable));
+ }
+ }
+ main.server.getThreadPool().dispatch(toRun);
+ }
+ }
+ def apply(id: String, create: Boolean) = {
+ if (create) {
+ Some(sockets.getOrElseUpdate(id, new StreamingSocket(id, handler)));
+ } else {
+ if (id == null)
+ error("bad id: "+id);
+ sockets.get(id);
+ }
+ }
+ class HandlerException(val sc: Int, val msg: String, val cause: Exception)
+ extends RuntimeException("An error occurred while handling a request: "+sc+" - "+msg, cause);
+}
+
+// And this would be the javascript interface. Whee.
+object Comet extends CometSupport.CometHandler {
+ def init() {
+ CometSupport.cometHandler = this;
+ context.start();
+ }
+
+ val acceptableTransports = {
+ val t = new ArrayBuffer[String];
+ if (! config.disableShortPolling) {
+ t += "shortpolling";
+ }
+ if (config.transportUseWildcardSubdomains) {
+ t += "longpolling";
+ }
+ t += "streaming";
+ t.mkString("['", "', '", "']");
+ }
+
+
+ val servlet = new StreamingSocketServlet();
+ val holder = new ServletHolder(servlet);
+ val context = new Context(null, "/", Context.NO_SESSIONS | Context.NO_SECURITY);
+ context.addServlet(holder, "/*");
+ context.setMaxFormContentSize(1024*1024);
+
+ def handleCometRequest(req: HttpServletRequest, res: HttpServletResponse) {
+ context.handle(req.getRequestURI().substring(config.transportPrefix.length), req, res, Handler.FORWARD);
+ }
+
+ lazy val ccLib = new FixedDiskResource(new JarOrNotFile(config.ajstdlibHome, "streaming-client.js") {
+ override val classBase = "/net/appjet/ajstdlib/";
+ override val fileSep = "/../../net.appjet.ajstdlib/";
+ });
+ def clientCode(contextPath: String, acceptableChannelTypes: String) = {
+ ccLib.contents.replaceAll("%contextPath%", contextPath).replaceAll("\"%acceptableChannelTypes%\"", acceptableChannelTypes).replaceAll("\"%canUseSubdomains%\"", if (config.transportUseWildcardSubdomains) "true" else "false");
+ }
+ def clientMTime = ccLib.fileLastModified;
+
+ lazy val ccFrame = new FixedDiskResource(new JarOrNotFile(config.ajstdlibHome, "streaming-iframe.html") {
+ override val classBase = "/net/appjet/ajstdlib/";
+ override val fileSep = "/../../net.appjet.ajstdlib/";
+ });
+ def frameCode = {
+ if (! config.devMode)
+ ccFrame.contents.replace("<head>\n<script>", """<head>
+ <script>
+ window.onerror = function() { /* silently drop errors */ }
+ </script>
+ <script>""");
+ else
+ ccFrame.contents;
+ }
+
+
+ // public
+ def connections(ec: ExecutionContext): Scriptable = {
+ JSContext.getCurrentContext().newArray(ec.runner.globalScope, SocketManager.sockets.keys.toList.toArray[Object]);
+ }
+
+ // public
+ def connectionStatus = {
+ val m = new HashMap[String, Int];
+ for (socket <- SocketManager.sockets.values) {
+ val key = socket.currentChannel.map(_.kind.toString()).getOrElse("(unconnected)");
+ m(key) = m.getOrElse(key, 0) + 1;
+ }
+ m;
+ }
+
+ // public
+ def getNumCurrentConnections = SocketManager.sockets.size;
+
+ // public
+ def write(id: String, msg: String) {
+ SocketManager.sockets.get(id).foreach(_.sendMessage(false, msg));
+ }
+
+ // public
+ def isConnected(id: String): java.lang.Boolean = {
+ SocketManager.sockets.contains(id);
+ }
+
+ // public
+ def getTransportType(id: String): String = {
+ SocketManager.sockets.get(id).map(_.currentChannel.map(_.kind.toString()).getOrElse("none")).getOrElse("none");
+ }
+
+ // public
+ def disconnect(id: String) {
+ SocketManager.sockets.get(id).foreach(x => x.close());
+ }
+
+ // public
+ def setAttribute(ec: ExecutionContext, id: String, key: String, value: String) {
+ ec.attributes.get("cometSocket").map(x => Some(x.asInstanceOf[StreamingSocket])).getOrElse(SocketManager.sockets.get(id))
+ .foreach(_.attributes(key) = value);
+ }
+ // public
+ def getAttribute(ec: ExecutionContext, id: String, key: String): String = {
+ ec.attributes.get("cometSocket").map(x => Some(x.asInstanceOf[StreamingSocket])).getOrElse(SocketManager.sockets.get(id))
+ .map(_.attributes.getOrElse(key, null)).getOrElse(null);
+ }
+
+ // public
+ def getClientCode(ec: ExecutionContext) = {
+ clientCode(config.transportPrefix, acceptableTransports);
+ }
+ def getClientMTime(ec: ExecutionContext) = clientMTime;
+}
+
+class StreamingSocket(val id: String, handler: SocketConnectionHandler) {
+ var hasConnected = false;
+ var shutdown = false;
+ var killed = false;
+ var currentChannel: Option[Channel] = None;
+ val activeChannels = new HashMap[ChannelType.Value, Channel]
+ with SynchronizedMap[ChannelType.Value, Channel];
+
+ lazy val attributes = new HashMap[String, String] with SynchronizedMap[String, String];
+
+ def channel(typ: String, create: Boolean, subType: String): Option[Channel] = {
+ val channelType = ChannelType.valueOf(typ);
+ if (channelType.isEmpty) {
+ streaminglog(Map(
+ "type" -> "error",
+ "error" -> "unknown channel type",
+ "channelType" -> channelType));
+ None;
+ } else if (create) {
+ Some(activeChannels.getOrElseUpdate(channelType.get, Channels.createNew(channelType.get, this, subType)));
+ } else {
+ activeChannels.get(channelType.get);
+ }
+ }
+
+ val outgoingMessageQueue = new Queue[SocketMessage];
+ val unconfirmedMessages = new HashMap[Int, SocketMessage];
+
+ var lastSentSeqNumber = 0;
+ var lastConfirmedSeqNumber = 0;
+
+ // external API
+ def sendMessage(isControl: boolean, body: String) {
+ if (hasConnected && ! shutdown) {
+ synchronized {
+ lastSentSeqNumber += 1;
+ val msg = new SocketMessage(lastSentSeqNumber, isControl, body);
+ outgoingMessageQueue += msg;
+ unconfirmedMessages(msg.seq) = msg;
+ }
+ currentChannel.foreach(_.messageWaiting());
+ }
+ }
+ def close() {
+ synchronized {
+ sendMessage(true, "kill");
+ shutdown = true;
+ Channels.timer.schedule(new TimerTask {
+ def run() {
+ kill("server request, timeout");
+ }
+ }, 15000);
+ }
+ }
+
+ var creatingRequest: Option[HttpServletRequest] = None;
+ // internal API
+ def kill(reason: String) {
+ synchronized {
+ if (! killed) {
+ streaminglog(Map(
+ "type" -> "event",
+ "event" -> "connection-killed",
+ "connection" -> id,
+ "reason" -> reason));
+ killed = true;
+ SocketManager.sockets -= id;
+ activeChannels.foreach(_._2.close());
+ currentChannel = None;
+ if (hasConnected) {
+ handler.disconnect(this, creatingRequest.getOrElse(null));
+ }
+ }
+ }
+ }
+ def receiveMessage(body: String, req: HttpServletRequest) {
+// println("Message received on "+id+": "+body);
+ handler.message(this, body, req);
+ }
+ def getWaitingMessage(channel: Channel): Option[SocketMessage] = {
+ synchronized {
+ if (currentChannel.isDefined && currentChannel.get == channel &&
+ ! outgoingMessageQueue.isEmpty) {
+ Some(outgoingMessageQueue.dequeue);
+ } else {
+ None;
+ }
+ }
+ }
+ def getUnconfirmedMessages(channel: Channel): Collection[SocketMessage] = {
+ synchronized {
+ if (currentChannel.isDefined && currentChannel.get == channel) {
+ for (i <- lastConfirmedSeqNumber+1 until lastSentSeqNumber+1)
+ yield unconfirmedMessages(i);
+ } else {
+ List[SocketMessage]();
+ }
+ }
+ }
+ def updateConfirmedSeqNumber(channel: Channel, received: Int) {
+ synchronized {
+ if (received > lastConfirmedSeqNumber && (channel == null || (currentChannel.isDefined && channel == currentChannel.get))) {
+ val oldConfirmed = lastConfirmedSeqNumber;
+ lastConfirmedSeqNumber = received;
+ for (i <- oldConfirmed+1 until lastConfirmedSeqNumber+1) { // inclusive!
+ unconfirmedMessages -= i;
+ }
+ }
+ }
+ }
+
+ var lastChannelUpdate = 0;
+ def useChannel(seqNo: Int, channelType0: String, req: HttpServletRequest) = synchronized {
+ if (seqNo <= lastChannelUpdate) false else {
+ lastChannelUpdate = seqNo;
+ val channelType = ChannelType.valueOf(channelType0);
+ if (channelType.isDefined) {
+ val channel = activeChannels.get(channelType.get);
+ if (channel.isDefined) {
+ if (! hasConnected) {
+ hasConnected = true;
+ creatingRequest = Some(HttpServletRequestFactory.createRequest(req));
+ handler.connect(this, req);
+ }
+ currentChannel = channel;
+// println("switching "+id+" to channel: "+channelType0);
+ if (currentChannel.get.isConnected) {
+ revive(channel.get);
+ } else {
+ hiccup(channel.get);
+ }
+ currentChannel.get.messageWaiting();
+ true;
+ } else
+ false;
+ } else
+ false;
+ }
+ }
+// def handleReceivedMessage(seq: Int, data: String) {
+// synchronized {
+// handler.message(this, data)
+// // TODO(jd): add client->server sequence numbers.
+// // if (seq == lastReceivedSeqNumber+1){
+// // lastReceivedSeqNumber = seq;
+// // handler.message(this, data);
+// // } else {
+// // // handle error.
+// // }
+// }
+// }
+ def hiccup(channel: Channel) = synchronized {
+ if (currentChannel.isDefined && channel == currentChannel.get) {
+// println("hiccuping: "+id);
+ scheduleTimeout();
+ }
+ }
+ def revive(channel: Channel) = synchronized {
+ if (currentChannel.isDefined && channel == currentChannel.get) {
+// println("reviving: "+id);
+ cancelTimeout();
+ }
+ }
+ def prepareForReconnect() = synchronized {
+// println("client-side hiccup: "+id);
+ activeChannels.foreach(_._2.close());
+ activeChannels.clear();
+ currentChannel = None;
+ scheduleTimeout();
+ }
+
+ // helpers
+ var timeoutTask: TimerTask = null;
+
+ def scheduleTimeout() {
+ if (timeoutTask != null) return;
+ val p = new WeakReference(this);
+ timeoutTask = new TimerTask {
+ def run() {
+ val socket = p.get();
+ if (socket != null) {
+ socket.kill("timeout");
+ }
+ }
+ }
+ Channels.timer.schedule(timeoutTask, 15*1000);
+ }
+ def cancelTimeout() {
+ if (timeoutTask != null)
+ timeoutTask.cancel();
+ timeoutTask = null;
+ }
+ scheduleTimeout();
+
+ streaminglog(Map(
+ "type" -> "event",
+ "event" -> "connection-created",
+ "connection" -> id));
+}
+
+object ChannelType extends Enumeration("shortpolling", "longpolling", "streaming") {
+ val ShortPolling, LongPolling, Streaming = Value;
+}
+
+object Channels {
+ def createNew(typ: ChannelType.Value, socket: StreamingSocket, subType: String): Channel = {
+ typ match {
+ case ChannelType.ShortPolling => new ShortPollingChannel(socket);
+ case ChannelType.LongPolling => new LongPollingChannel(socket);
+ case ChannelType.Streaming => {
+ subType match {
+ case "iframe" => new StreamingChannel(socket) with IFrameChannel;
+ case "opera" => new StreamingChannel(socket) with OperaChannel;
+ case _ => new StreamingChannel(socket);
+ }
+ }
+ }
+ }
+
+ val timer = new Timer(true);
+}
+
+class SocketMessage(val seq: Int, val isControl: Boolean, val body: String) {
+ def payload = seq+":"+(if (isControl) "1" else "0")+":"+body;
+}
+
+trait Channel {
+ def messageWaiting();
+ def close();
+ def handle(req: HttpServletRequest, res: HttpServletResponse);
+ def isConnected: Boolean;
+
+ def kind: ChannelType.Value;
+ def sendRestartFailure(ec: ExecutionContext);
+}
+
+trait XhrChannel extends Channel {
+ def wrapBody(msg: String) = msg.length+":"+msg;
+
+ // wire format: msgLength:seq:[01]:msg
+ def wireFormat(msg: SocketMessage) = wrapBody(msg.payload);
+ def controlMessage(data: String) = wrapBody("oob:"+data);
+
+ def sendRestartFailure(ec: ExecutionContext) {
+ ec.response.write(controlMessage("restart-fail"));
+ }
+}
+
+// trait IFrameChannel extends Channel {
+// def wireFormat(msg: SocketMessage)
+// }
+
+class ShortPollingChannel(val socket: StreamingSocket) extends Channel with XhrChannel {
+ def kind = ChannelType.ShortPolling;
+
+ def messageWaiting() {
+ // do nothing.
+ }
+ def close() {
+ // do nothing
+ }
+ def isConnected = false;
+
+ def handle(req: HttpServletRequest, res: HttpServletResponse) {
+ val ec = req.getAttribute("executionContext").asInstanceOf[ExecutionContext];
+ val out = new StringBuilder();
+ socket.synchronized {
+ socket.revive(this);
+ if (req.getParameter("new") == "yes") {
+ out.append(controlMessage("ok"));
+ } else {
+ val lastReceivedSeq = java.lang.Integer.parseInt(req.getParameter("seq"));
+ socket.updateConfirmedSeqNumber(this, lastReceivedSeq);
+ for (msg <- socket.getUnconfirmedMessages(this)) {
+ out.append(wireFormat(msg));
+ }
+ // ALL MESSAGES ARE UNCONFIRMED AT THIS POINT! JUST CLEAR QUEUE.
+ var msg = socket.getWaitingMessage(this);
+ while (msg.isDefined) {
+ msg = socket.getWaitingMessage(this);
+ }
+ }
+ }
+// println("Writing to "+socket.id+": "+out.toString);
+ ec.response.write(out.toString);
+ socket.synchronized {
+ socket.hiccup(this);
+ }
+ }
+}
+
+trait IFrameChannel extends StreamingChannel {
+ override def wrapBody(msgBody: String) = {
+ val txt = "<script type=\"text/javascript\">p('"+
+ msgBody.replace("\\","\\\\").replace("'", "\\'")+"');</script>";
+ if (txt.length < 256)
+ String.format("%256s", txt);
+ else
+ txt;
+ }
+
+ def header(req: HttpServletRequest) = {
+ val document_domain =
+ "\""+req.getHeader("Host").split("\\.").slice(2).mkString(".").split(":")(0)+"\"";
+ """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html><head><title>f</title></head><body id="thebody" onload="(!parent.closed)&&d()"><script type="text/javascript">document.domain = """+document_domain+""";
+var p = function(data) { try { parent.comet.pass_data } catch (err) { /* failed to pass data. no recourse. */ } };
+var d = parent.comet.disconnect;"""+(if(!config.devMode)"\nwindow.onerror = function() { /* silently drop errors */ }\n" else "")+"</script>"; // " - damn textmate mode!
+ }
+
+ override def sendRestartFailure(ec: ExecutionContext) {
+ ec.response.write(header(ec.request.req));
+ ec.response.write(controlMessage("restart-fail"));
+ }
+
+ override def handleNewConnection(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ super.handleNewConnection(req, res, out);
+ res.setContentType("text/html");
+ out.append(header(req));
+ }
+}
+
+trait OperaChannel extends StreamingChannel {
+ override def wrapBody(msgBody: String) = {
+ "Event: message\ndata: "+msgBody+"\n\n";
+ }
+ override def handleNewConnection(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ super.handleNewConnection(req, res, out);
+ res.setContentType("application/x-dom-event-stream");
+ }
+}
+
+class StreamingChannel(val socket: StreamingSocket) extends Channel with XhrChannel {
+ def kind = ChannelType.Streaming;
+
+ var c: Option[SelectChannelConnector.RetryContinuation] = None;
+ var doClose = false;
+
+ def messageWaiting() {
+ main.server.getThreadPool().dispatch(new Runnable() {
+ def run() {
+ socket.synchronized {
+ c.filter(_.isPending()).foreach(_.resume());
+ }
+ }
+ });
+ }
+
+ def setSequenceNumberIfAppropriate(req: HttpServletRequest) {
+ if (c.get.isNew) {
+ val lastReceivedSeq = java.lang.Integer.parseInt(req.getParameter("seq"));
+ socket.updateConfirmedSeqNumber(this, lastReceivedSeq);
+ }
+ }
+
+ def sendHandshake(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ out.append(controlMessage("ok"));
+ }
+
+ def sendUnconfirmedMessages(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ for (msg <- socket.getUnconfirmedMessages(this)) {
+ out.append(wireFormat(msg));
+ }
+ }
+
+ def sendWaitingMessages(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ var msg = socket.getWaitingMessage(this);
+ while (msg.isDefined) {
+ out.append(wireFormat(msg.get));
+ msg = socket.getWaitingMessage(this);
+ }
+ }
+
+ def handleUnexpectedDisconnect(req: HttpServletRequest, res: HttpServletResponse, ep: KnowsAboutDispatch) {
+ socket.synchronized {
+ socket.hiccup(this);
+ }
+ ep.close();
+ }
+
+ def writeAndFlush(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder, ep: KnowsAboutDispatch) {
+// println("Writing to "+socket.id+": "+out.toString);
+ res.getWriter.print(out.toString);
+ res.getWriter.flush();
+ }
+
+ def suspendIfNecessary(req: HttpServletRequest, res: HttpServletResponse,
+ out: StringBuilder, ep: KnowsAboutDispatch) {
+ scheduleKeepalive(50*1000);
+ ep.undispatch();
+ c.get.suspend(0);
+ }
+
+ def sendKeepaliveIfNecessary(out: StringBuilder, sendKeepalive: Boolean) {
+ if (out.length == 0 && sendKeepalive) {
+ out.append(controlMessage("keepalive"));
+ }
+ }
+
+ def shouldHandshake(req: HttpServletRequest, res: HttpServletResponse) = c.get.isNew;
+
+ var sendKeepalive = false;
+ var keepaliveTask: TimerTask = null;
+ def scheduleKeepalive(timeout: Int) {
+ if (keepaliveTask != null) {
+ keepaliveTask.cancel();
+ }
+ val p = new WeakReference(this);
+ keepaliveTask = new TimerTask {
+ def run() {
+ val channel = p.get();
+ if (channel != null) {
+ channel.synchronized {
+ channel.sendKeepalive = true;
+ channel.messageWaiting();
+ }
+ }
+ }
+ }
+ Channels.timer.schedule(keepaliveTask, timeout);
+ }
+
+ def handleNewConnection(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ req.setAttribute("StreamingSocketServlet_channel", this);
+ res.setHeader("Connection", "close");
+ for ((k, v) <- Util.noCacheHeaders) { res.setHeader(k, v); } // maybe this will help with proxies?
+ res.setContentType("text/messages; charset=utf-8");
+ }
+
+ def handle(req: HttpServletRequest, res: HttpServletResponse) {
+ val ec = req.getAttribute("executionContext").asInstanceOf[ExecutionContext];
+ val ep = HttpConnection.getCurrentConnection.getEndPoint.asInstanceOf[KnowsAboutDispatch];
+ val out = new StringBuilder;
+ try {
+ socket.synchronized {
+ val sendKeepaliveNow = sendKeepalive;
+ sendKeepalive = false;
+ if (keepaliveTask != null) {
+ keepaliveTask.cancel();
+ keepaliveTask = null;
+ }
+ c = Some(ContinuationSupport.getContinuation(req, socket).asInstanceOf[SelectChannelConnector.RetryContinuation]);
+ setSequenceNumberIfAppropriate(req);
+ if (doClose) {
+ ep.close();
+ return;
+ }
+ if (c.get.isNew) {
+ handleNewConnection(req, res, out);
+ } else {
+ c.get.suspend(-1);
+ if (ep.isDispatched) {
+ handleUnexpectedDisconnect(req, res, ep);
+ return;
+ }
+ }
+ if (shouldHandshake(req, res)) {
+// println("new stream request: "+socket.id);
+ sendHandshake(req, res, out);
+ sendUnconfirmedMessages(req, res, out);
+ }
+ sendWaitingMessages(req, res, out);
+ sendKeepaliveIfNecessary(out, sendKeepaliveNow);
+ suspendIfNecessary(req, res, out, ep);
+ }
+ } finally {
+ writeAndFlush(req, res, out, ep);
+ }
+ }
+
+ def close() {
+ doClose = true;
+ messageWaiting();
+ }
+
+ def isConnected = ! doClose;
+}
+
+class LongPollingChannel(socket: StreamingSocket) extends StreamingChannel(socket) {
+// println("creating longpoll!");
+ override def kind = ChannelType.LongPolling;
+
+ override def shouldHandshake(req: HttpServletRequest, res: HttpServletResponse) =
+ req.getParameter("new") == "yes";
+
+ override def sendHandshake(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+// println("sending handshake");
+ out.append(controlMessage("ok"));
+ }
+
+ override def suspendIfNecessary(req: HttpServletRequest, res: HttpServletResponse,
+ out: StringBuilder, ep: KnowsAboutDispatch) {
+ if (out.length == 0) {
+// println("suspending longpoll: "+socket.id);
+ val to = java.lang.Integer.parseInt(req.getParameter("timeout"));
+// println("LongPoll scheduling keepalive for: "+to);
+ scheduleKeepalive(to);
+ ep.undispatch();
+ c.get.suspend(0);
+ }
+ }
+
+ override def writeAndFlush(req: HttpServletRequest, res: HttpServletResponse,
+ out: StringBuilder, ep: KnowsAboutDispatch) {
+ if (out.length > 0) {
+// println("Writing to "+socket.id+": "+out.toString);
+// println("writing and flushing longpoll")
+ val ec = req.getAttribute("executionContext").asInstanceOf[ExecutionContext];
+ for ((k, v) <- Util.noCacheHeaders) { ec.response.setHeader(k, v); } // maybe this will help with proxies?
+// println("writing: "+out);
+ ec.response.write(out.toString);
+ socket.synchronized {
+ socket.hiccup(this);
+ c = None;
+ }
+ }
+ }
+
+ override def handleNewConnection(req: HttpServletRequest, res: HttpServletResponse, out: StringBuilder) {
+ socket.revive(this);
+ req.setAttribute("StreamingSocketServlet_channel", this);
+ }
+
+ override def isConnected = socket.synchronized {
+ c.isDefined;
+ }
+}
+
+class StreamingSocketServlet extends HttpServlet {
+ val version = 2;
+
+ override def doGet(req: HttpServletRequest, res: HttpServletResponse) {
+// describeRequest(req);
+ val ec = req.getAttribute("executionContext").asInstanceOf[ExecutionContext];
+ try {
+ if (req.getPathInfo() == "/js/client.js") {
+ val contextPath = config.transportPrefix;
+ val acceptableTransports = Comet.acceptableTransports;
+ ec.response.setContentType("application/x-javascript");
+ ec.response.write(Comet.clientCode(contextPath, acceptableTransports));
+ } else if (req.getPathInfo() == "/xhrXdFrame") {
+ ec.response.setContentType("text/html; charset=utf-8");
+ ec.response.write(Comet.frameCode);
+ } else {
+ val v = req.getParameter("v");
+ if (v == null || java.lang.Integer.parseInt(v) != version) {
+ res.sendError(HttpServletResponse.SC_BAD_REQUEST, "bad version number!");
+ return;
+ }
+ val existingChannel = req.getAttribute("StreamingSocketServlet_channel");
+ if (existingChannel != null) {
+ existingChannel.asInstanceOf[Channel].handle(req, res);
+ } else {
+ val socketId = req.getParameter("id");
+ val channelType = req.getParameter("channel");
+ val isNew = req.getParameter("new") == "yes";
+ val shouldCreateSocket = req.getParameter("create") == "yes";
+ val subType = req.getParameter("type");
+ val channel = SocketManager(socketId, shouldCreateSocket).map(_.channel(channelType, isNew, subType)).getOrElse(None);
+ if (channel.isDefined) {
+ channel.get.handle(req, res);
+ } else {
+ streaminglog(Map(
+ "type" -> "event",
+ "event" -> "restart-failure",
+ "connection" -> socketId));
+ val failureChannel = ChannelType.valueOf(channelType).map(Channels.createNew(_, null, subType));
+ if (failureChannel.isDefined) {
+ failureChannel.get.sendRestartFailure(ec);
+ } else {
+ ec.response.setStatusCode(HttpServletResponse.SC_NOT_FOUND);
+ ec.response.write("So such socket, and/or unknown channel type: "+channelType);
+ }
+ }
+ }
+ }
+ } catch {
+ case e: RetryRequest => throw e;
+ case t: Throwable => {
+ exceptionlog("A comet error occurred: ");
+ exceptionlog(t);
+ ec.response.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ec.response.write(t.getMessage());
+ }
+ }
+ }
+
+ def describeRequest(req: HttpServletRequest) {
+ println(req.getMethod+" on "+req.getRequestURI()+"?"+req.getQueryString());
+ for (pname <-
+ req.getParameterNames.asInstanceOf[java.util.Enumeration[String]]) {
+ println(" "+pname+" -> "+req.getParameterValues(pname).mkString("[", ",", "]"));
+ }
+ }
+
+ override def doPost(req: HttpServletRequest, res: HttpServletResponse) {
+ val v = req.getParameter("v");
+ if (v == null || java.lang.Integer.parseInt(v) != version) {
+ res.sendError(HttpServletResponse.SC_BAD_REQUEST, "bad version number!");
+ return;
+ }
+ val ec = req.getAttribute("executionContext").asInstanceOf[ExecutionContext];
+ val socketId = req.getParameter("id");
+ val socket = SocketManager(socketId, false);
+
+// describeRequest(req);
+
+ if (socket.isEmpty) {
+ ec.response.write("restart-fail");
+ streaminglog(Map(
+ "type" -> "event",
+ "event" -> "restart-failure",
+ "connection" -> socketId));
+// println("socket restart-fail: "+socketId);
+ } else {
+ val seq = java.lang.Integer.parseInt(req.getParameter("seq"));
+ socket.get.updateConfirmedSeqNumber(null, seq);
+ val messages = req.getParameterValues("m");
+ val controlMessages = req.getParameterValues("oob");
+ try {
+ if (messages != null)
+ for (msg <- messages) socket.get.receiveMessage(msg, req);
+ if (controlMessages != null)
+ for (msg <- controlMessages) {
+// println("Control message from "+socket.get.id+": "+msg);
+ msg match {
+ case "hiccup" => {
+ streaminglog(Map(
+ "type" -> "event",
+ "event" -> "hiccup",
+ "connection" -> socketId));
+ socket.get.prepareForReconnect();
+ }
+ case _ => {
+ if (msg.startsWith("useChannel")) {
+ val msgParts = msg.split(":");
+ socket.get.useChannel(java.lang.Integer.parseInt(msgParts(1)), msgParts(2), req);
+ } else if (msg.startsWith("kill")) {
+ socket.get.kill("client request: "+msg.substring(Math.min(msg.length, "kill:".length)));
+ } else {
+ streaminglog(Map(
+ "type" -> "error",
+ "error" -> "unknown control message",
+ "connection" -> socketId,
+ "message" -> msg));
+ }
+ }
+ }
+ }
+ ec.response.write("ok");
+ } catch {
+ case e: SocketManager.HandlerException => {
+ exceptionlog(e);
+ ec.response.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ec.response.write(e.getMessage());
+ // log these?
+ }
+ case t: Throwable => {
+ // shouldn't happen...
+ exceptionlog(t);
+ ec.response.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ec.response.write(t.getMessage());
+ }
+ }
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.ajstdlib/timer.scala b/infrastructure/net.appjet.ajstdlib/timer.scala
new file mode 100644
index 0000000..dac8fb6
--- /dev/null
+++ b/infrastructure/net.appjet.ajstdlib/timer.scala
@@ -0,0 +1,85 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.ajstdlib;
+
+import scala.collection.mutable.{HashMap,ListBuffer};
+import java.util.concurrent.locks.ReentrantLock;
+
+object timer {
+
+ var _timings = new HashMap[String,ListBuffer[double]];
+ var _lock = new ReentrantLock;
+ var _callstack = new ThreadLocal[ListBuffer[String]];
+
+ def start(opname: String) = {
+ var _localcallstack = _callstack.get();
+ if (_localcallstack == null) {
+ _callstack.set(new ListBuffer[String]);
+ _localcallstack = _callstack.get();
+ }
+ _localcallstack += opname;
+ var _oplabel = _localcallstack.mkString(".");
+ val startTime: long = System.nanoTime();
+
+ new {
+ def done() {
+ val elapsedTimeMs: double = (System.nanoTime() - startTime) / 1.0e6;
+
+ _lock.lock();
+ try {
+ var times = _timings.getOrElse(_oplabel, new ListBuffer[double]);
+ /*
+ if (times.size > 100000) {
+ times = new ListBuffer[double];
+ }*/
+ times += elapsedTimeMs;
+ _timings.put(_oplabel, times);
+ _localcallstack.remove(_localcallstack.length-1);
+ } finally {
+ _lock.unlock();
+ }
+ }
+ }
+ }
+
+ def getOpNames(): Array[String] = {
+ _lock.lock();
+ try {
+ return _timings.keys.toList.toArray;
+ } finally {
+ _lock.unlock();
+ }
+ }
+
+ def getStats(opname: String): Array[double] = {
+ _lock.lock();
+
+ try {
+ var times:ListBuffer[double] = _timings(opname);
+ var total = times.foldRight(0.0)(_ + _);
+ return Array(times.size, total, (total / times.size));
+ } finally {
+ _lock.unlock();
+ }
+ }
+
+ def reset() {
+ _lock.lock();
+ _timings = new HashMap[String,ListBuffer[double]];
+ _lock.unlock();
+ }
+}
diff --git a/infrastructure/net.appjet.bodylock/bodylock.scala b/infrastructure/net.appjet.bodylock/bodylock.scala
new file mode 100644
index 0000000..e24d55c
--- /dev/null
+++ b/infrastructure/net.appjet.bodylock/bodylock.scala
@@ -0,0 +1,291 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.bodylock;
+
+import net.appjet.common.rhino.rhinospect;
+
+import scala.collection.mutable.{SynchronizedMap, ArrayBuffer, HashMap};
+
+import org.mozilla.javascript.{Context, Scriptable, ScriptableObject, Script, JavaScriptException, NativeJavaObject, WrappedException, IdScriptableObject};
+
+trait Executable {
+ def execute(scope: Scriptable): Object;
+}
+
+trait JSStackFrame {
+ def errorLine: Int; // 1-indexed.
+ def errorContext(rad: Int): (Int, Int, Seq[String]); // 1-indexed
+ def name: String;
+}
+
+class ExecutionException(message: String, cause: Throwable) extends RuntimeException(message, cause) {
+ def this(message: String) = this(message, null);
+}
+
+class JSRuntimeException(val message: String, val cause: Throwable) extends ExecutionException(message, cause) {
+ private val i_frames: Seq[JSStackFrame] = if (cause == null) List() else {
+ val ab = new ArrayBuffer[JSStackFrame];
+ for (elt <- cause.getStackTrace() if (elt.getFileName != null && BodyLock.map.filter(_.contains(elt.getFileName)).isDefined && elt.getLineNumber >= 0)) {
+ ab += new JSStackFrame {
+ val errorLine = elt.getLineNumber;
+ val name = elt.getFileName;
+ val code = BodyLock.map.getOrElse(Map[String, String]()).getOrElse(elt.getFileName, "").split("\n"); // 0-indexed.
+ def errorContext(rad: Int) = {
+ val start_i = Math.max(errorLine-rad, 1)-1;
+ val end_i = Math.min(errorLine+rad, code.length)-1;
+ (start_i+1, end_i+1, code.slice(start_i, end_i+1));
+ }
+ }
+ }
+ ab;
+ }
+ def frames = i_frames;
+}
+
+class JSCompileException(message: String, cause: org.mozilla.javascript.EvaluatorException) extends JSRuntimeException(message, cause) {
+ override val frames =
+ List(new JSStackFrame {
+ val errorLine = cause.lineNumber();
+ val name = cause.sourceName();
+ val code = BodyLock.map.getOrElse(Map[String, String]()).getOrElse(cause.sourceName(), "").split("\n"); // 0-indexed.
+ def errorContext(rad: Int) = {
+ val start_i = Math.max(errorLine-rad, 1)-1;
+ val end_i = Math.min(errorLine+rad, code.length)-1;
+ (start_i+1, end_i+1, code.slice(start_i, end_i+1));
+ }
+ }).concat(List(super.frames: _*));
+}
+
+private[bodylock] class InnerExecutable(val code: String, val script: Script) extends Executable {
+ def execute(scope: Scriptable) = try {
+ BodyLock.runInContext { cx =>
+ script.exec(cx, scope);
+ }
+ } catch {
+ case e: Throwable => {
+ val orig = BodyLock.unwrapExceptionIfNecessary(e);
+ orig match {
+ case e: JSRuntimeException => throw e;
+ case e: org.mortbay.jetty.RetryRequest => throw e;
+ case _ => throw new JSRuntimeException("Error while executing: "+orig.getMessage, orig);
+ }
+ }
+ }
+
+ override def toString() =
+ rhinospect.dumpFields(script, 1, "");
+}
+
+object CustomContextFactory extends org.mozilla.javascript.ContextFactory {
+ val wrapFactory = new org.mozilla.javascript.WrapFactory {
+ setJavaPrimitiveWrap(false); // don't wrap strings, numbers, booleans
+ }
+
+ class CustomContext() extends Context() {
+ setWrapFactory(wrapFactory);
+ }
+
+ override def makeContext(): Context = new CustomContext();
+}
+
+object BodyLock {
+ var map: Option[SynchronizedMap[String, String]] = None;
+
+ def runInContext[E](expr: Context => E): E = {
+ val cx = CustomContextFactory.enterContext();
+ try {
+ expr(cx);
+ } finally {
+ Context.exit();
+ }
+ }
+
+ def newScope = runInContext { cx =>
+ cx.initStandardObjects(null, true);
+ }
+ def subScope(scope: Scriptable) = runInContext { cx =>
+ val newObj = cx.newObject(scope).asInstanceOf[ScriptableObject];
+ newObj.setPrototype(scope);
+ newObj.setParentScope(null);
+ newObj;
+ }
+
+ def evaluateString(scope: Scriptable, source: String, sourceName: String,
+ lineno: Int /*, securityDomain: AnyRef = null */) = runInContext { cx =>
+ cx.evaluateString(scope, source, sourceName, lineno, null);
+ }
+ def compileString(source: String, sourceName: String, lineno: Int
+ /*, securityDomain: AnyRef = null */) = runInContext { cx =>
+ map.foreach(_(sourceName) = source);
+ try {
+ new InnerExecutable(source, compileToScript(source, sourceName, lineno));
+ } catch {
+ case e: org.mozilla.javascript.EvaluatorException => {
+ throw new JSCompileException(e.getMessage(), e);
+ }
+ }
+ }
+
+ private val classId = new java.util.concurrent.atomic.AtomicInteger(0);
+
+ private def compileToScript(source: String, sourceName: String, lineNumber: Int): Script = {
+ val className = "JS$"+sourceName.replaceAll("[^a-zA-Z0-9]", "\\$")+"$"+classId.incrementAndGet();
+ compilationutils.compileToScript(source, sourceName, lineNumber, className);
+ }
+
+ def executableFromBytes(bytes: Array[byte], className: String) =
+ new InnerExecutable("(source not available)", compilationutils.bytesToScript(bytes, className));
+
+ def unwrapExceptionIfNecessary(e: Throwable): Throwable = {
+ e match {
+ case e: JavaScriptException => e.getValue() match {
+ case njo: NativeJavaObject => Context.jsToJava(njo, classOf[Object]) match {
+ case e: Throwable => e;
+ case _ => e;
+ }
+ case ne: IdScriptableObject => new JSRuntimeException("Error: "+ne.get("message", ne), e);
+ case t: Throwable => t;
+ case _ => e;
+ }
+ case e: WrappedException => unwrapExceptionIfNecessary(e.getWrappedException());
+ case _ => e;
+ }
+ }
+}
+
+private[bodylock] object compilationutils {
+ class Loader(parent: ClassLoader) extends ClassLoader(parent) {
+ def this() = this(getClass.getClassLoader);
+ def defineClass(className: String, bytes: Array[Byte]): Class[_] = {
+ // call protected method
+ defineClass(className, bytes, 0, bytes.length);
+ }
+ }
+
+ def compileToBytes(source: String, sourceName: String, lineNumber: Int,
+ className: String): Array[Byte] = {
+ val environs = new org.mozilla.javascript.CompilerEnvirons;
+ BodyLock.runInContext(environs.initFromContext(_));
+ environs.setGeneratingSource(false);
+ val compiler = new org.mozilla.javascript.optimizer.ClassCompiler(environs);
+
+ // throws EvaluatorException
+ val result:Array[Object] =
+ compiler.compileToClassFiles(source, sourceName, lineNumber, className);
+
+ // result[0] is class name, result[1] is class bytes
+ result(1).asInstanceOf[Array[Byte]];
+ }
+
+ def compileToScript(source: String, sourceName: String, lineNumber: Int,
+ className: String): Script = {
+ bytesToScript(compileToBytes(source, sourceName, lineNumber, className), className);
+ }
+
+ def bytesToScript(bytes: Array[Byte], className: String): Script = {
+ (new Loader()).defineClass(className, bytes).newInstance.asInstanceOf[Script];
+ }
+}
+
+
+import java.io.File;
+import scala.collection.mutable.HashMap;
+import net.appjet.common.util.BetterFile;
+import net.appjet.common.cli._;
+
+object Compiler {
+ val optionsList = Array(
+ ("destination", true, "Destination for class files", "path"),
+ ("cutPrefix", true, "Drop this prefix from files", "path"),
+ ("verbose", false, "Print debug information", "")
+ );
+ val chosenOptions = new HashMap[String, String];
+ val options =
+ for (opt <- optionsList) yield
+ new CliOption(opt._1, opt._3, if (opt._2) Some(opt._4) else None)
+
+// var o = new Options;
+// for (m <- optionsList) {
+// o.addOption({
+// if (m._2) {
+// withArgName(m._4);
+// hasArg();
+// }
+// withDescription(m._3);
+// // withLongOpt(m.getName());
+// create(m._1);
+// });
+// }
+// o;
+// }
+
+ var verbose = true;
+ def vprintln(s: String) {
+ if (verbose) println(s);
+ }
+
+ def printUsage() {
+ println((new CliParser(options)).usage);
+ }
+ def extractOptions(args0: Array[String]) = {
+ val parser = new CliParser(options);
+ val (opts, args) =
+ try {
+ parser.parseOptions(args0);
+ } catch {
+ case e: ParseException => {
+ println("error: "+e.getMessage());
+ printUsage();
+ System.exit(1);
+ null;
+ }
+ }
+ for ((k, v) <- opts) {
+ chosenOptions(k) = v;
+ }
+ args
+ }
+ def compileSingleFile(src: File, dst: File) {
+ val source = BetterFile.getFileContents(src);
+ vprintln("to: "+dst.getPath());
+ val classBytes = compilationutils.compileToBytes(source, src.getName(), 1, dst.getName().split("\\.")(0));
+
+ val fos = new java.io.FileOutputStream(dst);
+ fos.write(classBytes);
+ }
+
+ def main(args0: Array[String]) {
+ // should contain paths, relative to PWD, of javascript files to compile.
+ val args = extractOptions(args0);
+ val dst = chosenOptions("destination");
+ val pre = chosenOptions.getOrElse("cutPrefix", "");
+ verbose = chosenOptions.getOrElse("verbose", "false") == "true";
+ for (p <- args) {
+ val srcFile = new File(p);
+ if (srcFile.getParent() != null && ! srcFile.getParent().startsWith(pre))
+ throw new RuntimeException("srcFile "+srcFile.getPath()+" doesn't start with "+pre);
+ val parentDir =
+ if (srcFile.getParent() != null) {
+ new File(dst+"/"+srcFile.getParent().substring(pre.length));
+ } else {
+ new File(dst);
+ }
+ parentDir.mkdirs();
+ compileSingleFile(srcFile, new File(parentDir.getPath()+"/JS$"+srcFile.getName().split("\\.").reverse.drop(1).reverse.mkString(".").replaceAll("[^a-zA-Z0-9]", "\\$")+".class"));
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.bodylock/compressor.scala b/infrastructure/net.appjet.bodylock/compressor.scala
new file mode 100644
index 0000000..5041787
--- /dev/null
+++ b/infrastructure/net.appjet.bodylock/compressor.scala
@@ -0,0 +1,269 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.bodylock;
+
+import java.io.{StringWriter, StringReader}
+import net.appjet.common.util.BetterFile;
+
+object compressor {
+ def compress(code: String): String = {
+ import yuicompressor.org.mozilla.javascript.{ErrorReporter, EvaluatorException};
+ object MyErrorReporter extends ErrorReporter {
+ def warning(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+ if (message startsWith "Try to use a single 'var' statement per scope.") return;
+ if (line < 0) System.err.println("\n[WARNING] " + message);
+ else System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+ }
+ def error(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+ if (line < 0) System.err.println("\n[ERROR] " + message);
+ else System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+ java.lang.System.exit(1);
+ }
+ def runtimeError(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int): EvaluatorException = {
+ error(message, sourceName, line, lineSource, lineOffset);
+ return new EvaluatorException(message);
+ }
+ }
+
+ val munge = true;
+ val verbose = false;
+ val optimize = true;
+ val wrap = true;
+ val compressor = new com.yahoo.platform.yui.compressor.JavaScriptCompressor(new StringReader(code), MyErrorReporter);
+ val writer = new StringWriter;
+ compressor.compress(writer, if (wrap) 100 else -1, munge, verbose, true, optimize);
+ writer.toString;
+ }
+
+ def main(args: Array[String]) {
+ for (fname <- args) {
+ try {
+ val src = BetterFile.getFileContents(fname);
+ val obfSrc = compress(src);
+ val fw = (new java.io.FileWriter(new java.io.File(fname)));
+ fw.write(obfSrc, 0, obfSrc.length);
+ fw.close();
+ } catch {
+ case e => {
+ println("Failed to compress: "+fname+". Quitting.");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+ }
+}
+
+
+// ignore these:
+
+// import java.io._;
+
+// def doMake {
+
+// lazy val isEtherPad = (args.length >= 2 && args(1) == "etherpad");
+// lazy val isNoHelma = (args.length >= 2 && args(1) == "nohelma");
+
+// def getFile(path:String): String = {
+// val builder = new StringBuilder(1000);
+// val reader = new BufferedReader(new FileReader(path));
+// val buf = new Array[Char](1024);
+// var numRead = 0;
+// while({ numRead = reader.read(buf); numRead } != -1) {
+// builder.append(buf, 0, numRead);
+// }
+// reader.close;
+// return builder.toString;
+// }
+
+// def putFile(str: String, path: String): Unit = {
+// val writer = new FileWriter(path);
+// writer.write(str);
+// writer.close;
+// }
+
+// def writeToString(func:(Writer=>Unit)): String = {
+// val writer = new StringWriter;
+// func(writer);
+// return writer.toString;
+// }
+
+// def compressJS(code: String, wrap: Boolean): String = {
+// import org.mozilla.javascript.{ErrorReporter, EvaluatorException};
+// object MyErrorReporter extends ErrorReporter {
+// def warning(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+// if (message startsWith "Try to use a single 'var' statement per scope.") return;
+// if (line < 0) System.err.println("\n[WARNING] " + message);
+// else System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+// }
+// def error(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int) {
+// if (line < 0) System.err.println("\n[ERROR] " + message);
+// else System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+// }
+// def runtimeError(message:String, sourceName:String, line:Int, lineSource:String, lineOffset:Int): EvaluatorException = {
+// error(message, sourceName, line, lineSource, lineOffset);
+// return new EvaluatorException(message);
+// }
+// }
+
+// val munge = true;
+// val verbose = false;
+// val optimize = true;
+// val compressor = new com.yahoo.platform.yui.compressor.JavaScriptCompressor(new StringReader(code), MyErrorReporter);
+// return writeToString(compressor.compress(_, if (wrap) 100 else -1, munge, verbose, true, !optimize));
+// }
+
+// def compressCSS(code: String, wrap: Boolean): String = {
+// val compressor = new com.yahoo.platform.yui.compressor.CssCompressor(new StringReader(code));
+// return writeToString(compressor.compress(_, if (wrap) 100 else -1));
+// }
+
+// import java.util.regex.{Pattern, Matcher, MatchResult};
+
+// def stringReplace(orig: String, regex: String, groupReferences:Boolean, func:(MatchResult=>String)): String = {
+// val buf = new StringBuffer;
+// val m = Pattern.compile(regex).matcher(orig);
+// while (m.find) {
+// var str = func(m);
+// if (! groupReferences) {
+// str = str.replace("\\", "\\\\").replace("$", "\\$");
+// }
+// m.appendReplacement(buf, str);
+// }
+// m.appendTail(buf);
+// return buf.toString;
+// }
+
+// def stringToExpression(str: String): String = {
+// val contents = str.replace("\\", "\\\\").replace("'", "\\'").replace("<", "\\x3c").replace("\n", "\\n").
+// replace("\r", "\\n").replace("\t", "\\t");
+// return "'"+contents+"'";
+// }
+
+// val srcDir = "www";
+// val destDir = "build";
+// var code = getFile(srcDir+"/ace2_outer.js");
+
+// val useCompression = true; //if (isEtherPad) false else true;
+
+// code = stringReplace(code, "\\$\\$INCLUDE_([A-Z_]+)\\([\"']([^\"']+)[\"']\\)", false, (m:MatchResult) => {
+// val includeType = m.group(1);
+// val path = m.group(2);
+// includeType match {
+// case "JS" => {
+// var subcode = getFile(srcDir+"/"+path);
+// subcode = subcode.replaceAll("var DEBUG=true;//\\$\\$[^\n\r]*", "var DEBUG=false;");
+// if (useCompression) subcode = compressJS(subcode, false);
+// "('<script type=\"text/javascript\">//<!--\\n'+" + stringToExpression(subcode) +
+// "+'//-->\\n</script>')";
+// }
+// case "CSS" => {
+// var subcode = getFile(srcDir+"/"+path);
+// if (useCompression) subcode = compressCSS(subcode, false);
+// "('<style type=\"text/css\">'+" + stringToExpression(subcode) + "+'</style>')";
+// }
+// case "JS_Q" => {
+// var subcode = getFile(srcDir+"/"+path);
+// subcode = subcode.replaceAll("var DEBUG=true;//\\$\\$[^\n\r]*", "var DEBUG=false;");
+// if (useCompression) subcode = compressJS(subcode, false);
+// "('(\\'<script type=\"text/javascript\">//<!--\\\\n\\'+'+" +
+// stringToExpression(stringToExpression(subcode)) +
+// "+'+\\'//-->\\\\n\\\\x3c/script>\\')')";
+// }
+// case "CSS_Q" => {
+// var subcode = getFile(srcDir+"/"+path);
+// if (useCompression) subcode = compressCSS(subcode, false);
+// "('(\\'<style type=\"text/css\">\\'+'+" + stringToExpression(stringToExpression(subcode)) +
+// "+'+\\'\\\\x3c/style>\\')')";
+// }
+// case ("JS_DEV" | "CSS_DEV") => "''";
+// case ("JS_Q_DEV" | "CSS_Q_DEV") => "'\\'\\''";
+// case _ => "$$INCLUDE_"+includeType+"(\"../www/"+path+"\")";
+// }
+// });
+
+// if (useCompression) code = compressJS(code, true);
+
+// putFile(code, destDir+"/ace2bare.js");
+
+// var wrapper = getFile(srcDir+"/ace2_wrapper.js");
+// if (useCompression) wrapper = compressJS(wrapper, true);
+// putFile(wrapper+"\n"+code, destDir+"/ace2.js");
+
+// var index = getFile(srcDir+"/index.html");
+// index = index.replaceAll("<!--\\s*DEBUG\\s*-->\\s*([\\s\\S]+?)\\s*<!--\\s*/DEBUG\\s*-->", "");
+// index = index.replaceAll("<!--\\s*PROD:\\s*([\\s\\S]+?)\\s*-->", "$1");
+// putFile(index, destDir+"/index.html");
+
+// putFile(getFile(srcDir+"/testcode.js"), destDir+"/testcode.js");
+
+// def copyFile(fromFile: String, toFile: String) {
+// if (0 != Runtime.getRuntime.exec("cp "+fromFile+" "+toFile).waitFor) {
+// printf("copy failed (%s -> %s).\n", fromFile, toFile);
+// }
+// }
+
+// if (isEtherPad) {
+// copyFile("build/ace2.js", "../../../etherpad/src/static/js/ace.js");
+// val easysync = getFile(srcDir+"/easy_sync.js");
+// putFile(easysync, "../../../etherpad/src/etherpad/collab/easysync.js");
+// }
+// else if (! isNoHelma) {
+// copyFile("build/ace2.js", "../helma_apps/appjet/protectedStatic/js/ace.js");
+// }
+// }
+
+// def remakeLoop {
+
+// def getStamp: Long = {
+// return new java.io.File("www").listFiles.
+// filter(! _.getName.endsWith("~")).
+// filter(! _.getName.endsWith("#")).
+// filter(! _.getName.startsWith(".")).map(_.lastModified).
+// reduceLeft(Math.max(_:Long,_:Long));
+// }
+
+// var madeStamp:Long = 0;
+// var errorStamp:Long = 0;
+// while (true) {
+// Thread.sleep(500);
+// val s = getStamp;
+// if (s > madeStamp && s != errorStamp) {
+// Thread.sleep(1000);
+// if (getStamp == s) {
+// madeStamp = s;
+// print("Remaking... ");
+// try {
+// doMake;
+// println("OK");
+// }
+// catch { case e => {
+// println("ERROR");
+// errorStamp = s;
+// } }
+// }
+// }
+// }
+
+// }
+
+// if (args.length >= 1 && args(0) == "auto") {
+// remakeLoop;
+// }
+// else {
+// doMake;
+// }
diff --git a/infrastructure/net.appjet.common.cli/cli.scala b/infrastructure/net.appjet.common.cli/cli.scala
new file mode 100644
index 0000000..ef9223f
--- /dev/null
+++ b/infrastructure/net.appjet.common.cli/cli.scala
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.cli;
+
+import org.apache.commons.lang.WordUtils;
+
+class CliOption(val name: String, val description: String, val argName: Option[String]);
+
+class ParseException(message: String) extends RuntimeException(message);
+
+class CliParser(predef: Array[CliOption]) {
+ val displayWidth = 80;
+ val options = Map((for (opt <- predef) yield ((opt.name, opt))): _*);
+
+ def parseOptions(args0: Array[String]): (Map[String, String], Array[String]) = {
+ val (opts, args) = args0.partition(_.startsWith("-"));
+ (Map((for (arg <- opts) yield {
+ val parts = arg.split("=", 2);
+ val name = "-+".r.replaceFirstIn(parts(0), "");
+ if (parts.length == 1 && options.get(name).map(_.argName.isDefined).exists(x => x))
+ throw new ParseException("Missing argument for flag: "+name);
+ (name, parts.orElse(Map(1 -> "true"))(1));
+ }): _*),
+ args.toArray);
+ }
+
+ def dprint(prefix: String, value: String) = {
+// println(prefix+": "+value+"\n");
+ value;
+ }
+
+ def usage = {
+ val sb = new StringBuilder();
+ var maxLength = predef.map(opt => 2 + opt.name.length + opt.argName.map(_.length + 1).getOrElse(0) ).reduceRight(Math.max)+2;
+ for ((n, opt) <- options) {
+ sb.append(" --"+n+opt.argName.map("=<"+_+">").getOrElse("")+"\n");
+ sb.append(" "+WordUtils.wrap(opt.description, displayWidth-5).split("\n").mkString("\n "));
+ sb.append("\n\n");
+ }
+ sb.toString();
+ }
+}
diff --git a/infrastructure/net.appjet.common.sars/sars.scala b/infrastructure/net.appjet.common.sars/sars.scala
new file mode 100644
index 0000000..f91b292
--- /dev/null
+++ b/infrastructure/net.appjet.common.sars/sars.scala
@@ -0,0 +1,348 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.sars;
+
+import scala.collection.mutable.HashSet;
+import java.net.{Socket, ServerSocket, InetSocketAddress, SocketException};
+import java.io.{DataInputStream, DataOutputStream, IOException}
+import java.util.concurrent.atomic.AtomicBoolean;
+
+trait SarsMessageHandler {
+ def handle(s: String): Option[String] = None;
+ def handle(b: Array[byte]): Option[Array[byte]] = None;
+}
+
+class SarsException(m: String) extends RuntimeException(m);
+class ChannelClosedUnexpectedlyException extends SarsException("Sars channel closed unexpectedly.");
+class BadAuthKeyException extends SarsException("Sars authKey not accepted.");
+class NotAuthenticatedException extends SarsException("Sars must authenticate before sending message.");
+class UnknownTypeException(t: String) extends SarsException("Sars type unknown: "+t);
+
+private[sars] trait SarsMessageReaderWriter {
+ def byteArray = 1;
+ def utf8String = 2;
+
+ def inputStream: DataInputStream;
+ def outputStream: DataOutputStream;
+
+ def readMessage: Option[Any] = {
+ val messageType = inputStream.readInt;
+ if (messageType == byteArray) {
+ try {
+ val len = inputStream.readInt;
+ val bytes = new Array[byte](len);
+ inputStream.readFully(bytes);
+ Some(bytes);
+ } catch {
+ case ioe: IOException => None;
+ }
+ } else if (messageType == utf8String) {
+ try {
+ Some(inputStream.readUTF);
+ } catch {
+ case ioe: IOException => None;
+ }
+ } else {
+ throw new UnknownTypeException("type "+messageType);
+ }
+ }
+ def readString: Option[String] = {
+ val m = readMessage;
+ m.filter(_.isInstanceOf[String]).asInstanceOf[Option[String]];
+ }
+ def readBytes: Option[Array[byte]] = {
+ val m = readMessage;
+ m.filter(_.isInstanceOf[Array[byte]]).asInstanceOf[Option[Array[byte]]];
+ }
+ def writeMessage(bytes: Array[byte]) {
+ outputStream.writeInt(byteArray);
+ outputStream.writeInt(bytes.length);
+ outputStream.write(bytes);
+ }
+ def writeMessage(string: String) {
+ outputStream.writeInt(utf8String);
+ outputStream.writeUTF(string);
+ }
+}
+
+class SarsClient(authKey: String, host: String, port: Int) {
+
+ class SarsClientHandler(s: Socket) {
+ val readerWriter = new SarsMessageReaderWriter {
+ val inputStream = new DataInputStream(s.getInputStream());
+ val outputStream = new DataOutputStream(s.getOutputStream());
+ }
+ var authenticated = false;
+
+ def auth() {
+ val challenge = readerWriter.readString;
+ if (challenge.isEmpty) {
+ throw new ChannelClosedUnexpectedlyException;
+ }
+ readerWriter.writeMessage(SimpleSHA1(authKey+challenge.get));
+ val res = readerWriter.readString;
+ if (res.isEmpty || res.get != "ok") {
+ println(res.get);
+ throw new BadAuthKeyException;
+ }
+ authenticated = true;
+ }
+
+ def message[T](q: T, writer: T => Unit, reader: Unit => Option[T]): T = {
+ if (! authenticated) {
+ throw new NotAuthenticatedException;
+ }
+ try {
+ writer(q);
+ val res = reader();
+ if (res.isEmpty) {
+ throw new ChannelClosedUnexpectedlyException;
+ }
+ res.get;
+ } catch {
+ case e => {
+ if (! s.isClosed()) {
+ s.close();
+ }
+ throw e;
+ }
+ }
+ }
+
+ def message(s: String): String =
+ message[String](s, readerWriter.writeMessage, Unit => readerWriter.readString);
+
+ def message(b: Array[byte]): Array[byte] =
+ message[Array[byte]](b, readerWriter.writeMessage, Unit => readerWriter.readBytes);
+
+ def close() {
+ if (! s.isClosed) {
+ s.close();
+ }
+ }
+ }
+
+ var socket: Socket = null;
+ var connectTimeout = 0;
+ var readTimeout = 0;
+
+ def setConnectTimeout(timeout: Int) {
+ connectTimeout = timeout;
+ }
+ def setReadTimeout(timeout: Int) {
+ readTimeout = timeout;
+ }
+
+ var client: SarsClientHandler = null;
+ def connect() {
+ if (socket != null && ! socket.isClosed) {
+ socket.close();
+ }
+ socket = new Socket();
+ socket.connect(new InetSocketAddress(host, port), connectTimeout);
+ socket.setSoTimeout(readTimeout);
+ client = new SarsClientHandler(socket);
+ client.auth();
+ }
+
+ def message(q: String) = {
+ if (! socket.isConnected || socket.isClosed) {
+ connect();
+ }
+ client.message(q);
+ }
+
+ def message(b: Array[byte]) = {
+ if (! socket.isConnected || socket.isClosed) {
+ connect();
+ }
+ client.message(b);
+ }
+
+ def close() {
+ if (client != null) {
+ client.close();
+ }
+ }
+}
+
+class SarsServer(authKey: String, handler: SarsMessageHandler, host: Option[String], port: Int) {
+
+ // handles a single client.
+ class SarsServerHandler(cs: Socket) extends Runnable {
+ var thread: Thread = null;
+ var running = new AtomicBoolean(false);
+
+ def run() {
+ try {
+ thread = Thread.currentThread();
+ if (running.compareAndSet(false, true)) {
+ val readerWriter = new SarsMessageReaderWriter {
+ val inputStream = new DataInputStream(cs.getInputStream());
+ val outputStream = new DataOutputStream(cs.getOutputStream());
+ }
+ val challenge = Math.random*1e20;
+
+ readerWriter.writeMessage(String.valueOf(challenge));
+ val res = readerWriter.readString;
+ if (res.isEmpty || res.get != SimpleSHA1(authKey+challenge)) {
+ readerWriter.writeMessage("invalid key");
+ } else {
+ readerWriter.writeMessage("ok");
+ while (running.get()) {
+ val q = readerWriter.readMessage;
+ if (q.isEmpty) {
+ running.set(false);
+ } else {
+ q.get match {
+ case s: String => readerWriter.writeMessage(handler.handle(s).getOrElse(""));
+ case b: Array[byte] =>
+ readerWriter.writeMessage(handler.handle(b).getOrElse(new Array[byte](0)));
+ case x: AnyRef => throw new UnknownTypeException(x.getClass.getName);
+ }
+ }
+ }
+ }
+ }
+ } catch {
+ case e => { }
+ } finally {
+ cs.close();
+ }
+ }
+
+ def stop() {
+ if (running.compareAndSet(true, false)) {
+ thread.interrupt();
+ }
+ }
+ }
+
+ val ss = new ServerSocket(port);
+ if (host.isDefined) {
+ ss.bind(InetSocketAddress.createUnresolved(host.get, port));
+ }
+ var running = new AtomicBoolean(false);
+ var hasRun = false;
+ var serverThread: Thread = null;
+ val clients = new HashSet[SarsServerHandler];
+ var daemon = false;
+ val server = this;
+
+ def start() {
+ if (hasRun)
+ throw new RuntimeException("Can't reuse server.");
+ hasRun = true;
+ if (running.compareAndSet(false, true)) {
+ serverThread = new Thread() {
+ override def run() {
+ while(running.get()) {
+ val cs = try {
+ ss.accept();
+ } catch {
+ case e: SocketException => {
+ if (running.get()) {
+ println("socket exception.");
+ e.printStackTrace();
+ if (! ss.isClosed) {
+ ss.close();
+ }
+ return;
+ } else { // was closed by user.
+ return;
+ }
+ }
+ case e: IOException => {
+ println("i/o error");
+ e.printStackTrace();
+ ss.close();
+ return;
+ }
+ }
+ val client = new SarsServerHandler(cs);
+ server.synchronized {
+ clients += client;
+ }
+ (new Thread(client)).start();
+ }
+ }
+ }
+ if (daemon)
+ serverThread.setDaemon(true);
+ serverThread.start();
+ } else {
+ throw new RuntimeException("WTF, fool? Server's running already.");
+ }
+ }
+
+ def stop() {
+ if (running.compareAndSet(true, false)) {
+ if (! ss.isClosed) {
+ ss.close();
+ }
+ server.synchronized {
+ for (client <- clients) {
+ client.stop();
+ }
+ }
+ } else {
+ throw new RuntimeException("Not running.");
+ }
+ }
+
+ def join() {
+ serverThread.join();
+ }
+}
+
+object test {
+ def main(args: Array[String]) {
+ val handler = new SarsMessageHandler {
+ override def handle(s: String) = {
+ println("SERVER: "+s);
+ if (s == "hello!") {
+ Some("hey there.");
+ } else {
+ None;
+ }
+ }
+ override def handle(b: Array[byte]) = {
+ var actually = new String(b, "UTF-8");
+ println("SERVER: "+actually);
+ if (actually == "hello!") {
+ Some("hey there.".getBytes("UTF-8"));
+ } else {
+ None;
+ }
+ }
+ }
+
+ val server = new SarsServer("nopassword", handler, None, 9001);
+ server.start();
+
+ val client = new SarsClient("nopassword", "localhost", 9001);
+ client.connect();
+ println("CLIENT: "+client.message("hello!"));
+ println("CLIENT: "+client.message("goodbye!"));
+ println("CLIENT: "+new String(client.message("hello!".getBytes("UTF-8")), "UTF-8"));
+ println("CLIENT: "+new String(client.message("goodbye!".getBytes("UTF-8")), "UTF-8"));
+ client.close();
+ server.stop();
+ server.join();
+ println("done.");
+ }
+}
diff --git a/infrastructure/net.appjet.common.sars/sha1.scala b/infrastructure/net.appjet.common.sars/sha1.scala
new file mode 100644
index 0000000..8f9e69e
--- /dev/null
+++ b/infrastructure/net.appjet.common.sars/sha1.scala
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.sars;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+object SimpleSHA1 {
+ private val chars = Map(0 -> '0', 1 -> '1', 2 -> '2', 3 -> '3', 4 -> '4', 5 -> '5', 6 -> '6', 7 -> '7',
+ 8 -> '8', 9 -> '9', 10 -> 'a', 11 -> 'b', 12 -> 'c', 13 -> 'd', 14 -> 'e', 15 -> 'f');
+ private def convertToHex(data: Array[Byte]): String = {
+ val buf = new StringBuilder();
+ for (b <- data) {
+ buf.append(chars(b >>> 4 & 0x0F));
+ buf.append(chars(b & 0x0F));
+ }
+ buf.toString();
+ }
+
+ def apply(text: String): String = {
+ val md = MessageDigest.getInstance("SHA-1");
+ md.update(text.getBytes("UTF-8"), 0, text.length());
+ convertToHex(md.digest());
+ }
+}
diff --git a/infrastructure/net.appjet.common/rhino/rhinospect.scala b/infrastructure/net.appjet.common/rhino/rhinospect.scala
new file mode 100644
index 0000000..65f278c
--- /dev/null
+++ b/infrastructure/net.appjet.common/rhino/rhinospect.scala
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.rhino;
+
+import java.lang.reflect.Modifier;
+
+object rhinospect {
+
+ def visitFields(obj: Object, func: (String,Any)=>Unit) {
+ var cls: Class[_] = obj.getClass;
+
+ if (cls.isArray) {
+ import java.lang.reflect.Array;
+ for(i <- 0 until Array.getLength(obj)) {
+ func(String.valueOf(i), Array.get(obj, i));
+ }
+ }
+ else {
+ while (cls ne null) {
+ for (f <- cls.getDeclaredFields) {
+ if (! Modifier.isStatic(f.getModifiers)) {
+ f.setAccessible(true);
+ val nm = f.getName;
+ val vl = f.get(obj);
+ func(nm, vl);
+ }
+ }
+ cls = cls.getSuperclass;
+ }
+ }
+ }
+
+ def dumpFields(obj: Object, depth: Int, prefix: String): String = {
+ val s = new java.io.StringWriter();
+ val out = new java.io.PrintWriter(s);
+ visitFields(obj, (name: String, value: Any) => {
+ out.printf("%30s: %s\n", name+prefix, String.valueOf(value));
+ if (depth > 0 && value.isInstanceOf[Object]) {
+ out.print(dumpFields(value.asInstanceOf[Object], depth-1, prefix+" --"));
+ }
+ });
+ s.toString();
+ }
+}
diff --git a/infrastructure/net.appjet.common/util/BCrypt.java b/infrastructure/net.appjet.common/util/BCrypt.java
new file mode 100644
index 0000000..818c261
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/BCrypt.java
@@ -0,0 +1,752 @@
+package net.appjet.common.util;
+
+// Copyright (c) 2006 Damien Miller <djm@mindrot.org>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import java.io.UnsupportedEncodingException;
+
+import java.security.SecureRandom;
+
+/**
+ * BCrypt implements OpenBSD-style Blowfish password hashing using
+ * the scheme described in "A Future-Adaptable Password Scheme" by
+ * Niels Provos and David Mazieres.
+ * <p>
+ * This password hashing system tries to thwart off-line password
+ * cracking using a computationally-intensive hashing algorithm,
+ * based on Bruce Schneier's Blowfish cipher. The work factor of
+ * the algorithm is parameterised, so it can be increased as
+ * computers get faster.
+ * <p>
+ * Usage is really simple. To hash a password for the first time,
+ * call the hashpw method with a random salt, like this:
+ * <p>
+ * <code>
+ * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
+ * </code>
+ * <p>
+ * To check whether a plaintext password matches one that has been
+ * hashed previously, use the checkpw method:
+ * <p>
+ * <code>
+ * if (BCrypt.checkpw(candidate_password, stored_hash))<br />
+ * &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It matches");<br />
+ * else<br />
+ * &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It does not match");<br />
+ * </code>
+ * <p>
+ * The gensalt() method takes an optional parameter (log_rounds)
+ * that determines the computational complexity of the hashing:
+ * <p>
+ * <code>
+ * String strong_salt = BCrypt.gensalt(10)<br />
+ * String stronger_salt = BCrypt.gensalt(12)<br />
+ * </code>
+ * <p>
+ * The amount of work increases exponentially (2**log_rounds), so
+ * each increment is twice as much work. The default log_rounds is
+ * 10, and the valid range is 4 to 31.
+ *
+ * @author Damien Miller
+ * @version 0.2
+ */
+public class BCrypt {
+ // BCrypt parameters
+ private static int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
+ private static final int BCRYPT_SALT_LEN = 16;
+
+ // Blowfish parameters
+ private static final int BLOWFISH_NUM_ROUNDS = 16;
+
+ // Initial contents of key schedule
+ private static final int P_orig[] = {
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+ 0x9216d5d9, 0x8979fb1b
+ };
+ private static final int S_orig[] = {
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+ };
+
+ // bcrypt IV: "OrpheanBeholderScryDoubt"
+ static private final int bf_crypt_ciphertext[] = {
+ 0x4f727068, 0x65616e42, 0x65686f6c,
+ 0x64657253, 0x63727944, 0x6f756274
+ };
+
+ // Table for Base64 encoding
+ static private final char base64_code[] = {
+ '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+ 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9'
+ };
+
+ // Table for Base64 decoding
+ static private final byte index_64[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
+ -1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ -1, -1, -1, -1, -1, -1, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, -1, -1, -1, -1, -1
+ };
+
+ // Expanded Blowfish key
+ private int P[];
+ private int S[];
+
+ /**
+ * Encode a byte array using bcrypt's slightly-modified base64
+ * encoding scheme. Note that this is *not* compatible with
+ * the standard MIME-base64 encoding.
+ *
+ * @param d the byte array to encode
+ * @param len the number of bytes to encode
+ * @return base64-encoded string
+ * @exception IllegalArgumentException if the length is invalid
+ */
+ private static String encode_base64(byte d[], int len)
+ throws IllegalArgumentException {
+ int off = 0;
+ StringBuffer rs = new StringBuffer();
+ int c1, c2;
+
+ if (len <= 0 || len > d.length)
+ throw new IllegalArgumentException ("Invalid len");
+
+ while (off < len) {
+ c1 = d[off++] & 0xff;
+ rs.append(base64_code[(c1 >> 2) & 0x3f]);
+ c1 = (c1 & 0x03) << 4;
+ if (off >= len) {
+ rs.append(base64_code[c1 & 0x3f]);
+ break;
+ }
+ c2 = d[off++] & 0xff;
+ c1 |= (c2 >> 4) & 0x0f;
+ rs.append(base64_code[c1 & 0x3f]);
+ c1 = (c2 & 0x0f) << 2;
+ if (off >= len) {
+ rs.append(base64_code[c1 & 0x3f]);
+ break;
+ }
+ c2 = d[off++] & 0xff;
+ c1 |= (c2 >> 6) & 0x03;
+ rs.append(base64_code[c1 & 0x3f]);
+ rs.append(base64_code[c2 & 0x3f]);
+ }
+ return rs.toString();
+ }
+
+ /**
+ * Look up the 3 bits base64-encoded by the specified character,
+ * range-checking againt conversion table
+ * @param x the base64-encoded value
+ * @return the decoded value of x
+ */
+ private static byte char64(char x) {
+ if ((int)x < 0 || (int)x > index_64.length)
+ return -1;
+ return index_64[(int)x];
+ }
+
+ /**
+ * Decode a string encoded using bcrypt's base64 scheme to a
+ * byte array. Note that this is *not* compatible with
+ * the standard MIME-base64 encoding.
+ * @param s the string to decode
+ * @param maxolen the maximum number of bytes to decode
+ * @return an array containing the decoded bytes
+ * @throws IllegalArgumentException if maxolen is invalid
+ */
+ private static byte[] decode_base64(String s, int maxolen)
+ throws IllegalArgumentException {
+ StringBuffer rs = new StringBuffer();
+ int off = 0, slen = s.length(), olen = 0;
+ byte ret[];
+ byte c1, c2, c3, c4, o;
+
+ if (maxolen <= 0)
+ throw new IllegalArgumentException ("Invalid maxolen");
+
+ while (off < slen - 1 && olen < maxolen) {
+ c1 = char64(s.charAt(off++));
+ c2 = char64(s.charAt(off++));
+ if (c1 == -1 || c2 == -1)
+ break;
+ o = (byte)(c1 << 2);
+ o |= (c2 & 0x30) >> 4;
+ rs.append((char)o);
+ if (++olen >= maxolen || off >= slen)
+ break;
+ c3 = char64(s.charAt(off++));
+ if (c3 == -1)
+ break;
+ o = (byte)((c2 & 0x0f) << 4);
+ o |= (c3 & 0x3c) >> 2;
+ rs.append((char)o);
+ if (++olen >= maxolen || off >= slen)
+ break;
+ c4 = char64(s.charAt(off++));
+ o = (byte)((c3 & 0x03) << 6);
+ o |= c4;
+ rs.append((char)o);
+ ++olen;
+ }
+
+ ret = new byte[olen];
+ for (off = 0; off < olen; off++)
+ ret[off] = (byte)rs.charAt(off);
+ return ret;
+ }
+
+ /**
+ * Blowfish encipher a single 64-bit block encoded as
+ * two 32-bit halves
+ * @param lr an array containing the two 32-bit half blocks
+ * @param off the position in the array of the blocks
+ */
+ private final void encipher(int lr[], int off) {
+ int i, n, l = lr[off], r = lr[off + 1];
+
+ l ^= P[0];
+ for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
+ // Feistel substitution on left word
+ n = S[(l >> 24) & 0xff];
+ n += S[0x100 | ((l >> 16) & 0xff)];
+ n ^= S[0x200 | ((l >> 8) & 0xff)];
+ n += S[0x300 | (l & 0xff)];
+ r ^= n ^ P[++i];
+
+ // Feistel substitution on right word
+ n = S[(r >> 24) & 0xff];
+ n += S[0x100 | ((r >> 16) & 0xff)];
+ n ^= S[0x200 | ((r >> 8) & 0xff)];
+ n += S[0x300 | (r & 0xff)];
+ l ^= n ^ P[++i];
+ }
+ lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
+ lr[off + 1] = l;
+ }
+
+ /**
+ * Cycically extract a word of key material
+ * @param data the string to extract the data from
+ * @param offp a "pointer" (as a one-entry array) to the
+ * current offset into data
+ * @return the next word of material from data
+ */
+ private static int streamtoword(byte data[], int offp[]) {
+ int i;
+ int word = 0;
+ int off = offp[0];
+
+ for (i = 0; i < 4; i++) {
+ word = (word << 8) | (data[off] & 0xff);
+ off = (off + 1) % data.length;
+ }
+
+ offp[0] = off;
+ return word;
+ }
+
+ /**
+ * Initialise the Blowfish key schedule
+ */
+ private void init_key() {
+ P = (int[])P_orig.clone();
+ S = (int[])S_orig.clone();
+ }
+
+ /**
+ * Key the Blowfish cipher
+ * @param key an array containing the key
+ */
+ private void key(byte key[]) {
+ int i;
+ int koffp[] = { 0 };
+ int lr[] = { 0, 0 };
+ int plen = P.length, slen = S.length;
+
+ for (i = 0; i < plen; i++)
+ P[i] = P[i] ^ streamtoword(key, koffp);
+
+ for (i = 0; i < plen; i += 2) {
+ encipher(lr, 0);
+ P[i] = lr[0];
+ P[i + 1] = lr[1];
+ }
+
+ for (i = 0; i < slen; i += 2) {
+ encipher(lr, 0);
+ S[i] = lr[0];
+ S[i + 1] = lr[1];
+ }
+ }
+
+ /**
+ * Perform the "enhanced key schedule" step described by
+ * Provos and Mazieres in "A Future-Adaptable Password Scheme"
+ * http://www.openbsd.org/papers/bcrypt-paper.ps
+ * @param data salt information
+ * @param key password information
+ */
+ private void ekskey(byte data[], byte key[]) {
+ int i;
+ int koffp[] = { 0 }, doffp[] = { 0 };
+ int lr[] = { 0, 0 };
+ int plen = P.length, slen = S.length;
+
+ for (i = 0; i < plen; i++)
+ P[i] = P[i] ^ streamtoword(key, koffp);
+
+ for (i = 0; i < plen; i += 2) {
+ lr[0] ^= streamtoword(data, doffp);
+ lr[1] ^= streamtoword(data, doffp);
+ encipher(lr, 0);
+ P[i] = lr[0];
+ P[i + 1] = lr[1];
+ }
+
+ for (i = 0; i < slen; i += 2) {
+ lr[0] ^= streamtoword(data, doffp);
+ lr[1] ^= streamtoword(data, doffp);
+ encipher(lr, 0);
+ S[i] = lr[0];
+ S[i + 1] = lr[1];
+ }
+ }
+
+ /**
+ * Perform the central password hashing step in the
+ * bcrypt scheme
+ * @param password the password to hash
+ * @param salt the binary salt to hash with the password
+ * @param log_rounds the binary logarithm of the number
+ * of rounds of hashing to apply
+ * @return an array containing the binary hashed password
+ */
+ private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
+ int rounds, i, j;
+ int cdata[] = (int[])bf_crypt_ciphertext.clone();
+ int clen = cdata.length;
+ byte ret[];
+
+ if (log_rounds < 4 || log_rounds > 31)
+ throw new IllegalArgumentException ("Bad number of rounds");
+ rounds = 1 << log_rounds;
+ if (salt.length != BCRYPT_SALT_LEN)
+ throw new IllegalArgumentException ("Bad salt length");
+
+ init_key();
+ ekskey(salt, password);
+ for (i = 0; i < rounds; i++) {
+ key(password);
+ key(salt);
+ }
+
+ for (i = 0; i < 64; i++) {
+ for (j = 0; j < (clen >> 1); j++)
+ encipher(cdata, j << 1);
+ }
+
+ ret = new byte[clen * 4];
+ for (i = 0, j = 0; i < clen; i++) {
+ ret[j++] = (byte)((cdata[i] >> 24) & 0xff);
+ ret[j++] = (byte)((cdata[i] >> 16) & 0xff);
+ ret[j++] = (byte)((cdata[i] >> 8) & 0xff);
+ ret[j++] = (byte)(cdata[i] & 0xff);
+ }
+ return ret;
+ }
+
+ /**
+ * Hash a password using the OpenBSD bcrypt scheme
+ * @param password the password to hash
+ * @param salt the salt to hash with (perhaps generated
+ * using BCrypt.gensalt)
+ * @return the hashed password
+ */
+ public static String hashpw(String password, String salt) {
+ BCrypt B;
+ String real_salt;
+ byte passwordb[], saltb[], hashed[];
+ char minor = (char)0;
+ int rounds, off = 0;
+ StringBuffer rs = new StringBuffer();
+
+ if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
+ throw new IllegalArgumentException ("Invalid salt version");
+ if (salt.charAt(1) != '$') {
+ minor = salt.charAt(2);
+ if (minor != 'a' || salt.charAt(3) != '$')
+ throw new IllegalArgumentException ("Invalid salt revision");
+ off = 4;
+ } else
+ off = 3;
+
+ // Extract number of rounds
+ if (salt.charAt(off + 2) > '$')
+ throw new IllegalArgumentException ("Missing salt rounds");
+ rounds = Integer.parseInt(salt.substring(off, off + 2));
+
+ real_salt = salt.substring(off + 3, off + 25);
+ try {
+ passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("US-ASCII");
+ } catch (UnsupportedEncodingException uee) {
+ // The JDK guarantees that US-ASCII is supported.
+ throw new AssertionError("US-ASCII is not supported");
+ }
+
+ saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
+
+ B = new BCrypt();
+ hashed = B.crypt_raw(passwordb, saltb, rounds);
+
+ rs.append("$2");
+ if (minor >= 'a')
+ rs.append(minor);
+ rs.append("$");
+ if (rounds < 10)
+ rs.append("0");
+ rs.append(Integer.toString(rounds));
+ rs.append("$");
+ rs.append(encode_base64(saltb, saltb.length));
+ rs.append(encode_base64(hashed,
+ bf_crypt_ciphertext.length * 4 - 1));
+ return rs.toString();
+ }
+
+ /**
+ * Generate a salt for use with the BCrypt.hashpw() method
+ * @param log_rounds the log2 of the number of rounds of
+ * hashing to apply - the work factor therefore increases as
+ * 2**log_rounds.
+ * @param random an instance of SecureRandom to use
+ * @return an encoded salt value
+ */
+ public static String gensalt(int log_rounds, SecureRandom random) {
+ StringBuffer rs = new StringBuffer();
+ byte rnd[] = new byte[BCRYPT_SALT_LEN];
+
+ random.nextBytes(rnd);
+
+ rs.append("$2a$");
+ if (log_rounds < 10)
+ rs.append("0");
+ rs.append(Integer.toString(log_rounds));
+ rs.append("$");
+ rs.append(encode_base64(rnd, rnd.length));
+ return rs.toString();
+ }
+
+ /**
+ * Generate a salt for use with the BCrypt.hashpw() method
+ * @param log_rounds the log2 of the number of rounds of
+ * hashing to apply - the work factor therefore increases as
+ * 2**log_rounds.
+ * @return an encoded salt value
+ */
+ public static String gensalt(int log_rounds) {
+ return gensalt(log_rounds, new SecureRandom());
+ }
+
+ /**
+ * Generate a salt for use with the BCrypt.hashpw() method,
+ * selecting a reasonable default for the number of hashing
+ * rounds to apply
+ * @return an encoded salt value
+ */
+ public static String gensalt() {
+ return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS);
+ }
+
+ /**
+ * Check that a plaintext password matches a previously hashed
+ * one
+ * @param plaintext the plaintext password to verify
+ * @param hashed the previously-hashed password
+ * @return true if the passwords match, false otherwise
+ */
+ public static boolean checkpw(String plaintext, String hashed) {
+ return (hashed.compareTo(hashpw(plaintext, hashed)) == 0);
+ }
+}
diff --git a/infrastructure/net.appjet.common/util/BetterFile.java b/infrastructure/net.appjet.common/util/BetterFile.java
new file mode 100644
index 0000000..c674810
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/BetterFile.java
@@ -0,0 +1,280 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.*;
+
+
+/**
+ * A bunch of stuff that should've been in the Java Standard Libraries.
+ */
+public class BetterFile {
+ public static String getFileContents(File f, boolean t) throws FileNotFoundException {
+ FileInputStream in;
+ try {
+ in = new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ if (t) throw e;
+ return null;
+ }
+ return getStreamContents(in);
+ }
+
+ public static String getFileContents(File f) {
+ try {
+ return getFileContents(f, false);
+ } catch (FileNotFoundException e) {
+ // won't ever get here.
+ }
+ return null;
+ }
+
+ public static String getBinaryFileContents(File f) {
+ FileInputStream in;
+ try {
+ in = new FileInputStream(f);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ return getBinaryStreamContents(in);
+ }
+
+ // Using the non-converting String contructor here. Yum.
+ @SuppressWarnings({"deprecation"})
+ public static String getBinaryStreamContents(InputStream in) {
+ StringBuilder out = new StringBuilder();
+ byte[] b = new byte[4096];
+ try {
+ for (int n; (n = in.read(b)) != -1 ;) {
+ out.append(new String(b, 0, 0, n));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return out.toString();
+ }
+
+ public static String getStreamContents(InputStream instream) {
+ InputStreamReader in = new InputStreamReader(instream, java.nio.charset.Charset.forName("UTF-8"));
+ StringBuilder out = new StringBuilder();
+
+ char[] b = new char[4096];
+ try {
+ for (int n; (n = in.read(b)) != -1; ){
+ out.append(b, 0, n);
+ }
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return out.toString();
+ }
+
+ public static String getBinaryFileContents(String filename) {
+ return getBinaryFileContents(new File(filename));
+ }
+
+ public static String getFileContents(String filename) {
+ return getFileContents(new File(filename));
+ }
+
+ public static String getFileContents(String filename, boolean t) throws FileNotFoundException {
+ return getFileContents(new File(filename), t);
+ }
+
+ public static byte[] getStreamBytes(InputStream instream) {
+ byte[] b = new byte[8192];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(16384);
+ try {
+ for (int n; (n = instream.read(b)) != -1;) {
+ baos.write(b, 0, n);
+ }
+ instream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return baos.toByteArray();
+ }
+
+ public static String getReaderString(BufferedReader reader) {
+ StringBuffer out = new StringBuffer();
+ char[] c = new char[8192];
+ try {
+ for (int n; (n = reader.read(c, 0, c.length)) != -1;) {
+ out.append(c, 0, n);
+ }
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return out.toString();
+ }
+
+ public static byte[] getFileBytes(File f) {
+ try {
+ return getStreamBytes(new FileInputStream(f));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static byte[] getFileBytes(String filename) {
+ return getFileBytes(new File(filename));
+ }
+
+ public static String getUnicodeFile(File f) throws FileNotFoundException {
+ return getReaderString(new BufferedReader(new UnicodeReader(new FileInputStream(f), null)));
+ }
+
+ public static String getUnicodeFile(String filename) throws FileNotFoundException {
+ return getUnicodeFile(new File(filename));
+ }
+
+ public static String stringFromUnicode(byte[] bytes) {
+ return getReaderString(new BufferedReader(new UnicodeReader(new ByteArrayInputStream(bytes), null)));
+ }
+
+ // Ripped from: http://koti.mbnet.fi/akini/java/unicodereader/
+ /**
+ version: 1.1 / 2007-01-25
+ - changed BOM recognition ordering (longer boms first)
+
+ Original pseudocode : Thomas Weidenfeller
+ Implementation tweaked: Aki Nieminen
+
+ http://www.unicode.org/unicode/faq/utf_bom.html
+ BOMs:
+ 00 00 FE FF = UTF-32, big-endian
+ FF FE 00 00 = UTF-32, little-endian
+ EF BB BF = UTF-8,
+ FE FF = UTF-16, big-endian
+ FF FE = UTF-16, little-endian
+
+ Win2k Notepad:
+ Unicode format = UTF-16LE
+ ***/
+
+ /**
+ * Generic unicode textreader, which will use BOM mark
+ * to identify the encoding to be used. If BOM is not found
+ * then use a given default or system encoding.
+ */
+ public static class UnicodeReader extends Reader {
+ PushbackInputStream internalIn;
+ InputStreamReader internalIn2 = null;
+ String defaultEnc;
+
+ private static final int BOM_SIZE = 4;
+
+ /**
+ *
+ * @param in inputstream to be read
+ * @param defaultEnc default encoding if stream does not have
+ * BOM marker. Give NULL to use system-level default.
+ */
+ UnicodeReader(InputStream in, String defaultEnc) {
+ internalIn = new PushbackInputStream(in, BOM_SIZE);
+ this.defaultEnc = defaultEnc;
+ }
+
+ public String getDefaultEncoding() {
+ return defaultEnc;
+ }
+
+ /**
+ * Get stream encoding or NULL if stream is uninitialized.
+ * Call init() or read() method to initialize it.
+ */
+ public String getEncoding() {
+ if (internalIn2 == null) return null;
+ return internalIn2.getEncoding();
+ }
+
+ /**
+ * Read-ahead four bytes and check for BOM marks. Extra bytes are
+ * unread back to the stream, only BOM bytes are skipped.
+ */
+ protected void init() throws IOException {
+ if (internalIn2 != null) return;
+
+ String encoding;
+ byte bom[] = new byte[BOM_SIZE];
+ int n, unread;
+ n = internalIn.read(bom, 0, bom.length);
+
+ if ( (bom[0] == (byte)0x00) && (bom[1] == (byte)0x00) &&
+ (bom[2] == (byte)0xFE) && (bom[3] == (byte)0xFF) ) {
+ encoding = "UTF-32BE";
+ unread = n - 4;
+ } else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) &&
+ (bom[2] == (byte)0x00) && (bom[3] == (byte)0x00) ) {
+ encoding = "UTF-32LE";
+ unread = n - 4;
+ } else if ( (bom[0] == (byte)0xEF) && (bom[1] == (byte)0xBB) &&
+ (bom[2] == (byte)0xBF) ) {
+ encoding = "UTF-8";
+ unread = n - 3;
+ } else if ( (bom[0] == (byte)0xFE) && (bom[1] == (byte)0xFF) ) {
+ encoding = "UTF-16BE";
+ unread = n - 2;
+ } else if ( (bom[0] == (byte)0xFF) && (bom[1] == (byte)0xFE) ) {
+ encoding = "UTF-16LE";
+ unread = n - 2;
+ } else {
+ // Unicode BOM mark not found, unread all bytes
+ encoding = defaultEnc;
+ unread = n;
+ }
+ //System.out.println("read=" + n + ", unread=" + unread);
+
+ if (unread > 0) internalIn.unread(bom, (n - unread), unread);
+
+ // Use given encoding
+ if (encoding == null) {
+ internalIn2 = new InputStreamReader(internalIn);
+ } else {
+ internalIn2 = new InputStreamReader(internalIn, encoding);
+ }
+ }
+
+ public void close() throws IOException {
+ init();
+ internalIn2.close();
+ }
+
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ init();
+ return internalIn2.read(cbuf, off, len);
+ }
+
+ }
+}
diff --git a/infrastructure/net.appjet.common/util/ClassReload.java b/infrastructure/net.appjet.common/util/ClassReload.java
new file mode 100644
index 0000000..3fbc480
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/ClassReload.java
@@ -0,0 +1,263 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.util;
+
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+
+public class ClassReload {
+
+ /**
+ * To use: Optionally call initCompilerArgs, just like command-line
+ * starting after "scalac" or "fsc", do not use "-d", you may
+ * want to use "-classpath"/"-cp", no source files. Then call
+ * compile(...). Then load classes. isUpToDate() will tell you
+ * if source files have changed since compilation. If you want
+ * to compile again, use recompile() to create a new class-loader so that
+ * you can have new versions of existing classes. The class-loader
+ * behavior is to load classes that were generated during compilation
+ * using the output of compilation, and delegate all other classes to
+ * the parent loader.
+ */
+ public static class ScalaSourceClassLoader extends ClassLoader {
+ public ScalaSourceClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+ public ScalaSourceClassLoader() {
+ this(ScalaSourceClassLoader.class.getClassLoader());
+ }
+
+ private List<String> compilerArgs = Collections.emptyList();
+ private List<String> sourceFileList = Collections.emptyList();
+
+ private Map<File,Long> sourceFileMap = new HashMap<File,Long>();
+ private Map<String,byte[]> outputFileMap = new HashMap<String,byte[]>();
+
+ private boolean successfulCompile = false;
+
+ public void initCompilerArgs(String... args) {
+ compilerArgs = new ArrayList<String>();
+ for(String a : args) compilerArgs.add(a);
+ }
+
+ public boolean compile(String... sourceFiles) {
+ sourceFileList = new ArrayList<String>();
+ for(String a : sourceFiles) sourceFileList.add(a);
+
+ sourceFileMap.clear();
+ outputFileMap.clear();
+
+ File tempDir = makeTemporaryDir();
+ try {
+ List<String> argsToPass = new ArrayList<String>();
+ argsToPass.add("-d");
+ argsToPass.add(tempDir.getAbsolutePath());
+ argsToPass.addAll(compilerArgs);
+ for(String sf : sourceFileList) {
+ File f = new File(sf).getAbsoluteFile();
+ sourceFileMap.put(f, f.lastModified());
+ argsToPass.add(f.getPath());
+ }
+ String[] argsToPassArray = argsToPass.toArray(new String[0]);
+
+ int compileResult = invokeFSC(argsToPassArray);
+
+ if (compileResult != 0) {
+ successfulCompile = false;
+ return false;
+ }
+
+ for(String outputFile : listRecursive(tempDir)) {
+ outputFileMap.put(outputFile,
+ getFileBytes(new File(tempDir, outputFile)));
+ }
+
+ successfulCompile = true;
+ return true;
+ }
+ finally {
+ deleteRecursive(tempDir);
+ }
+ }
+
+ public ScalaSourceClassLoader recompile() {
+ ScalaSourceClassLoader sscl = new ScalaSourceClassLoader(getParent());
+ sscl.initCompilerArgs(compilerArgs.toArray(new String[0]));
+ sscl.compile(sourceFileList.toArray(new String[0]));
+ return sscl;
+ }
+
+ public boolean isSuccessfulCompile() {
+ return successfulCompile;
+ }
+
+ public boolean isUpToDate() {
+ for(Map.Entry<File,Long> entry : sourceFileMap.entrySet()) {
+ long mod = entry.getKey().lastModified();
+ if (mod == 0 || mod > entry.getValue()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override protected synchronized Class<?> loadClass(String name,
+ boolean resolve)
+ throws ClassNotFoundException {
+
+ // Based on java.lang.ClassLoader.loadClass(String,boolean)
+
+ // First, check if the class has already been loaded
+ Class<?> c = findLoadedClass(name);
+ if (c == null) {
+ String fileName = name.replace('.','/')+".class";
+ if (outputFileMap.containsKey(fileName)) {
+ // define it ourselves
+ byte b[] = outputFileMap.get(fileName);
+ c = defineClass(name, b, 0, b.length);
+ }
+ }
+ if (c != null) {
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ else {
+ // use super behavior
+ return super.loadClass(name, resolve);
+ }
+ }
+ }
+
+ private static byte[] readStreamFully(InputStream in) throws IOException {
+ InputStream from = new BufferedInputStream(in);
+ ByteArrayOutputStream to = new ByteArrayOutputStream(in.available());
+ ferry(from, to);
+ return to.toByteArray();
+ }
+
+ private static void ferry(InputStream from, OutputStream to)
+ throws IOException {
+
+ byte[] buf = new byte[1024];
+ boolean done = false;
+ while (! done) {
+ int numRead = from.read(buf);
+ if (numRead < 0) {
+ done = true;
+ }
+ else {
+ to.write(buf, 0, numRead);
+ }
+ }
+ from.close();
+ to.close();
+ }
+
+ private static Class<?> classForName(String name) {
+ try {
+ return Class.forName(name);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static boolean deleteRecursive(File f) {
+ if(f.exists()) {
+ File[] files = f.listFiles();
+ for(File g : files) {
+ if(g.isDirectory()) {
+ deleteRecursive(g);
+ }
+ else {
+ g.delete();
+ }
+ }
+ }
+ return f.delete();
+ }
+
+ static byte[] getFileBytes(File f) {
+ try {
+ return readStreamFully(new FileInputStream(f));
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static List<String> listRecursive(File dir) {
+ List<String> L = new ArrayList<String>();
+ listRecursive(dir, "", L);
+ return L;
+ }
+
+ static void listRecursive(File dir, String prefix, Collection<String> drop) {
+ for(File f : dir.listFiles()) {
+ if (f.isDirectory()) {
+ listRecursive(f, prefix + f.getName() + "/", drop);
+ }
+ else {
+ drop.add(prefix + f.getName());
+ }
+ }
+ }
+
+ static File makeTemporaryDir() {
+ try {
+ File f = File.createTempFile("ajclsreload", "").getAbsoluteFile();
+ if (! f.delete())
+ throw new RuntimeException("error creating temp dir");
+ if (! f.mkdir())
+ throw new RuntimeException("error creating temp dir");
+ return f;
+ }
+ catch (IOException e) {
+ throw new RuntimeException("error creating temp dir");
+ }
+ }
+
+ private static int invokeFSC(String[] args) {
+ try {
+ Class<?> fsc =
+ Class.forName("scala.tools.nsc.StandardCompileClient");
+ Object compiler = fsc.newInstance();
+ Method main0Method = fsc.getMethod("main0", String[].class);
+ return (Integer)main0Method.invoke(compiler, (Object)args);
+ }
+ catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+ catch (InstantiationException e) { throw new RuntimeException(e); }
+ catch (NoSuchMethodException e) { throw new RuntimeException(e); }
+ catch (IllegalAccessException e) { throw new RuntimeException(e); }
+ catch (InvocationTargetException e) {
+ Throwable origThrowable = e.getCause();
+ if (origThrowable == null) throw new RuntimeException(e);
+ else if (origThrowable instanceof Error) {
+ throw (Error)origThrowable;
+ }
+ else if (origThrowable instanceof RuntimeException) {
+ throw (RuntimeException)origThrowable;
+ }
+ else {
+ throw new RuntimeException(origThrowable);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/infrastructure/net.appjet.common/util/ExpiringMapping.java b/infrastructure/net.appjet.common/util/ExpiringMapping.java
new file mode 100644
index 0000000..d4b9d5a
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/ExpiringMapping.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.util;
+
+import java.util.*;
+
+// this class is synchronized
+
+public class ExpiringMapping<K,V> {
+
+ private Map<K,TimeStampedValue> keyToValue =
+ new HashMap<K,TimeStampedValue>();
+ private SortedMap<Long,K> timeToKey= new TreeMap<Long,K>();
+
+ private long lastTimeStamp = 0;
+
+ private ExpiryPolicy policy;
+
+ public ExpiringMapping(final long maxAgeMillis) {
+ this(new ExpiryPolicy() {
+ public boolean hasExpired(long timeStamp, long now, int rank) {
+ return now - timeStamp > maxAgeMillis;
+ }
+ });
+ }
+
+ protected ExpiringMapping(ExpiryPolicy policy) {
+ this.policy = policy;
+ }
+
+ public synchronized void clear() {
+ keyToValue.clear();
+ timeToKey.clear();
+ }
+
+ public synchronized void put(K key, V value) {
+ TimeStampedValue old = keyToValue.get(key);
+ if (old != null) {
+ timeToKey.remove(old.getTimeStamp());
+ }
+ TimeStampedValue newVal = new TimeStampedValue(value);
+ keyToValue.put(key, newVal);
+ timeToKey.put(newVal.getTimeStamp(), key);
+ checkExpiry();
+ }
+
+ public synchronized void touch(K key) {
+ TimeStampedValue old = keyToValue.get(key);
+ if (old != null) {
+ put(key, old.getValue());
+ }
+ }
+
+ public synchronized void remove(Object key) {
+ TimeStampedValue old = keyToValue.get(key);
+ if (old != null) {
+ keyToValue.remove(key);
+ timeToKey.remove(old.getTimeStamp());
+ }
+ }
+
+ // doesn't "touch" key or trigger expiry of expired items
+ public synchronized V get(Object key) {
+ if (keyToValue.containsKey(key)) {
+ return keyToValue.get(key).getValue();
+ } else {
+ return null;
+ }
+ }
+
+ public synchronized boolean containsKey(Object key) {
+ return keyToValue.containsKey(key);
+ }
+
+ public synchronized void checkExpiry() {
+ while (timeToKey.size() > 0) {
+ long oldestTime = timeToKey.firstKey();
+ if (hasExpired(oldestTime, timeToKey.size())) {
+ remove(timeToKey.get(oldestTime));
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ // lists keys in time order, oldest to newest
+ public synchronized List<K> listAllKeys() {
+ List<K> keyList = new java.util.ArrayList<K>(timeToKey.size());
+ for(Map.Entry<Long,K> entry : timeToKey.entrySet()) {
+ keyList.add(entry.getValue());
+ }
+ return Collections.unmodifiableList(keyList);
+ }
+
+ // result must be monotonic
+ private boolean hasExpired(long time, int rank) {
+ return policy.hasExpired(time, System.currentTimeMillis(), rank);
+ }
+
+ private long nowTimeStamp() {
+ // return "now", but unique
+ long now = System.currentTimeMillis();
+ if (now <= lastTimeStamp) {
+ now = lastTimeStamp+1;
+ }
+ lastTimeStamp = now;
+ return now;
+ }
+
+ private class TimeStampedValue {
+ private final V value;
+ private long timeStamp;
+ private TimeStampedValue(V value) {
+ this(value, nowTimeStamp());
+ }
+ private TimeStampedValue(V value, long timeStamp) {
+ this.value = value; this.timeStamp = timeStamp;
+ }
+ public void setTimeStamp(long ts) {
+ timeStamp = ts;
+ }
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+ public V getValue() {
+ return value;
+ }
+ public String toString() {
+ return "("+value+", "+new Date(timeStamp)+")";
+ }
+ }
+
+ public synchronized String toString() {
+ return keyToValue.toString();
+ }
+
+ protected interface ExpiryPolicy {
+ // result must be monotonic wrt timeStamp given now
+ boolean hasExpired(long timeStamp, long now, int rank);
+ }
+
+}
+
+ /*private static int compareLongs(long a, long b) {
+ if (a < b) return -1;
+ if (a > b) return 1;
+ return 0;
+ }*/
diff --git a/infrastructure/net.appjet.common/util/HttpServletRequestFactory.java b/infrastructure/net.appjet.common/util/HttpServletRequestFactory.java
new file mode 100644
index 0000000..4d7826a
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/HttpServletRequestFactory.java
@@ -0,0 +1,306 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.util;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URL;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Enumeration;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class HttpServletRequestFactory {
+ public static class RequestResponse {
+ public final HttpServletRequest request;
+ public final HttpServletResponse response;
+
+ private RequestResponse(HttpServletRequest req, HttpServletResponse res) {
+ request = req;
+ response = res;
+ }
+ }
+
+ public static HttpServletRequest createRequest(String uri, Map<String, String> headers,
+ String method, String body)
+ throws java.net.URISyntaxException {
+ return new InnerHttpServletRequest(new URI(uri), headers, method, body);
+ }
+
+ public static HttpServletRequest createRequest(HttpServletRequest req)
+ throws java.net.URISyntaxException {
+ Map<String, String> headers = new java.util.HashMap<String, String>();
+ Enumeration<String> headerNames = (Enumeration<String>) req.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String e = headerNames.nextElement();
+ headers.put(e, req.getHeader(e));
+ }
+ return createRequest(
+ req.getRequestURL() +
+ (req.getQueryString() != null ? "?"+req.getQueryString() : ""),
+ headers, req.getMethod(), null);
+ }
+
+ public static HttpServletResponse createResponse() {
+ return new InnerHttpServletResponse();
+ }
+
+ public static RequestResponse createPair(String uri, Map<String, String> headers,
+ String method, String body)
+ throws java.net.URISyntaxException {
+ return new RequestResponse(createRequest(uri, headers, method, body), createResponse());
+ }
+
+ public static interface ServletAccessor {
+ int getStatusCode();
+ String getOutput();
+ }
+
+ private static class InnerHttpServletRequest implements HttpServletRequest {
+ private String method;
+ private String host;
+ private String scheme;
+ private int port;
+ private String path;
+ private String queryString;
+ private Map<String, String[]> parameters;
+ private Map<String, String> headers;
+ private final String body;
+
+ public InnerHttpServletRequest(URI uri, Map<String, String> headers, String method,
+ String body)
+ throws java.net.URISyntaxException {
+ this.method = method;
+ this.host = uri.getHost();
+ this.scheme = uri.getScheme();
+ this.port = uri.getPort();
+ this.path = uri.getRawPath();
+ this.queryString = uri.getRawQuery();
+ extractParameters();
+ extractHeaders(headers);
+ this.headers.put("host", host);
+ if (body != null)
+ this.headers.put("content-length", Integer.toString(body.length()));
+ this.body = body;
+ }
+
+ private void extractHeaders(Map<String, String> headers) {
+ this.headers = new HashMap<String, String>();
+ for (Map.Entry<String, String> kv : headers.entrySet()) {
+ this.headers.put(kv.getKey().toLowerCase(), kv.getValue());
+ }
+ }
+
+ private String decodeUTF8(String s) {
+ try {
+ return URLDecoder.decode(s, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException e) {
+ System.err.println("Unsupported character encoding! UTF-8");
+ return s;
+ }
+ }
+
+ private void extractParameters() {
+ parameters = new HashMap<String, String[]>();
+ if (queryString == null)
+ return;
+
+ Map<String, List<String> > params = new HashMap<String, List<String> >();
+ String[] pairs = queryString.split("&");
+ for (String s : pairs) {
+ String[] kv = s.split("=", 2);
+ if (! params.containsKey(kv[0])) {
+ params.put(decodeUTF8(kv[0]), new ArrayList<String>());
+ }
+ params.get(decodeUTF8(kv[0])).add(decodeUTF8(kv[1]));
+ }
+ String[] stringArray = new String[0];
+
+ for (Map.Entry<String, List<String> > e : params.entrySet()) {
+ parameters.put(e.getKey(), e.getValue().toArray(stringArray));
+ }
+ }
+
+ // HttpServletRequest methods
+ public String getAuthType() { return null; }
+ public String getContextPath() { return ""; }
+ public javax.servlet.http.Cookie[] getCookies() { return new javax.servlet.http.Cookie[0]; }
+ @SuppressWarnings({"deprecation"})
+ public long getDateHeader(String name) { return java.util.Date.parse(getHeader(name)); }
+ public String getHeader(String name) { return headers.get(name.toLowerCase()); }
+ public Enumeration<String> getHeaders(String name) {
+ Vector<String> v = new Vector<String>();
+ v.add(getHeader(name));
+ return v.elements();
+ }
+ public Enumeration<String> getHeaderNames() {
+ return Collections.enumeration(headers.keySet());
+ }
+ public int getIntHeader(String name) { return Integer.parseInt(getHeader(name)); }
+ public String getMethod() { return method.toUpperCase(); }
+ public String getPathInfo() { return null; }
+ public String getPathTranslated() { return null; }
+ public String getQueryString() { return queryString; }
+ public String getRemoteUser() { return null; }
+ public boolean isUserInRole(String role) { return false; }
+ public java.security.Principal getUserPrincipal() { return null; }
+ public String getRequestedSessionId() { return null; }
+ public String getRequestURI() { return path; }
+ public StringBuffer getRequestURL() {
+ return new StringBuffer(scheme+"://"+host+(port==-1?"":":"+port)+path);
+ }
+ public String getServletPath() { return ""; }
+ public javax.servlet.http.HttpSession getSession(boolean create) { return null; }
+ public javax.servlet.http.HttpSession getSession() { return null; }
+ public boolean isRequestedSessionIdValid() { return false; }
+ public boolean isRequestedSessionIdFromCookie() { return false; }
+ public boolean isRequestedSessionIdFromURL() { return false; }
+ public boolean isRequestedSessionIdFromUrl() { return isRequestedSessionIdFromURL(); }
+
+ // ServletRequest methods
+ public Object getAttribute(String name) { return null; }
+ public Enumeration<String> getAttributeNames() {
+ return Collections.enumeration(new ArrayList<String>());
+ }
+ public String getCharacterEncoding() { return null; }
+ public void setCharacterEncoding(String env) { }
+ public int getContentLength() {
+ return ((getHeader("Content-Length") == null)
+ ? (body == null ? 0 : body.length())
+ : getIntHeader("Content-Length"));
+ }
+ public String getContentType() { return getHeader("Content-Type"); }
+ public javax.servlet.ServletInputStream getInputStream() throws java.io.IOException{
+ return new javax.servlet.ServletInputStream() {
+ private java.io.InputStream istream =
+ new java.io.ByteArrayInputStream(body.getBytes());
+ public int read() throws java.io.IOException {
+ return istream.read();
+ }
+ };
+ }
+ public String getParameter(String name) {
+ String[] vals = getParameterValues(name);
+ if (vals == null) return null;
+ if (vals.length < 1) return null;
+ return vals[0];
+ }
+ public Enumeration<String> getParameterNames() {
+ return Collections.enumeration(parameters.keySet());
+ }
+ public String[] getParameterValues(String name) { return parameters.get(name); }
+ public Map getParameterMap() { return Collections.unmodifiableMap(parameters); }
+ public String getProtocol() { return "HTTP/1.1"; }
+ public String getScheme() { return scheme; }
+ public String getServerName() { return host; }
+ public int getServerPort() { return port; }
+ public java.io.BufferedReader getReader() {
+ return new java.io.BufferedReader(new java.io.StringReader(body));
+ }
+ public String getRemoteAddr() { return "127.0.0.1"; }
+ public String getRemoteHost() { return "localhost"; }
+ public void setAttribute(String name, Object o) { }
+ public void removeAttribute(String name) { }
+ public java.util.Locale getLocale() { return java.util.Locale.US; }
+ public Enumeration<java.util.Locale> getLocales() {
+ Vector<java.util.Locale> v = new Vector<java.util.Locale>();
+ v.add(java.util.Locale.US);
+ return v.elements();
+ }
+ public boolean isSecure() { return false; }
+ public javax.servlet.RequestDispatcher getRequestDispatcher(String path) { return null; }
+ public String getRealPath(String path) { return null; }
+ public int getRemotePort() { return -1; }
+ public String getLocalName() { return "localhost"; }
+ public String getLocalAddr() { return "127.0.0.1"; }
+ public int getLocalPort() { return 80; }
+ }
+
+ private static class InnerHttpServletResponse implements HttpServletResponse, ServletAccessor {
+ private InnerHttpServletResponse() { }
+
+ // ServletAccessor methods
+ public int getStatusCode() { return e_code; }
+ public String getOutput() {
+ try {
+ writer.flush();
+ ostream.flush();
+ } catch (java.io.IOException e) {
+ return "(An IOException occurred while getting output: "+e.getMessage()+")";
+ }
+ return ostream.toString();
+ }
+
+ // HttpServletResponse methods
+ private int e_code = 200;
+ private String e_msg = "";
+
+ public void addCookie(javax.servlet.http.Cookie cookie) { }
+ public void addDateHeader(String name, long date) { }
+ public void addHeader(String name, String value) { }
+ public void addIntHeader(String name, int value) { }
+ public boolean containsHeader(String name) { return true; }
+ public String encodeRedirectUrl(String url) { return encodeRedirectURL(url); }
+ public String encodeRedirectURL(String url) { return url; }
+ public String encodeUrl(String url) { return encodeURL(url); }
+ public String encodeURL(String url) { return url; }
+ public void sendError(int sc) { e_code = sc; }
+ public void sendError(int sc, String msg) { e_code = sc; e_msg = msg;}
+ public void sendRedirect(String location) { }
+ public void setDateHeader(String name, long date) { }
+ public void setHeader(String name, String value) { }
+ public void setIntHeader(String name, int value) { }
+ public void setStatus(int sc) { e_code = sc; }
+ public void setStatus(int sc, String sm) { e_code = sc; e_msg = sm; }
+
+ // ServletResponse methods
+ private String c_enc = "";
+ private String c_type = "";
+ private java.util.Locale locale = java.util.Locale.US;
+ private final java.io.OutputStream ostream = new java.io.ByteArrayOutputStream();
+ private final javax.servlet.ServletOutputStream sostream =
+ new javax.servlet.ServletOutputStream() {
+ public void write(int b) throws java.io.IOException {
+ ostream.write(b);
+ }
+ };
+ private final java.io.PrintWriter writer = new java.io.PrintWriter(ostream);
+
+ public void flushBuffer() { }
+ public int getBufferSize() { return 0; }
+ public String getCharacterEncoding() { return c_enc; }
+ public String getContentType() { return c_type; }
+ public java.util.Locale getLocale() { return locale; }
+ public javax.servlet.ServletOutputStream getOutputStream() { return sostream; }
+ public java.io.PrintWriter getWriter() { return writer; }
+ public boolean isCommitted() { return false; }
+ public void reset() { }
+ public void resetBuffer() { }
+ public void setBufferSize(int size) { }
+ public void setCharacterEncoding(String charset) { c_enc = charset; }
+ public void setContentLength(int len) { }
+ public void setContentType(String type) { c_type = type; }
+ public void setLocale(java.util.Locale loc) { locale = loc; }
+ }
+} \ No newline at end of file
diff --git a/infrastructure/net.appjet.common/util/LenientFormatter.java b/infrastructure/net.appjet.common/util/LenientFormatter.java
new file mode 100644
index 0000000..293dcdf
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/LenientFormatter.java
@@ -0,0 +1,2809 @@
+/* Portions Copyright 2009 Google Inc.
+ * The rest licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF and Google license this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.appjet.common.util;
+
+import java.util.*;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+
+/**
+ * <p>The {@code LenientFormatter} class is a copy of {@code java.util.Formatter}
+ * that is lenient in the exact type of {@code java.lang.Number} passed into
+ * certain flags (integer, floating point, date, and character formats).</p>
+ *
+ * <p>The {@code Formatter} class is a String-formatting utility that is designed
+ * to work like the {@code printf} function of the C programming language.
+ * Its key methods are the {@code format} methods which create a formatted
+ * {@code String} by replacing a set of placeholders (format tokens) with formatted
+ * values. The style used to format each value is determined by the format
+ * token used. For example, the call<br/>
+ * {@code format("My decimal value is %d and my String is %s.", 3, "Hello");}<br/>
+ * returns the {@code String}<br/>
+ * {@code My decimal value is 3 and my String is Hello.}
+ *
+ * <p>The format token consists of a percent sign, optionally followed
+ * by flags and precision arguments, and then a single character that
+ * indicates the type of value
+ * being formatted. If the type is a time/date, then the type character
+ * {@code t} is followed by an additional character that indicates how the
+ * date is to be formatted. The two characters {@code <$} immediately
+ * following the % sign indicate that the previous value should be used again
+ * instead of moving on to the next value argument. A number {@code n}
+ * and a dollar sign immediately following the % sign make n the next argument
+ * to be used.
+ *
+ * <p>The available choices are the following:
+ *
+ * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Text value types</B></TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code s}</td>
+ * <td width="10%">String</td>
+ * <td width="30%">{@code format("%s, %s", "hello", "Hello");}</td>
+ * <td width="30%">{@code hello, Hello}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code S}, {@code s}</td>
+ * <td width="10%">String to capitals</td>
+ * <td width="30%">{@code format("%S, %S", "hello", "Hello");}</td>
+ * <td width="30%">{@code HELLO, HELLO}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code c}</td>
+ * <td width="10%">Character</td>
+ * <td width="30%">{@code format("%c, %c", 'd', 0x65);}</td>
+ * <td width="30%">{@code d, e}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code C}</td>
+ * <td width="10%">Character to capitals</td>
+ * <td width="30%">{@code format("%C, %C", 'd', 0x65);}</td>
+ * <td width="30%">{@code D, E}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Text option flags</B><br/>The value between the
+ * option and the type character indicates the minimum width in
+ * characters of the formatted value </TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code -}</td>
+ * <td width="10%">Left justify (width value is required)</td>
+ * <td width="30%">{@code format("%-3C, %3C", 'd', 0x65);}</td>
+ * <td width="30%">{@code D , E}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Integer types</B></TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code d}</td>
+ * <td width="10%">int, formatted as decimal</td>
+ * <td width="30%">{@code format("%d, %d"1$, 35, 0x10);}</td>
+ * <td width="30%">{@code 35, 16}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code o}</td>
+ * <td width="10%">int, formatted as octal</td>
+ * <td width="30%">{@code format("%o, %o", 8, 010);}</td>
+ * <td width="30%">{@code 10, 10}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code X}, {@code x}</td>
+ * <td width="10%">int, formatted as hexidecimal</td>
+ * <td width="30%">{@code format("%x, %X", 10, 10);}</td>
+ * <td width="30%">{@code a, A}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Integer option flags</B><br/>The value between the
+ * option and the type character indicates the minimum width in
+ * characters of the formatted value </TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code +}</td>
+ * <td width="10%">lead with the number's sign</td>
+ * <td width="30%">{@code format("%+d, %+4d", 5, 5);}</td>
+ * <td width="30%">{@code +5, +5}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code -}</td>
+ * <td width="10%">Left justify (width value is required)</td>
+ * <td width="30%">{@code format("%-6dx", 5);}</td>
+ * <td width="30%">{@code 5 x}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code #}</td>
+ * <td width="10%">Print the leading characters that indicate
+ * hexidecimal or octal (for use only with hex and octal types) </td>
+ * <td width="30%">{@code format("%#o", 010);}</td>
+ * <td width="30%">{@code 010}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code }</td>
+ * <td width="10%">A space indicates that non-negative numbers
+ * should have a leading space. </td>
+ * <td width="30%">{@code format("x% d% 5d", 4, 4);}</td>
+ * <td width="30%">{@code x 4 4}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code 0}</td>
+ * <td width="10%">Pad the number with leading zeros (width value is required)</td>
+ * <td width="30%">{@code format("%07d, %03d", 4, 5555);}</td>
+ * <td width="30%">{@code 0000004, 5555}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code (}</td>
+ * <td width="10%">Put parentheses around negative numbers (decimal only)</td>
+ * <td width="30%">{@code format("%(d, %(d, %(6d", 12, -12, -12);}</td>
+ * <td width="30%">{@code 12, (12), (12)}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Float types</B><br/>A value immediately following the % symbol
+ * gives the minimum width in characters of the formatted value; if it
+ * is followed by a period and another integer, then the second value
+ * gives the precision (6 by default).</TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code f}</td>
+ * <td width="10%">float (or double) formatted as a decimal, where
+ * the precision indicates the number of digits after the decimal.</td>
+ * <td width="30%">{@code format("%f %<.1f %<1.5f %<10f %<6.0f", 123.456f);}</td>
+ * <td width="30%">{@code 123.456001 123.5 123.45600 123.456001 123}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code E}, {@code e}</td>
+ * <td width="10%">float (or double) formatted in decimal exponential
+ * notation, where the precision indicates the number of significant digits.</td>
+ * <td width="30%">{@code format("%E %<.1e %<1.5E %<10E %<6.0E", 123.456f);}</td>
+ * <td width="30%">{@code 1.234560E+02 1.2e+02 1.23456E+02 1.234560E+02 1E+02}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code G}, {@code g}</td>
+ * <td width="10%">float (or double) formatted in decimal exponential
+ * notation , where the precision indicates the maximum number of significant digits.</td>
+ * <td width="30%">{@code format("%G %<.1g %<1.5G %<10G %<6.0G", 123.456f);}</td>
+ * <td width="30%">{@code 123.456 1e+02 123.46 123.456 1E+02}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code A}, {@code a}</td>
+ * <td width="10%">float (or double) formatted as a hexidecimal in exponential
+ * notation, where the precision indicates the number of significant digits.</td>
+ * <td width="30%">{@code format("%A %<.1a %<1.5A %<10A %<6.0A", 123.456f);}</td>
+ * <td width="30%">{@code 0X1.EDD2F2P6 0x1.fp6 0X1.EDD2FP6 0X1.EDD2F2P6 0X1.FP6}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Float-type option flags</B><br/>See the Integer-type options.
+ * The options for float-types are the
+ * same as for integer types with one addition: </TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code ,}</td>
+ * <td width="10%">Use a comma in place of a decimal if the locale
+ * requires it. </td>
+ * <td width="30%">{@code format(new Locale("fr"), "%,7.2f", 6.03f);}</td>
+ * <td width="30%">{@code 6,03}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Date types</B></TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code t}, {@code T}</td>
+ * <td width="10%">Date</td>
+ * <td width="30%">{@code format(new Locale("fr"), "%tB %TB", Calendar.getInstance(), Calendar.getInstance());}</td>
+ * <td width="30%">{@code avril AVRIL}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Date format precisions</B><br/>The format precision character
+ * follows the {@code t}. </TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code A}, {@code a}</td>
+ * <td width="10%">The day of the week</td>
+ * <td width="30%">{@code format("%ta %tA", cal, cal);}</td>
+ * <td width="30%">{@code Tue Tuesday}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code b}, {@code B}, {@code h}</td>
+ * <td width="10%">The name of the month</td>
+ * <td width="30%">{@code format("%tb %<tB %<th", cal, cal, cal);}</td>
+ * <td width="30%">{@code Apr April Apr}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code C}</td>
+ * <td width="10%">The century</td>
+ * <td width="30%">{@code format("%tC\n", cal);}</td>
+ * <td width="30%">{@code 20}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code d}, {@code e}</td>
+ * <td width="10%">The day of the month (with or without leading zeros)</td>
+ * <td width="30%">{@code format("%td %te", cal, cal);}</td>
+ * <td width="30%">{@code 01 1}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code F}</td>
+ * <td width="10%">The complete date formatted as YYYY-MM-DD</td>
+ * <td width="30%">{@code format("%tF", cal);}</td>
+ * <td width="30%">{@code 2008-04-01}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code D}</td>
+ * <td width="10%">The complete date formatted as MM/DD/YY
+ * (not corrected for locale) </td>
+ * <td width="30%">{@code format(new Locale("en_US"), "%tD", cal);<br/>format(new Locale("en_UK"), " %tD", cal);}</td>
+ * <td width="30%">{@code 04/01/08 04/01/08}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code j}</td>
+ * <td width="10%">The number of the day (from the beginning of the year).</td>
+ * <td width="30%">{@code format("%tj\n", cal);}</td>
+ * <td width="30%">{@code 092}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code m}</td>
+ * <td width="10%">The number of the month</td>
+ * <td width="30%">{@code format("%tm\n", cal);}</td>
+ * <td width="30%">{@code 04}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code y}, {@code Y}</td>
+ * <td width="10%">The year</td>
+ * <td width="30%">{@code format("%ty %tY", cal, cal);}</td>
+ * <td width="30%">{@code 08 2008}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code H}, {@code I}, {@code k}, {@code l}</td>
+ * <td width="10%">The hour of the day, in 12 or 24 hour format, with or
+ * without a leading zero</td>
+ * <td width="30%">{@code format("%tH %tI %tk %tl", cal, cal, cal, cal);}</td>
+ * <td width="30%">{@code 16 04 16 4}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code p}</td>
+ * <td width="10%">a.m. or p.m.</td>
+ * <td width="30%">{@code format("%tp %Tp", cal, cal);}</td>
+ * <td width="30%">{@code pm PM}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code M}, {@code S}, {@code L}, {@code N}</td>
+ * <td width="10%">The minutes, seconds, milliseconds, and nanoseconds</td>
+ * <td width="30%">{@code format("%tM %tS %tL %tN", cal, cal, cal, cal);}</td>
+ * <td width="30%">{@code 08 17 359 359000000}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code Z}, {@code z}</td>
+ * <td width="10%">The time zone: its abbreviation or offset from GMT</td>
+ * <td width="30%">{@code format("%tZ %tz", cal, cal);}</td>
+ * <td width="30%">{@code CEST +0100}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code R}, {@code r}, {@code T}</td>
+ * <td width="10%">The complete time</td>
+ * <td width="30%">{@code format("%tR %tr %tT", cal, cal, cal);}</td>
+ * <td width="30%">{@code 16:15 04:15:32 PM 16:15:32}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code s}, {@code Q}</td>
+ * <td width="10%">The number of seconds or milliseconds from "the epoch"
+ * (1 January 1970 00:00:00 UTC) </td>
+ * <td width="30%">{@code format("%ts %tQ", cal, cal);}</td>
+ * <td width="30%">{@code 1207059412 1207059412656}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code c}</td>
+ * <td width="10%">The complete time and date</td>
+ * <td width="30%">{@code format("%tc", cal);}</td>
+ * <td width="30%">{@code Tue Apr 01 16:19:17 CEST 2008}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Other data types</B></TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code B}, {@code b}</td>
+ * <td width="10%">Boolean</td>
+ * <td width="30%">{@code format("%b, %B", true, false);}</td>
+ * <td width="30%">{@code true, FALSE}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code H}, {@code h}</td>
+ * <td width="10%">Hashcode</td>
+ * <td width="30%">{@code format("%h, %H", obj, obj);}</td>
+ * <td width="30%">{@code 190d11, 190D11}</td>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code n}</td>
+ * <td width="10%">line separator</td>
+ * <td width="30%">{@code format("first%nsecond", "???");}</td>
+ * <td width="30%">{@code first<br/>second}</td>
+ * </tr>
+ * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+ * <TD COLSPAN=4>
+ * <B>Escape sequences</B></TD>
+ * </tr>
+ * <tr>
+ * <td width="5%">{@code %}</td>
+ * <td width="10%">Escape the % character</td>
+ * <td width="30%">{@code format("%d%%, %d", 50, 60);}</td>
+ * <td width="30%">{@code 50%, 60}</td>
+ * </tr>
+ * </table>
+ *
+ * <p>An instance of Formatter can be created to write the formatted
+ * output to standard types of output streams. Its functionality can
+ * also be accessed through the format methods of an output stream
+ * or of {@code String}:<br/>
+ * {@code System.out.println(String.format("%ty\n", cal));}<br/>
+ * {@code System.out.format("%ty\n", cal);}
+ *
+ * <p>The class is not multi-threaded safe. The user is responsible for
+ * maintaining a thread-safe design if a {@code Formatter} is
+ * accessed by multiple threads.
+ *
+ * @since 1.5
+ */
+public final class LenientFormatter implements Closeable, Flushable {
+
+ /**
+ * The enumeration giving the available styles for formatting very large
+ * decimal numbers.
+ */
+ public enum BigDecimalLayoutForm {
+ /**
+ * Use scientific style for BigDecimals.
+ */
+ SCIENTIFIC,
+ /**
+ * Use normal decimal/float style for BigDecimals.
+ */
+ DECIMAL_FLOAT
+ }
+
+ private Appendable out;
+
+ private Locale locale;
+
+ private boolean closed = false;
+
+ private IOException lastIOException;
+
+ /**
+ * Constructs a {@code Formatter}.
+ *
+ * The output is written to a {@code StringBuilder} which can be acquired by invoking
+ * {@link #out()} and whose content can be obtained by calling
+ * {@code toString()}.
+ *
+ * The {@code Locale} for the {@code LenientFormatter} is the default {@code Locale}.
+ */
+ public LenientFormatter() {
+ this(new StringBuilder(), Locale.getDefault());
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output will be written to the
+ * specified {@code Appendable}.
+ *
+ * The locale for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param a
+ * the output destination of the {@code Formatter}. If {@code a} is {@code null},
+ * then a {@code StringBuilder} will be used.
+ */
+ public LenientFormatter(Appendable a) {
+ this(a, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the specified {@code Locale}.
+ *
+ * The output is written to a {@code StringBuilder} which can be acquired by invoking
+ * {@link #out()} and whose content can be obtained by calling
+ * {@code toString()}.
+ *
+ * @param l
+ * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
+ * then no localization will be used.
+ */
+ public LenientFormatter(Locale l) {
+ this(new StringBuilder(), l);
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the specified {@code Locale}
+ * and whose output will be written to the
+ * specified {@code Appendable}.
+ *
+ * @param a
+ * the output destination of the {@code Formatter}. If {@code a} is {@code null},
+ * then a {@code StringBuilder} will be used.
+ * @param l
+ * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
+ * then no localization will be used.
+ */
+ public LenientFormatter(Appendable a, Locale l) {
+ if (null == a) {
+ out = new StringBuilder();
+ } else {
+ out = a;
+ }
+ locale = l;
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output is written to the specified file.
+ *
+ * The charset of the {@code Formatter} is the default charset.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param fileName
+ * the filename of the file that is used as the output
+ * destination for the {@code Formatter}. The file will be truncated to
+ * zero size if the file exists, or else a new file will be
+ * created. The output of the {@code Formatter} is buffered.
+ * @throws FileNotFoundException
+ * if the filename does not denote a normal and writable file,
+ * or if a new file cannot be created, or if any error arises when
+ * opening or creating the file.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the file in {@code checkWrite(file.getPath())}.
+ */
+ public LenientFormatter(String fileName) throws FileNotFoundException {
+ this(new File(fileName));
+
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output is written to the specified file.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param fileName
+ * the filename of the file that is used as the output
+ * destination for the {@code Formatter}. The file will be truncated to
+ * zero size if the file exists, or else a new file will be
+ * created. The output of the {@code Formatter} is buffered.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @throws FileNotFoundException
+ * if the filename does not denote a normal and writable file,
+ * or if a new file cannot be created, or if any error arises when
+ * opening or creating the file.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the file in {@code checkWrite(file.getPath())}.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(String fileName, String csn) throws FileNotFoundException,
+ UnsupportedEncodingException {
+ this(new File(fileName), csn);
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * and whose output is written to the specified file.
+ *
+ * @param fileName
+ * the filename of the file that is used as the output
+ * destination for the {@code Formatter}. The file will be truncated to
+ * zero size if the file exists, or else a new file will be
+ * created. The output of the {@code Formatter} is buffered.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @param l
+ * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
+ * then no localization will be used.
+ * @throws FileNotFoundException
+ * if the filename does not denote a normal and writable file,
+ * or if a new file cannot be created, or if any error arises when
+ * opening or creating the file.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the file in {@code checkWrite(file.getPath())}.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(String fileName, String csn, Locale l)
+ throws FileNotFoundException, UnsupportedEncodingException {
+
+ this(new File(fileName), csn, l);
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output is written to the specified {@code File}.
+ *
+ * The charset of the {@code Formatter} is the default charset.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param file
+ * the {@code File} that is used as the output destination for the
+ * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
+ * exists, or else a new {@code File} will be created. The output of the
+ * {@code Formatter} is buffered.
+ * @throws FileNotFoundException
+ * if the {@code File} is not a normal and writable {@code File}, or if a
+ * new {@code File} cannot be created, or if any error rises when opening or
+ * creating the {@code File}.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the {@code File} in {@code checkWrite(file.getPath())}.
+ */
+ public LenientFormatter(File file) throws FileNotFoundException {
+ this(new FileOutputStream(file));
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the given charset,
+ * and whose output is written to the specified {@code File}.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param file
+ * the {@code File} that is used as the output destination for the
+ * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
+ * exists, or else a new {@code File} will be created. The output of the
+ * {@code Formatter} is buffered.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @throws FileNotFoundException
+ * if the {@code File} is not a normal and writable {@code File}, or if a
+ * new {@code File} cannot be created, or if any error rises when opening or
+ * creating the {@code File}.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the {@code File} in {@code checkWrite(file.getPath())}.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(File file, String csn) throws FileNotFoundException,
+ UnsupportedEncodingException {
+ this(file, csn, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * and whose output is written to the specified {@code File}.
+ *
+ * @param file
+ * the {@code File} that is used as the output destination for the
+ * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
+ * exists, or else a new {@code File} will be created. The output of the
+ * {@code Formatter} is buffered.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @param l
+ * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
+ * then no localization will be used.
+ * @throws FileNotFoundException
+ * if the {@code File} is not a normal and writable {@code File}, or if a
+ * new {@code File} cannot be created, or if any error rises when opening or
+ * creating the {@code File}.
+ * @throws SecurityException
+ * if there is a {@code SecurityManager} in place which denies permission
+ * to write to the {@code File} in {@code checkWrite(file.getPath())}.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(File file, String csn, Locale l)
+ throws FileNotFoundException, UnsupportedEncodingException {
+ FileOutputStream fout = null;
+ try {
+ fout = new FileOutputStream(file);
+ OutputStreamWriter writer = new OutputStreamWriter(fout, csn);
+ out = new BufferedWriter(writer);
+ } catch (RuntimeException e) {
+ closeOutputStream(fout);
+ throw e;
+ } catch (UnsupportedEncodingException e) {
+ closeOutputStream(fout);
+ throw e;
+ }
+
+ locale = l;
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output is written to the specified {@code OutputStream}.
+ *
+ * The charset of the {@code Formatter} is the default charset.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param os
+ * the stream to be used as the destination of the {@code Formatter}.
+ */
+ public LenientFormatter(OutputStream os) {
+ OutputStreamWriter writer = new OutputStreamWriter(os, Charset
+ .defaultCharset());
+ out = new BufferedWriter(writer);
+ locale = Locale.getDefault();
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the given charset,
+ * and whose output is written to the specified {@code OutputStream}.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param os
+ * the stream to be used as the destination of the {@code Formatter}.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(OutputStream os, String csn)
+ throws UnsupportedEncodingException {
+
+ this(os, csn, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * and whose output is written to the specified {@code OutputStream}.
+ *
+ * @param os
+ * the stream to be used as the destination of the {@code Formatter}.
+ * @param csn
+ * the name of the charset for the {@code Formatter}.
+ * @param l
+ * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
+ * then no localization will be used.
+ * @throws UnsupportedEncodingException
+ * if the charset with the specified name is not supported.
+ */
+ public LenientFormatter(OutputStream os, String csn, Locale l)
+ throws UnsupportedEncodingException {
+
+ OutputStreamWriter writer = new OutputStreamWriter(os, csn);
+ out = new BufferedWriter(writer);
+
+ locale = l;
+ }
+
+ /**
+ * Constructs a {@code Formatter} whose output is written to the specified {@code PrintStream}.
+ *
+ * The charset of the {@code Formatter} is the default charset.
+ *
+ * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+ *
+ * @param ps
+ * the {@code PrintStream} used as destination of the {@code Formatter}. If
+ * {@code ps} is {@code null}, then a {@code NullPointerException} will
+ * be raised.
+ */
+ public LenientFormatter(PrintStream ps) {
+ if (null == ps) {
+ throw new NullPointerException();
+ }
+ out = ps;
+ locale = Locale.getDefault();
+ }
+
+ private void checkClosed() {
+ if (closed) {
+ throw new FormatterClosedException();
+ }
+ }
+
+ /**
+ * Returns the {@code Locale} of the {@code Formatter}.
+ *
+ * @return the {@code Locale} for the {@code Formatter} or {@code null} for no {@code Locale}.
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ public Locale locale() {
+ checkClosed();
+ return locale;
+ }
+
+ /**
+ * Returns the output destination of the {@code Formatter}.
+ *
+ * @return the output destination of the {@code Formatter}.
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ public Appendable out() {
+ checkClosed();
+ return out;
+ }
+
+ /**
+ * Returns the content by calling the {@code toString()} method of the output
+ * destination.
+ *
+ * @return the content by calling the {@code toString()} method of the output
+ * destination.
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ @Override
+ public String toString() {
+ checkClosed();
+ return out.toString();
+ }
+
+ /**
+ * Flushes the {@code Formatter}. If the output destination is {@link Flushable},
+ * then the method {@code flush()} will be called on that destination.
+ *
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ public void flush() {
+ checkClosed();
+ if (out instanceof Flushable) {
+ try {
+ ((Flushable) out).flush();
+ } catch (IOException e) {
+ lastIOException = e;
+ }
+ }
+ }
+
+ /**
+ * Closes the {@code Formatter}. If the output destination is {@link Closeable},
+ * then the method {@code close()} will be called on that destination.
+ *
+ * If the {@code Formatter} has been closed, then calling the this method will have no
+ * effect.
+ *
+ * Any method but the {@link #ioException()} that is called after the
+ * {@code Formatter} has been closed will raise a {@code FormatterClosedException}.
+ */
+ public void close() {
+ closed = true;
+ try {
+ if (out instanceof Closeable) {
+ ((Closeable) out).close();
+ }
+ } catch (IOException e) {
+
+ lastIOException = e;
+ }
+ }
+
+ /**
+ * Returns the last {@code IOException} thrown by the {@code Formatter}'s output
+ * destination. If the {@code append()} method of the destination does not throw
+ * {@code IOException}s, the {@code ioException()} method will always return {@code null}.
+ *
+ * @return the last {@code IOException} thrown by the {@code Formatter}'s output
+ * destination.
+ */
+ public IOException ioException() {
+ return lastIOException;
+ }
+
+ /**
+ * Writes a formatted string to the output destination of the {@code Formatter}.
+ *
+ * @param format
+ * a format string.
+ * @param args
+ * the arguments list used in the {@code format()} method. If there are
+ * more arguments than those specified by the format string, then
+ * the additional arguments are ignored.
+ * @return this {@code Formatter}.
+ * @throws IllegalFormatException
+ * if the format string is illegal or incompatible with the
+ * arguments, or if fewer arguments are sent than those required by
+ * the format string, or any other illegal situation.
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ public LenientFormatter format(String format, Object... args) {
+ return format(locale, format, args);
+ }
+
+ /**
+ * Writes a formatted string to the output destination of the {@code Formatter}.
+ *
+ * @param l
+ * the {@code Locale} used in the method. If {@code locale} is
+ * {@code null}, then no localization will be applied. This
+ * parameter does not influence the {@code Locale} specified during
+ * construction.
+ * @param format
+ * a format string.
+ * @param args
+ * the arguments list used in the {@code format()} method. If there are
+ * more arguments than those specified by the format string, then
+ * the additional arguments are ignored.
+ * @return this {@code Formatter}.
+ * @throws IllegalFormatException
+ * if the format string is illegal or incompatible with the
+ * arguments, or if fewer arguments are sent than those required by
+ * the format string, or any other illegal situation.
+ * @throws FormatterClosedException
+ * if the {@code Formatter} has been closed.
+ */
+ public LenientFormatter format(Locale l, String format, Object... args) {
+ checkClosed();
+ CharBuffer formatBuffer = CharBuffer.wrap(format);
+ ParserStateMachine parser = new ParserStateMachine(formatBuffer);
+ Transformer transformer = new Transformer(this, l);
+
+ int currentObjectIndex = 0;
+ Object lastArgument = null;
+ boolean hasLastArgumentSet = false;
+ while (formatBuffer.hasRemaining()) {
+ parser.reset();
+ FormatToken token = parser.getNextFormatToken();
+ String result;
+ String plainText = token.getPlainText();
+ if (token.getConversionType() == (char) FormatToken.UNSET) {
+ result = plainText;
+ } else {
+ plainText = plainText.substring(0, plainText.indexOf('%'));
+ Object argument = null;
+ if (token.requireArgument()) {
+ int index = token.getArgIndex() == FormatToken.UNSET ? currentObjectIndex++
+ : token.getArgIndex();
+ argument = getArgument(args, index, token, lastArgument,
+ hasLastArgumentSet);
+ lastArgument = argument;
+ hasLastArgumentSet = true;
+ }
+ result = transformer.transform(token, argument);
+ result = (null == result ? plainText : plainText + result);
+ }
+ // if output is made by formattable callback
+ if (null != result) {
+ try {
+ out.append(result);
+ } catch (IOException e) {
+ lastIOException = e;
+ }
+ }
+ }
+ return this;
+ }
+
+ private Object getArgument(Object[] args, int index, FormatToken token,
+ Object lastArgument, boolean hasLastArgumentSet) {
+ if (index == FormatToken.LAST_ARGUMENT_INDEX && !hasLastArgumentSet) {
+ throw new MissingFormatArgumentException("<"); //$NON-NLS-1$
+ }
+
+ if (null == args) {
+ return null;
+ }
+
+ if (index >= args.length) {
+ throw new MissingFormatArgumentException(token.getPlainText());
+ }
+
+ if (index == FormatToken.LAST_ARGUMENT_INDEX) {
+ return lastArgument;
+ }
+
+ return args[index];
+ }
+
+ private static void closeOutputStream(OutputStream os) {
+ if (null == os) {
+ return;
+ }
+ try {
+ os.close();
+
+ } catch (IOException e) {
+ // silently
+ }
+ }
+
+ /*
+ * Information about the format string of a specified argument, which
+ * includes the conversion type, flags, width, precision and the argument
+ * index as well as the plainText that contains the whole format string used
+ * as the result for output if necessary. Besides, the string for flags is
+ * recorded to construct corresponding FormatExceptions if necessary.
+ */
+ private static class FormatToken {
+
+ static final int LAST_ARGUMENT_INDEX = -2;
+
+ static final int UNSET = -1;
+
+ static final int FLAGS_UNSET = 0;
+
+ static final int DEFAULT_PRECISION = 6;
+
+ static final int FLAG_MINUS = 1;
+
+ static final int FLAG_SHARP = 1 << 1;
+
+ static final int FLAG_ADD = 1 << 2;
+
+ static final int FLAG_SPACE = 1 << 3;
+
+ static final int FLAG_ZERO = 1 << 4;
+
+ static final int FLAG_COMMA = 1 << 5;
+
+ static final int FLAG_PARENTHESIS = 1 << 6;
+
+ private static final int FLAGT_TYPE_COUNT = 6;
+
+ private int formatStringStartIndex;
+
+ private String plainText;
+
+ private int argIndex = UNSET;
+
+ private int flags = 0;
+
+ private int width = UNSET;
+
+ private int precision = UNSET;
+
+ private StringBuilder strFlags = new StringBuilder(FLAGT_TYPE_COUNT);
+
+ private char dateSuffix;// will be used in new feature.
+
+ private char conversionType = (char) UNSET;
+
+ boolean isPrecisionSet() {
+ return precision != UNSET;
+ }
+
+ boolean isWidthSet() {
+ return width != UNSET;
+ }
+
+ boolean isFlagSet(int flag) {
+ return 0 != (flags & flag);
+ }
+
+ int getArgIndex() {
+ return argIndex;
+ }
+
+ void setArgIndex(int index) {
+ argIndex = index;
+ }
+
+ String getPlainText() {
+ return plainText;
+ }
+
+ void setPlainText(String plainText) {
+ this.plainText = plainText;
+ }
+
+ int getWidth() {
+ return width;
+ }
+
+ void setWidth(int width) {
+ this.width = width;
+ }
+
+ int getPrecision() {
+ return precision;
+ }
+
+ void setPrecision(int precise) {
+ this.precision = precise;
+ }
+
+ String getStrFlags() {
+ return strFlags.toString();
+ }
+
+ int getFlags() {
+ return flags;
+ }
+
+ void setFlags(int flags) {
+ this.flags = flags;
+ }
+
+ /*
+ * Sets qualified char as one of the flags. If the char is qualified,
+ * sets it as a flag and returns true. Or else returns false.
+ */
+ boolean setFlag(char c) {
+ int newFlag;
+ switch (c) {
+ case '-': {
+ newFlag = FLAG_MINUS;
+ break;
+ }
+ case '#': {
+ newFlag = FLAG_SHARP;
+ break;
+ }
+ case '+': {
+ newFlag = FLAG_ADD;
+ break;
+ }
+ case ' ': {
+ newFlag = FLAG_SPACE;
+ break;
+ }
+ case '0': {
+ newFlag = FLAG_ZERO;
+ break;
+ }
+ case ',': {
+ newFlag = FLAG_COMMA;
+ break;
+ }
+ case '(': {
+ newFlag = FLAG_PARENTHESIS;
+ break;
+ }
+ default:
+ return false;
+ }
+ if (0 != (flags & newFlag)) {
+ throw new DuplicateFormatFlagsException(String.valueOf(c));
+ }
+ flags = (flags | newFlag);
+ strFlags.append(c);
+ return true;
+
+ }
+
+ int getFormatStringStartIndex() {
+ return formatStringStartIndex;
+ }
+
+ void setFormatStringStartIndex(int index) {
+ formatStringStartIndex = index;
+ }
+
+ char getConversionType() {
+ return conversionType;
+ }
+
+ void setConversionType(char c) {
+ conversionType = c;
+ }
+
+ char getDateSuffix() {
+ return dateSuffix;
+ }
+
+ void setDateSuffix(char c) {
+ dateSuffix = c;
+ }
+
+ boolean requireArgument() {
+ return conversionType != '%' && conversionType != 'n';
+ }
+ }
+
+ /*
+ * Transforms the argument to the formatted string according to the format
+ * information contained in the format token.
+ */
+ private static class Transformer {
+
+ private LenientFormatter formatter;
+
+ private FormatToken formatToken;
+
+ private Object arg;
+
+ private Locale locale;
+
+ private static String lineSeparator;
+
+ private NumberFormat numberFormat;
+
+ private DecimalFormatSymbols decimalFormatSymbols;
+
+ private DateTimeUtil dateTimeUtil;
+
+ Transformer(LenientFormatter formatter, Locale locale) {
+ this.formatter = formatter;
+ this.locale = (null == locale ? Locale.US : locale);
+ }
+
+ private NumberFormat getNumberFormat() {
+ if (null == numberFormat) {
+ numberFormat = NumberFormat.getInstance(locale);
+ }
+ return numberFormat;
+ }
+
+ private DecimalFormatSymbols getDecimalFormatSymbols() {
+ if (null == decimalFormatSymbols) {
+ decimalFormatSymbols = new DecimalFormatSymbols(locale);
+ }
+ return decimalFormatSymbols;
+ }
+
+ /*
+ * Gets the formatted string according to the format token and the
+ * argument.
+ */
+ String transform(FormatToken token, Object argument) {
+
+ /* init data member to print */
+ this.formatToken = token;
+ this.arg = argument;
+
+ String result;
+ switch (token.getConversionType()) {
+ case 'B':
+ case 'b': {
+ result = transformFromBoolean();
+ break;
+ }
+ case 'H':
+ case 'h': {
+ result = transformFromHashCode();
+ break;
+ }
+ case 'S':
+ case 's': {
+ result = transformFromString();
+ break;
+ }
+ case 'C':
+ case 'c': {
+ result = transformFromCharacter();
+ break;
+ }
+ case 'd':
+ case 'o':
+ case 'x':
+ case 'X': {
+ if (null == arg || arg instanceof BigInteger) {
+ result = transformFromBigInteger();
+ } else {
+ result = transformFromInteger();
+ }
+ break;
+ }
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ case 'f':
+ case 'a':
+ case 'A': {
+ result = transformFromFloat();
+ break;
+ }
+ case '%': {
+ result = transformFromPercent();
+ break;
+ }
+ case 'n': {
+ result = transformFromLineSeparator();
+ break;
+ }
+ case 't':
+ case 'T': {
+ result = transformFromDateTime();
+ break;
+ }
+ default: {
+ throw new UnknownFormatConversionException(String
+ .valueOf(token.getConversionType()));
+ }
+ }
+
+ if (Character.isUpperCase(token.getConversionType())) {
+ if (null != result) {
+ result = result.toUpperCase(Locale.US);
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Transforms the Boolean argument to a formatted string.
+ */
+ private String transformFromBoolean() {
+ StringBuilder result = new StringBuilder();
+ int startIndex = 0;
+ int flags = formatToken.getFlags();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && !formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + formatToken.getConversionType());
+ }
+
+ // only '-' is valid for flags
+ if (FormatToken.FLAGS_UNSET != flags
+ && FormatToken.FLAG_MINUS != flags) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), formatToken.getConversionType());
+ }
+
+ if (null == arg) {
+ result.append("false"); //$NON-NLS-1$
+ } else if (arg instanceof Boolean) {
+ result.append(arg);
+ } else {
+ result.append("true"); //$NON-NLS-1$
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms the hashcode of the argument to a formatted string.
+ */
+ private String transformFromHashCode() {
+ StringBuilder result = new StringBuilder();
+
+ int startIndex = 0;
+ int flags = formatToken.getFlags();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && !formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + formatToken.getConversionType());
+ }
+
+ // only '-' is valid for flags
+ if (FormatToken.FLAGS_UNSET != flags
+ && FormatToken.FLAG_MINUS != flags) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), formatToken.getConversionType());
+ }
+
+ if (null == arg) {
+ result.append("null"); //$NON-NLS-1$
+ } else {
+ result.append(Integer.toHexString(arg.hashCode()));
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms the String to a formatted string.
+ */
+ private String transformFromString() {
+ StringBuilder result = new StringBuilder();
+ int startIndex = 0;
+ int flags = formatToken.getFlags();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && !formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + formatToken.getConversionType());
+ }
+
+ // only '-' is valid for flags if the argument is not an
+ // instance of Formattable
+ if (FormatToken.FLAGS_UNSET != flags
+ && FormatToken.FLAG_MINUS != flags) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), formatToken.getConversionType());
+ }
+
+ result.append(arg);
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms the Character to a formatted string.
+ */
+ private String transformFromCharacter() {
+ StringBuilder result = new StringBuilder();
+
+ int startIndex = 0;
+ int flags = formatToken.getFlags();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && !formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + formatToken.getConversionType());
+ }
+
+ // only '-' is valid for flags
+ if (FormatToken.FLAGS_UNSET != flags
+ && FormatToken.FLAG_MINUS != flags) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), formatToken.getConversionType());
+ }
+
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+
+ if (null == arg) {
+ result.append("null"); //$NON-NLS-1$
+ } else {
+ if (arg instanceof Character) {
+ result.append(arg);
+ } else if (arg instanceof Byte) {
+ byte b = ((Byte) arg).byteValue();
+ if (!Character.isValidCodePoint(b)) {
+ throw new IllegalFormatCodePointException(b);
+ }
+ result.append((char) b);
+ } else if (arg instanceof Short) {
+ short s = ((Short) arg).shortValue();
+ if (!Character.isValidCodePoint(s)) {
+ throw new IllegalFormatCodePointException(s);
+ }
+ result.append((char) s);
+ } else if (arg instanceof Number) {
+ int codePoint = ((Number) arg).intValue();
+ if (!Character.isValidCodePoint(codePoint)) {
+ throw new IllegalFormatCodePointException(codePoint);
+ }
+ result.append(String.valueOf(Character.toChars(codePoint)));
+ } else {
+ // argument of other class is not acceptable.
+ throw new IllegalFormatConversionException(formatToken
+ .getConversionType(), arg.getClass());
+ }
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms percent to a formatted string. Only '-' is legal flag.
+ * Precision is illegal.
+ */
+ private String transformFromPercent() {
+ StringBuilder result = new StringBuilder("%"); //$NON-NLS-1$
+
+ int startIndex = 0;
+ int flags = formatToken.getFlags();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && !formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + formatToken.getConversionType());
+ }
+
+ if (FormatToken.FLAGS_UNSET != flags
+ && FormatToken.FLAG_MINUS != flags) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), formatToken.getConversionType());
+ }
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms line separator to a formatted string. Any flag, the width
+ * or the precision is illegal.
+ */
+ private String transformFromLineSeparator() {
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+
+ if (formatToken.isWidthSet()) {
+ throw new IllegalFormatWidthException(formatToken.getWidth());
+ }
+
+ int flags = formatToken.getFlags();
+ if (FormatToken.FLAGS_UNSET != flags) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ if (null == lineSeparator) {
+ lineSeparator = AccessController
+ .doPrivileged(new PrivilegedAction<String>() {
+
+ public String run() {
+ return System.getProperty("line.separator"); //$NON-NLS-1$
+ }
+ });
+ }
+ return lineSeparator;
+ }
+
+ /*
+ * Pads characters to the formatted string.
+ */
+ private String padding(StringBuilder source, int startIndex) {
+ int start = startIndex;
+ boolean paddingRight = formatToken
+ .isFlagSet(FormatToken.FLAG_MINUS);
+ char paddingChar = '\u0020';// space as padding char.
+ if (formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ if ('d' == formatToken.getConversionType()) {
+ paddingChar = getDecimalFormatSymbols().getZeroDigit();
+ } else {
+ paddingChar = '0';
+ }
+ } else {
+ // if padding char is space, always padding from the head
+ // location.
+ start = 0;
+ }
+ int width = formatToken.getWidth();
+ int precision = formatToken.getPrecision();
+
+ int length = source.length();
+ if (precision >= 0) {
+ length = Math.min(length, precision);
+ source.delete(length, source.length());
+ }
+ if (width > 0) {
+ width = Math.max(source.length(), width);
+ }
+ if (length >= width) {
+ return source.toString();
+ }
+
+ char[] paddings = new char[width - length];
+ Arrays.fill(paddings, paddingChar);
+ String insertString = new String(paddings);
+
+ if (paddingRight) {
+ source.append(insertString);
+ } else {
+ source.insert(start, insertString);
+ }
+ return source.toString();
+ }
+
+ /*
+ * Transforms the Integer to a formatted string.
+ */
+ private String transformFromInteger() {
+ int startIndex = 0;
+ boolean isNegative = false;
+ StringBuilder result = new StringBuilder();
+ char currentConversionType = formatToken.getConversionType();
+ long value;
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ || formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ if (!formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException(formatToken
+ .getStrFlags());
+ }
+ }
+ // Combination of '+' & ' ' is illegal.
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)
+ && formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+ if (arg instanceof Long) {
+ value = ((Long) arg).longValue();
+ } else if (arg instanceof Integer) {
+ value = ((Integer) arg).longValue();
+ } else if (arg instanceof Short) {
+ value = ((Short) arg).longValue();
+ } else if (arg instanceof Byte) {
+ value = ((Byte) arg).longValue();
+ }
+ else if (arg instanceof Number) {
+ value = ((Number) arg).longValue();
+ } else {
+ throw new IllegalFormatConversionException(formatToken
+ .getConversionType(), arg.getClass());
+ }
+ if ('d' != currentConversionType) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)
+ || formatToken.isFlagSet(FormatToken.FLAG_SPACE)
+ || formatToken.isFlagSet(FormatToken.FLAG_COMMA)
+ || formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ throw new FormatFlagsConversionMismatchException(
+ formatToken.getStrFlags(), formatToken
+ .getConversionType());
+ }
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)) {
+ if ('d' == currentConversionType) {
+ throw new FormatFlagsConversionMismatchException(
+ formatToken.getStrFlags(), formatToken
+ .getConversionType());
+ } else if ('o' == currentConversionType) {
+ result.append("0"); //$NON-NLS-1$
+ startIndex += 1;
+ } else {
+ result.append("0x"); //$NON-NLS-1$
+ startIndex += 2;
+ }
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ if (value < 0) {
+ isNegative = true;
+ }
+
+ if ('d' == currentConversionType) {
+ NumberFormat numberFormat = getNumberFormat();
+ if (formatToken.isFlagSet(FormatToken.FLAG_COMMA)) {
+ numberFormat.setGroupingUsed(true);
+ } else {
+ numberFormat.setGroupingUsed(false);
+ }
+ result.append(numberFormat.format(arg));
+ } else {
+ long BYTE_MASK = 0x00000000000000FFL;
+ long SHORT_MASK = 0x000000000000FFFFL;
+ long INT_MASK = 0x00000000FFFFFFFFL;
+ if (isNegative) {
+ if (arg instanceof Byte) {
+ value &= BYTE_MASK;
+ } else if (arg instanceof Short) {
+ value &= SHORT_MASK;
+ } else if (arg instanceof Integer) {
+ value &= INT_MASK;
+ }
+ }
+ if ('o' == currentConversionType) {
+ result.append(Long.toOctalString(value));
+ } else {
+ result.append(Long.toHexString(value));
+ }
+ isNegative = false;
+ }
+
+ if (!isNegative) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)) {
+ result.insert(0, '+');
+ startIndex += 1;
+ }
+ if (formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ result.insert(0, ' ');
+ startIndex += 1;
+ }
+ }
+
+ /* pad paddingChar to the output */
+ if (isNegative
+ && formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ result = wrapParentheses(result);
+ return result.toString();
+
+ }
+ if (isNegative && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ startIndex++;
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * add () to the output,if the value is negative and
+ * formatToken.FLAG_PARENTHESIS is set. 'result' is used as an in-out
+ * parameter.
+ */
+ private StringBuilder wrapParentheses(StringBuilder result) {
+ // delete the '-'
+ result.deleteCharAt(0);
+ result.insert(0, '(');
+ if (formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ formatToken.setWidth(formatToken.getWidth() - 1);
+ padding(result, 1);
+ result.append(')');
+ } else {
+ result.append(')');
+ padding(result, 0);
+ }
+ return result;
+ }
+
+ private String transformFromSpecialNumber() {
+ String source = null;
+
+ if (!(arg instanceof Number) || arg instanceof BigDecimal) {
+ return null;
+ }
+
+ Number number = (Number) arg;
+ double d = number.doubleValue();
+ if (Double.isNaN(d)) {
+ source = "NaN"; //$NON-NLS-1$
+ } else if (Double.isInfinite(d)) {
+ if (d >= 0) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)) {
+ source = "+Infinity"; //$NON-NLS-1$
+ } else if (formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ source = " Infinity"; //$NON-NLS-1$
+ } else {
+ source = "Infinity"; //$NON-NLS-1$
+ }
+ } else {
+ if (formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ source = "(Infinity)"; //$NON-NLS-1$
+ } else {
+ source = "-Infinity"; //$NON-NLS-1$
+ }
+ }
+ }
+
+ if (null != source) {
+ formatToken.setPrecision(FormatToken.UNSET);
+ formatToken.setFlags(formatToken.getFlags()
+ & (~FormatToken.FLAG_ZERO));
+ source = padding(new StringBuilder(source), 0);
+ }
+ return source;
+ }
+
+ private String transformFromNull() {
+ formatToken.setFlags(formatToken.getFlags()
+ & (~FormatToken.FLAG_ZERO));
+ return padding(new StringBuilder("null"), 0); //$NON-NLS-1$
+ }
+
+ /*
+ * Transforms a BigInteger to a formatted string.
+ */
+ private String transformFromBigInteger() {
+ int startIndex = 0;
+ boolean isNegative = false;
+ StringBuilder result = new StringBuilder();
+ BigInteger bigInt = (BigInteger) arg;
+ char currentConversionType = formatToken.getConversionType();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ || formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ if (!formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException(formatToken
+ .getStrFlags());
+ }
+ }
+
+ // Combination of '+' & ' ' is illegal.
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)
+ && formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ // Combination of '-' & '0' is illegal.
+ if (formatToken.isFlagSet(FormatToken.FLAG_ZERO)
+ && formatToken.isFlagSet(FormatToken.FLAG_MINUS)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+
+ if ('d' != currentConversionType
+ && formatToken.isFlagSet(FormatToken.FLAG_COMMA)) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), currentConversionType);
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)
+ && 'd' == currentConversionType) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), currentConversionType);
+ }
+
+ if (null == bigInt) {
+ return transformFromNull();
+ }
+
+ isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0);
+
+ if ('d' == currentConversionType) {
+ NumberFormat numberFormat = getNumberFormat();
+ boolean readableName = formatToken
+ .isFlagSet(FormatToken.FLAG_COMMA);
+ numberFormat.setGroupingUsed(readableName);
+ result.append(numberFormat.format(bigInt));
+ } else if ('o' == currentConversionType) {
+ // convert BigInteger to a string presentation using radix 8
+ result.append(bigInt.toString(8));
+ } else {
+ // convert BigInteger to a string presentation using radix 16
+ result.append(bigInt.toString(16));
+ }
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)) {
+ startIndex = isNegative ? 1 : 0;
+ if ('o' == currentConversionType) {
+ result.insert(startIndex, "0"); //$NON-NLS-1$
+ startIndex += 1;
+ } else if ('x' == currentConversionType
+ || 'X' == currentConversionType) {
+ result.insert(startIndex, "0x"); //$NON-NLS-1$
+ startIndex += 2;
+ }
+ }
+
+ if (!isNegative) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)) {
+ result.insert(0, '+');
+ startIndex += 1;
+ }
+ if (formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ result.insert(0, ' ');
+ startIndex += 1;
+ }
+ }
+
+ /* pad paddingChar to the output */
+ if (isNegative
+ && formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ result = wrapParentheses(result);
+ return result.toString();
+
+ }
+ if (isNegative && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ startIndex++;
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms a Float,Double or BigDecimal to a formatted string.
+ */
+ private String transformFromFloat() {
+ StringBuilder result = new StringBuilder();
+ int startIndex = 0;
+ char currentConversionType = formatToken.getConversionType();
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS
+ | FormatToken.FLAG_ZERO)) {
+ if (!formatToken.isWidthSet()) {
+ throw new MissingFormatWidthException(formatToken
+ .getStrFlags());
+ }
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)
+ && formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && formatToken.isFlagSet(FormatToken.FLAG_ZERO)) {
+ throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+ }
+
+ if ('e' == Character.toLowerCase(currentConversionType)) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_COMMA)) {
+ throw new FormatFlagsConversionMismatchException(
+ formatToken.getStrFlags(), currentConversionType);
+ }
+ }
+
+ if ('g' == Character.toLowerCase(currentConversionType)) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)) {
+ throw new FormatFlagsConversionMismatchException(
+ formatToken.getStrFlags(), currentConversionType);
+ }
+ }
+
+ if ('a' == Character.toLowerCase(currentConversionType)) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_COMMA)
+ || formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ throw new FormatFlagsConversionMismatchException(
+ formatToken.getStrFlags(), currentConversionType);
+ }
+ }
+
+ if (null == arg) {
+ return transformFromNull();
+ }
+
+ Object arg2 = arg;
+
+ if (!(arg2 instanceof Float || arg2 instanceof Double || arg2 instanceof BigDecimal)) {
+ if (arg2 instanceof Number) {
+ arg2 = Double.valueOf(((Number)arg2).doubleValue());
+ }
+ else {
+ throw new IllegalFormatConversionException(currentConversionType, arg.getClass());
+ }
+ }
+
+ String specialNumberResult = transformFromSpecialNumber();
+ if (null != specialNumberResult) {
+ return specialNumberResult;
+ }
+
+ if ('a' != Character.toLowerCase(currentConversionType)) {
+ formatToken
+ .setPrecision(formatToken.isPrecisionSet() ? formatToken
+ .getPrecision()
+ : FormatToken.DEFAULT_PRECISION);
+ }
+ // output result
+ FloatUtil floatUtil = new FloatUtil(result, formatToken,
+ (DecimalFormat) NumberFormat.getInstance(locale), arg2);
+ floatUtil.transform(formatToken, result);
+
+ formatToken.setPrecision(FormatToken.UNSET);
+
+ if (getDecimalFormatSymbols().getMinusSign() == result.charAt(0)) {
+ if (formatToken.isFlagSet(FormatToken.FLAG_PARENTHESIS)) {
+ result = wrapParentheses(result);
+ return result.toString();
+ }
+ } else {
+ if (formatToken.isFlagSet(FormatToken.FLAG_SPACE)) {
+ result.insert(0, ' ');
+ startIndex++;
+ }
+ if (formatToken.isFlagSet(FormatToken.FLAG_ADD)) {
+ result.insert(0, floatUtil.getAddSign());
+ startIndex++;
+ }
+ }
+
+ char firstChar = result.charAt(0);
+ if (formatToken.isFlagSet(FormatToken.FLAG_ZERO)
+ && (firstChar == floatUtil.getAddSign() || firstChar == floatUtil
+ .getMinusSign())) {
+ startIndex = 1;
+ }
+
+ if ('a' == Character.toLowerCase(currentConversionType)) {
+ startIndex += 2;
+ }
+ return padding(result, startIndex);
+ }
+
+ /*
+ * Transforms a Date to a formatted string.
+ */
+ private String transformFromDateTime() {
+ int startIndex = 0;
+ char currentConversionType = formatToken.getConversionType();
+
+ if (formatToken.isPrecisionSet()) {
+ throw new IllegalFormatPrecisionException(formatToken
+ .getPrecision());
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)) {
+ throw new FormatFlagsConversionMismatchException(formatToken
+ .getStrFlags(), currentConversionType);
+ }
+
+ if (formatToken.isFlagSet(FormatToken.FLAG_MINUS)
+ && FormatToken.UNSET == formatToken.getWidth()) {
+ throw new MissingFormatWidthException("-" //$NON-NLS-1$
+ + currentConversionType);
+ }
+
+ if (null == arg) {
+ return transformFromNull();
+ }
+
+ Calendar calendar;
+ if (arg instanceof Calendar) {
+ calendar = (Calendar) arg;
+ } else {
+ Date date = null;
+ if (arg instanceof Number) {
+ date = new Date(((Number) arg).longValue());
+ } else if (arg instanceof Date) {
+ date = (Date) arg;
+ } else {
+ throw new IllegalFormatConversionException(
+ currentConversionType, arg.getClass());
+ }
+ calendar = Calendar.getInstance(locale);
+ calendar.setTime(date);
+ }
+
+ if (null == dateTimeUtil) {
+ dateTimeUtil = new DateTimeUtil(locale);
+ }
+ StringBuilder result = new StringBuilder();
+ // output result
+ dateTimeUtil.transform(formatToken, calendar, result);
+ return padding(result, startIndex);
+ }
+ }
+
+ private static class FloatUtil {
+ private StringBuilder result;
+
+ private DecimalFormat decimalFormat;
+
+ private FormatToken formatToken;
+
+ private Object argument;
+
+ private char minusSign;
+
+ FloatUtil(StringBuilder result, FormatToken formatToken,
+ DecimalFormat decimalFormat, Object argument) {
+ this.result = result;
+ this.formatToken = formatToken;
+ this.decimalFormat = decimalFormat;
+ this.argument = argument;
+ this.minusSign = decimalFormat.getDecimalFormatSymbols()
+ .getMinusSign();
+ }
+
+ void transform(FormatToken aFormatToken, StringBuilder aResult) {
+ this.result = aResult;
+ this.formatToken = aFormatToken;
+ switch (formatToken.getConversionType()) {
+ case 'e':
+ case 'E': {
+ transform_e();
+ break;
+ }
+ case 'f': {
+ transform_f();
+ break;
+ }
+ case 'g':
+ case 'G': {
+ transform_g();
+ break;
+ }
+ case 'a':
+ case 'A': {
+ transform_a();
+ break;
+ }
+ default: {
+ throw new UnknownFormatConversionException(String
+ .valueOf(formatToken.getConversionType()));
+ }
+ }
+ }
+
+ char getMinusSign() {
+ return minusSign;
+ }
+
+ char getAddSign() {
+ return '+';
+ }
+
+ void transform_e() {
+ StringBuilder pattern = new StringBuilder();
+ pattern.append('0');
+ if (formatToken.getPrecision() > 0) {
+ pattern.append('.');
+ char[] zeros = new char[formatToken.getPrecision()];
+ Arrays.fill(zeros, '0');
+ pattern.append(zeros);
+ }
+ pattern.append('E');
+ pattern.append("+00"); //$NON-NLS-1$
+ decimalFormat.applyPattern(pattern.toString());
+ String formattedString = decimalFormat.format(argument);
+ result.append(formattedString.replace('E', 'e'));
+
+ // if the flag is sharp and decimal seperator is always given
+ // out.
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)
+ && 0 == formatToken.getPrecision()) {
+ int indexOfE = result.indexOf("e"); //$NON-NLS-1$
+ char dot = decimalFormat.getDecimalFormatSymbols()
+ .getDecimalSeparator();
+ result.insert(indexOfE, dot);
+ }
+ }
+
+ void transform_g() {
+ int precision = formatToken.getPrecision();
+ precision = (0 == precision ? 1 : precision);
+ formatToken.setPrecision(precision);
+
+ if (0.0 == ((Number) argument).doubleValue()) {
+ precision--;
+ formatToken.setPrecision(precision);
+ transform_f();
+ return;
+ }
+
+ boolean requireScientificRepresentation = true;
+ double d = ((Number) argument).doubleValue();
+ d = Math.abs(d);
+ if (Double.isInfinite(d)) {
+ precision = formatToken.getPrecision();
+ precision--;
+ formatToken.setPrecision(precision);
+ transform_e();
+ return;
+ }
+ BigDecimal b = new BigDecimal(d, new MathContext(precision));
+ d = b.doubleValue();
+ long l = b.longValue();
+
+ if (d >= 1 && d < Math.pow(10, precision)) {
+ if (l < Math.pow(10, precision)) {
+ requireScientificRepresentation = false;
+ precision -= String.valueOf(l).length();
+ precision = precision < 0 ? 0 : precision;
+ l = Math.round(d * Math.pow(10, precision + 1));
+ if (String.valueOf(l).length() <= formatToken
+ .getPrecision()) {
+ precision++;
+ }
+ formatToken.setPrecision(precision);
+ }
+
+ } else {
+ l = b.movePointRight(4).longValue();
+ if (d >= Math.pow(10, -4) && d < 1) {
+ requireScientificRepresentation = false;
+ precision += 4 - String.valueOf(l).length();
+ l = b.movePointRight(precision + 1).longValue();
+ if (String.valueOf(l).length() <= formatToken
+ .getPrecision()) {
+ precision++;
+ }
+ l = b.movePointRight(precision).longValue();
+ if (l >= Math.pow(10, precision - 4)) {
+ formatToken.setPrecision(precision);
+ }
+ }
+ }
+ if (requireScientificRepresentation) {
+ precision = formatToken.getPrecision();
+ precision--;
+ formatToken.setPrecision(precision);
+ transform_e();
+ } else {
+ transform_f();
+ }
+
+ }
+
+ void transform_f() {
+ StringBuilder pattern = new StringBuilder();
+ if (formatToken.isFlagSet(FormatToken.FLAG_COMMA)) {
+ pattern.append(',');
+ int groupingSize = decimalFormat.getGroupingSize();
+ if (groupingSize > 1) {
+ char[] sharps = new char[groupingSize - 1];
+ Arrays.fill(sharps, '#');
+ pattern.append(sharps);
+ }
+ }
+
+ pattern.append(0);
+
+ if (formatToken.getPrecision() > 0) {
+ pattern.append('.');
+ char[] zeros = new char[formatToken.getPrecision()];
+ Arrays.fill(zeros, '0');
+ pattern.append(zeros);
+ }
+ decimalFormat.applyPattern(pattern.toString());
+ result.append(decimalFormat.format(argument));
+ // if the flag is sharp and decimal seperator is always given
+ // out.
+ if (formatToken.isFlagSet(FormatToken.FLAG_SHARP)
+ && 0 == formatToken.getPrecision()) {
+ char dot = decimalFormat.getDecimalFormatSymbols()
+ .getDecimalSeparator();
+ result.append(dot);
+ }
+
+ }
+
+ void transform_a() {
+ char currentConversionType = formatToken.getConversionType();
+
+ if (argument instanceof Float) {
+ Float F = (Float) argument;
+ result.append(Float.toHexString(F.floatValue()));
+
+ } else if (argument instanceof Double) {
+ Double D = (Double) argument;
+ result.append(Double.toHexString(D.doubleValue()));
+ } else {
+ // BigInteger is not supported.
+ throw new IllegalFormatConversionException(
+ currentConversionType, argument.getClass());
+ }
+
+ if (!formatToken.isPrecisionSet()) {
+ return;
+ }
+
+ int precision = formatToken.getPrecision();
+ precision = (0 == precision ? 1 : precision);
+ int indexOfFirstFracitoanlDigit = result.indexOf(".") + 1; //$NON-NLS-1$
+ int indexOfP = result.indexOf("p"); //$NON-NLS-1$
+ int fractionalLength = indexOfP - indexOfFirstFracitoanlDigit;
+
+ if (fractionalLength == precision) {
+ return;
+ }
+
+ if (fractionalLength < precision) {
+ char zeros[] = new char[precision - fractionalLength];
+ Arrays.fill(zeros, '0');
+ result.insert(indexOfP, zeros);
+ return;
+ }
+ result.delete(indexOfFirstFracitoanlDigit + precision, indexOfP);
+ }
+ }
+
+ private static class DateTimeUtil {
+ private Calendar calendar;
+
+ private Locale locale;
+
+ private StringBuilder result;
+
+ private DateFormatSymbols dateFormatSymbols;
+
+ DateTimeUtil(Locale locale) {
+ this.locale = locale;
+ }
+
+ void transform(FormatToken formatToken, Calendar aCalendar,
+ StringBuilder aResult) {
+ this.result = aResult;
+ this.calendar = aCalendar;
+ char suffix = formatToken.getDateSuffix();
+
+ switch (suffix) {
+ case 'H': {
+ transform_H();
+ break;
+ }
+ case 'I': {
+ transform_I();
+ break;
+ }
+ case 'M': {
+ transform_M();
+ break;
+ }
+ case 'S': {
+ transform_S();
+ break;
+ }
+ case 'L': {
+ transform_L();
+ break;
+ }
+ case 'N': {
+ transform_N();
+ break;
+ }
+ case 'k': {
+ transform_k();
+ break;
+ }
+ case 'l': {
+ transform_l();
+ break;
+ }
+ case 'p': {
+ transform_p(true);
+ break;
+ }
+ case 's': {
+ transform_s();
+ break;
+ }
+ case 'z': {
+ transform_z();
+ break;
+ }
+ case 'Z': {
+ transform_Z();
+ break;
+ }
+ case 'Q': {
+ transform_Q();
+ break;
+ }
+ case 'B': {
+ transform_B();
+ break;
+ }
+ case 'b':
+ case 'h': {
+ transform_b();
+ break;
+ }
+ case 'A': {
+ transform_A();
+ break;
+ }
+ case 'a': {
+ transform_a();
+ break;
+ }
+ case 'C': {
+ transform_C();
+ break;
+ }
+ case 'Y': {
+ transform_Y();
+ break;
+ }
+ case 'y': {
+ transform_y();
+ break;
+ }
+ case 'j': {
+ transform_j();
+ break;
+ }
+ case 'm': {
+ transform_m();
+ break;
+ }
+ case 'd': {
+ transform_d();
+ break;
+ }
+ case 'e': {
+ transform_e();
+ break;
+ }
+ case 'R': {
+ transform_R();
+ break;
+ }
+
+ case 'T': {
+ transform_T();
+ break;
+ }
+ case 'r': {
+ transform_r();
+ break;
+ }
+ case 'D': {
+ transform_D();
+ break;
+ }
+ case 'F': {
+ transform_F();
+ break;
+ }
+ case 'c': {
+ transform_c();
+ break;
+ }
+ default: {
+ throw new UnknownFormatConversionException(String
+ .valueOf(formatToken.getConversionType())
+ + formatToken.getDateSuffix());
+ }
+ }
+ }
+
+ private void transform_e() {
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ result.append(day);
+ }
+
+ private void transform_d() {
+ int day = calendar.get(Calendar.DAY_OF_MONTH);
+ result.append(paddingZeros(day, 2));
+ }
+
+ private void transform_m() {
+ int month = calendar.get(Calendar.MONTH);
+ // The returned month starts from zero, which needs to be
+ // incremented by 1.
+ month++;
+ result.append(paddingZeros(month, 2));
+ }
+
+ private void transform_j() {
+ int day = calendar.get(Calendar.DAY_OF_YEAR);
+ result.append(paddingZeros(day, 3));
+ }
+
+ private void transform_y() {
+ int year = calendar.get(Calendar.YEAR);
+ year %= 100;
+ result.append(paddingZeros(year, 2));
+ }
+
+ private void transform_Y() {
+ int year = calendar.get(Calendar.YEAR);
+ result.append(paddingZeros(year, 4));
+ }
+
+ private void transform_C() {
+ int year = calendar.get(Calendar.YEAR);
+ year /= 100;
+ result.append(paddingZeros(year, 2));
+ }
+
+ private void transform_a() {
+ int day = calendar.get(Calendar.DAY_OF_WEEK);
+ result.append(getDateFormatSymbols().getShortWeekdays()[day]);
+ }
+
+ private void transform_A() {
+ int day = calendar.get(Calendar.DAY_OF_WEEK);
+ result.append(getDateFormatSymbols().getWeekdays()[day]);
+ }
+
+ private void transform_b() {
+ int month = calendar.get(Calendar.MONTH);
+ result.append(getDateFormatSymbols().getShortMonths()[month]);
+ }
+
+ private void transform_B() {
+ int month = calendar.get(Calendar.MONTH);
+ result.append(getDateFormatSymbols().getMonths()[month]);
+ }
+
+ private void transform_Q() {
+ long milliSeconds = calendar.getTimeInMillis();
+ result.append(milliSeconds);
+ }
+
+ private void transform_s() {
+ long milliSeconds = calendar.getTimeInMillis();
+ milliSeconds /= 1000;
+ result.append(milliSeconds);
+ }
+
+ private void transform_Z() {
+ TimeZone timeZone = calendar.getTimeZone();
+ result.append(timeZone
+ .getDisplayName(
+ timeZone.inDaylightTime(calendar.getTime()),
+ TimeZone.SHORT, locale));
+ }
+
+ private void transform_z() {
+ int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
+ zoneOffset /= 3600000;
+ zoneOffset *= 100;
+ if (zoneOffset >= 0) {
+ result.append('+');
+ }
+ result.append(paddingZeros(zoneOffset, 4));
+ }
+
+ private void transform_p(boolean isLowerCase) {
+ int i = calendar.get(Calendar.AM_PM);
+ String s = getDateFormatSymbols().getAmPmStrings()[i];
+ if (isLowerCase) {
+ s = s.toLowerCase(locale);
+ }
+ result.append(s);
+ }
+
+ private void transform_N() {
+ // TODO System.nanoTime();
+ long nanosecond = calendar.get(Calendar.MILLISECOND) * 1000000L;
+ result.append(paddingZeros(nanosecond, 9));
+ }
+
+ private void transform_L() {
+ int millisecond = calendar.get(Calendar.MILLISECOND);
+ result.append(paddingZeros(millisecond, 3));
+ }
+
+ private void transform_S() {
+ int second = calendar.get(Calendar.SECOND);
+ result.append(paddingZeros(second, 2));
+ }
+
+ private void transform_M() {
+ int minute = calendar.get(Calendar.MINUTE);
+ result.append(paddingZeros(minute, 2));
+ }
+
+ private void transform_l() {
+ int hour = calendar.get(Calendar.HOUR);
+ if (0 == hour) {
+ hour = 12;
+ }
+ result.append(hour);
+ }
+
+ private void transform_k() {
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ result.append(hour);
+ }
+
+ private void transform_I() {
+ int hour = calendar.get(Calendar.HOUR);
+ if (0 == hour) {
+ hour = 12;
+ }
+ result.append(paddingZeros(hour, 2));
+ }
+
+ private void transform_H() {
+ int hour = calendar.get(Calendar.HOUR_OF_DAY);
+ result.append(paddingZeros(hour, 2));
+ }
+
+ private void transform_R() {
+ transform_H();
+ result.append(':');
+ transform_M();
+ }
+
+ private void transform_T() {
+ transform_H();
+ result.append(':');
+ transform_M();
+ result.append(':');
+ transform_S();
+ }
+
+ private void transform_r() {
+ transform_I();
+ result.append(':');
+ transform_M();
+ result.append(':');
+ transform_S();
+ result.append(' ');
+ transform_p(false);
+ }
+
+ private void transform_D() {
+ transform_m();
+ result.append('/');
+ transform_d();
+ result.append('/');
+ transform_y();
+ }
+
+ private void transform_F() {
+ transform_Y();
+ result.append('-');
+ transform_m();
+ result.append('-');
+ transform_d();
+ }
+
+ private void transform_c() {
+ transform_a();
+ result.append(' ');
+ transform_b();
+ result.append(' ');
+ transform_d();
+ result.append(' ');
+ transform_T();
+ result.append(' ');
+ transform_Z();
+ result.append(' ');
+ transform_Y();
+ }
+
+ private static String paddingZeros(long number, int length) {
+ int len = length;
+ StringBuilder result = new StringBuilder();
+ result.append(number);
+ int startIndex = 0;
+ if (number < 0) {
+ len++;
+ startIndex = 1;
+ }
+ len -= result.length();
+ if (len > 0) {
+ char[] zeros = new char[len];
+ Arrays.fill(zeros, '0');
+ result.insert(startIndex, zeros);
+ }
+ return result.toString();
+ }
+
+ private DateFormatSymbols getDateFormatSymbols() {
+ if (null == dateFormatSymbols) {
+ dateFormatSymbols = new DateFormatSymbols(locale);
+ }
+ return dateFormatSymbols;
+ }
+ }
+
+ private static class ParserStateMachine {
+
+ private static final char EOS = (char) -1;
+
+ private static final int EXIT_STATE = 0;
+
+ private static final int ENTRY_STATE = 1;
+
+ private static final int START_CONVERSION_STATE = 2;
+
+ private static final int FLAGS_STATE = 3;
+
+ private static final int WIDTH_STATE = 4;
+
+ private static final int PRECISION_STATE = 5;
+
+ private static final int CONVERSION_TYPE_STATE = 6;
+
+ private static final int SUFFIX_STATE = 7;
+
+ private FormatToken token;
+
+ private int state = ENTRY_STATE;
+
+ private char currentChar = 0;
+
+ private CharBuffer format = null;
+
+ ParserStateMachine(CharBuffer format) {
+ this.format = format;
+ }
+
+ void reset() {
+ this.currentChar = (char) FormatToken.UNSET;
+ this.state = ENTRY_STATE;
+ this.token = null;
+ }
+
+ /*
+ * Gets the information about the current format token. Information is
+ * recorded in the FormatToken returned and the position of the stream
+ * for the format string will be advanced till the next format token.
+ */
+ FormatToken getNextFormatToken() {
+ token = new FormatToken();
+ token.setFormatStringStartIndex(format.position());
+
+ // FINITE AUTOMATIC MACHINE
+ while (true) {
+
+ if (ParserStateMachine.EXIT_STATE != state) {
+ // exit state does not need to get next char
+ currentChar = getNextFormatChar();
+ if (EOS == currentChar
+ && ParserStateMachine.ENTRY_STATE != state) {
+ throw new UnknownFormatConversionException(
+ getFormatString());
+ }
+ }
+
+ switch (state) {
+ // exit state
+ case ParserStateMachine.EXIT_STATE: {
+ process_EXIT_STATE();
+ return token;
+ }
+ // plain text state, not yet applied converter
+ case ParserStateMachine.ENTRY_STATE: {
+ process_ENTRY_STATE();
+ break;
+ }
+ // begins converted string
+ case ParserStateMachine.START_CONVERSION_STATE: {
+ process_START_CONVERSION_STATE();
+ break;
+ }
+ case ParserStateMachine.FLAGS_STATE: {
+ process_FlAGS_STATE();
+ break;
+ }
+ case ParserStateMachine.WIDTH_STATE: {
+ process_WIDTH_STATE();
+ break;
+ }
+ case ParserStateMachine.PRECISION_STATE: {
+ process_PRECISION_STATE();
+ break;
+ }
+ case ParserStateMachine.CONVERSION_TYPE_STATE: {
+ process_CONVERSION_TYPE_STATE();
+ break;
+ }
+ case ParserStateMachine.SUFFIX_STATE: {
+ process_SUFFIX_STATE();
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Gets next char from the format string.
+ */
+ private char getNextFormatChar() {
+ if (format.hasRemaining()) {
+ return format.get();
+ }
+ return EOS;
+ }
+
+ private String getFormatString() {
+ int end = format.position();
+ format.rewind();
+ String formatString = format.subSequence(
+ token.getFormatStringStartIndex(), end).toString();
+ format.position(end);
+ return formatString;
+ }
+
+ private void process_ENTRY_STATE() {
+ if (EOS == currentChar) {
+ state = ParserStateMachine.EXIT_STATE;
+ } else if ('%' == currentChar) {
+ // change to conversion type state
+ state = START_CONVERSION_STATE;
+ }
+ // else remains in ENTRY_STATE
+ }
+
+ private void process_START_CONVERSION_STATE() {
+ if (Character.isDigit(currentChar)) {
+ int position = format.position() - 1;
+ int number = parseInt(format);
+ char nextChar = 0;
+ if (format.hasRemaining()) {
+ nextChar = format.get();
+ }
+ if ('$' == nextChar) {
+ // the digital sequence stands for the argument
+ // index.
+ int argIndex = number;
+ // k$ stands for the argument whose index is k-1 except that
+ // 0$ and 1$ both stands for the first element.
+ if (argIndex > 0) {
+ token.setArgIndex(argIndex - 1);
+ } else if (argIndex == FormatToken.UNSET) {
+ throw new MissingFormatArgumentException(
+ getFormatString());
+ }
+ state = FLAGS_STATE;
+ } else {
+ // the digital zero stands for one format flag.
+ if ('0' == currentChar) {
+ state = FLAGS_STATE;
+ format.position(position);
+ } else {
+ // the digital sequence stands for the width.
+ state = WIDTH_STATE;
+ // do not get the next char.
+ format.position(format.position() - 1);
+ token.setWidth(number);
+ }
+ }
+ currentChar = nextChar;
+ } else if ('<' == currentChar) {
+ state = FLAGS_STATE;
+ token.setArgIndex(FormatToken.LAST_ARGUMENT_INDEX);
+ } else {
+ state = FLAGS_STATE;
+ // do not get the next char.
+ format.position(format.position() - 1);
+ }
+
+ }
+
+ private void process_FlAGS_STATE() {
+ if (token.setFlag(currentChar)) {
+ // remains in FLAGS_STATE
+ } else if (Character.isDigit(currentChar)) {
+ token.setWidth(parseInt(format));
+ state = WIDTH_STATE;
+ } else if ('.' == currentChar) {
+ state = PRECISION_STATE;
+ } else {
+ state = CONVERSION_TYPE_STATE;
+ // do not get the next char.
+ format.position(format.position() - 1);
+ }
+ }
+
+ private void process_WIDTH_STATE() {
+ if ('.' == currentChar) {
+ state = PRECISION_STATE;
+ } else {
+ state = CONVERSION_TYPE_STATE;
+ // do not get the next char.
+ format.position(format.position() - 1);
+ }
+ }
+
+ private void process_PRECISION_STATE() {
+ if (Character.isDigit(currentChar)) {
+ token.setPrecision(parseInt(format));
+ } else {
+ // the precision is required but not given by the
+ // format string.
+ throw new UnknownFormatConversionException(getFormatString());
+ }
+ state = CONVERSION_TYPE_STATE;
+ }
+
+ private void process_CONVERSION_TYPE_STATE() {
+ token.setConversionType(currentChar);
+ if ('t' == currentChar || 'T' == currentChar) {
+ state = SUFFIX_STATE;
+ } else {
+ state = EXIT_STATE;
+ }
+
+ }
+
+ private void process_SUFFIX_STATE() {
+ token.setDateSuffix(currentChar);
+ state = EXIT_STATE;
+ }
+
+ private void process_EXIT_STATE() {
+ token.setPlainText(getFormatString());
+ }
+
+ /*
+ * Parses integer value from the given buffer
+ */
+ private int parseInt(CharBuffer buffer) {
+ int start = buffer.position() - 1;
+ int end = buffer.limit();
+ while (buffer.hasRemaining()) {
+ if (!Character.isDigit(buffer.get())) {
+ end = buffer.position() - 1;
+ break;
+ }
+ }
+ buffer.position(0);
+ String intStr = buffer.subSequence(start, end).toString();
+ buffer.position(end);
+ try {
+ return Integer.parseInt(intStr);
+ } catch (NumberFormatException e) {
+ return FormatToken.UNSET;
+ }
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.common/util/LimitedSizeMapping.java b/infrastructure/net.appjet.common/util/LimitedSizeMapping.java
new file mode 100644
index 0000000..331baca
--- /dev/null
+++ b/infrastructure/net.appjet.common/util/LimitedSizeMapping.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.common.util;
+
+public class LimitedSizeMapping<K,V> extends ExpiringMapping<K,V> {
+
+ public LimitedSizeMapping(final int maxSize) {
+ super(new ExpiryPolicy() {
+ public boolean hasExpired(long timeStamp, long now, int rank) {
+ return rank > maxSize;
+ }
+ });
+ }
+}
diff --git a/infrastructure/net.appjet.oui/ConfigParam.java b/infrastructure/net.appjet.oui/ConfigParam.java
new file mode 100644
index 0000000..5029f28
--- /dev/null
+++ b/infrastructure/net.appjet.oui/ConfigParam.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ConfigParam {
+ public String value(); // a description of the config parameter.
+ public String argName() default "";
+} \ No newline at end of file
diff --git a/infrastructure/net.appjet.oui/FastJSON.scala b/infrastructure/net.appjet.oui/FastJSON.scala
new file mode 100644
index 0000000..60cfc48
--- /dev/null
+++ b/infrastructure/net.appjet.oui/FastJSON.scala
@@ -0,0 +1,171 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import org.mozilla.javascript.{Context,Scriptable,ScriptableObject};
+import org.json.{JSONStringer,JSONObject,JSONArray};
+
+object FastJSON {
+ def stringify(rhinoObj: Scriptable): String = {
+ return FastJSONStringify.stringify(rhinoObj);
+ }
+ def parse(exctx: ExecutionContext, source: String): Scriptable = {
+ return (new FastJSONParser(exctx)).parse(source);
+ }
+}
+
+//----------------------------------------------------------------
+// FastJSONStringify
+//----------------------------------------------------------------
+object FastJSONStringify {
+
+ def stringify(rhinoObj: Scriptable): String = {
+ val stringer = new JSONStringer();
+ stringerizeScriptable(stringer, rhinoObj);
+ return stringer.toString();
+ }
+
+ private def stringerize(s: JSONStringer, v: Object) {
+ if (v == Context.getUndefinedValue) {
+ return;
+ }
+ v match {
+ case (o:Scriptable) => stringerizeScriptable(s, o);
+ case (o:Number) => {
+ val d = o.doubleValue;
+ if (d.toLong.toDouble == d) {
+ s.value(d.toLong);
+ }
+ else {
+ s.value(o);
+ }
+ }
+ case o => s.value(o);
+ }
+ }
+
+ private def stringerizeScriptable(stringer: JSONStringer, rhinoObj: Scriptable) {
+ if (rhinoObj.getClassName() == "Array") {
+ stringerizeArray(stringer, rhinoObj);
+ } else {
+ stringerizeObj(stringer, rhinoObj);
+ }
+ }
+
+ private def stringerizeObj(stringer: JSONStringer, rhinoObj: Scriptable) {
+ stringer.`object`();
+
+ for (id <- rhinoObj.getIds()) {
+ val k = id.toString();
+ var v:Object = null;
+ id match {
+ case (s:String) => { v = rhinoObj.get(s, rhinoObj); }
+ case (n:Number) => { v = rhinoObj.get(n.intValue, rhinoObj); }
+ case _ => {}
+ }
+
+ if (v != null && v != Scriptable.NOT_FOUND && v != Context.getUndefinedValue) {
+ stringer.key(k);
+ stringerize(stringer, v);
+ }
+ }
+
+ stringer.endObject();
+ }
+
+ private def stringerizeArray(stringer: JSONStringer, rhinoArray: Scriptable) {
+ stringer.`array`();
+
+ val ids:Array[Object] = rhinoArray.getIds();
+ var x = 0;
+ for (i <- 0 until ids.length) {
+ // we ignore string keys on js arrays. crockford's "offical"
+ // json library does this as well.
+ if (ids(i).isInstanceOf[Number]) {
+ val id:Int = ids(i).asInstanceOf[Number].intValue;
+ while (x < id) {
+ stringer.value(null);
+ x += 1;
+ }
+ val v:Object = rhinoArray.get(id, rhinoArray);
+ stringerize(stringer, v);
+ x += 1;
+ }
+ }
+
+ stringer.endArray();
+ }
+}
+
+//----------------------------------------------------------------
+// FastJSONParse
+//----------------------------------------------------------------
+class FastJSONParser(val ctx:ExecutionContext) {
+
+ def parse(source: String): Scriptable = {
+ if (source(0) == '[') {
+ jsonToRhino(new JSONArray(source)).asInstanceOf[Scriptable];
+ } else {
+ jsonToRhino(new JSONObject(source)).asInstanceOf[Scriptable];
+ }
+ }
+
+ private def newObj(): Scriptable = {
+ Context.getCurrentContext().newObject(ctx.runner.globalScope);
+ }
+
+ private def newArray(): Scriptable = {
+ Context.getCurrentContext().newArray(ctx.runner.globalScope, 0);
+ }
+
+ private def jsonToRhino(json: Object): Object = {
+ json match {
+ case (o:JSONArray) => jsonArrayToRhino(o);
+ case (o:JSONObject) => jsonObjectToRhino(o);
+ case o if (o == JSONObject.NULL) => null;
+ case o => o;
+ }
+ }
+
+ private def jsonArrayToRhino(json: JSONArray): Scriptable = {
+ val o:Scriptable = newArray();
+ for (i <- 0 until json.length()) {
+ o.put(i, o, jsonToRhino(json.get(i)));
+ }
+ return o;
+ }
+
+ private def jsonObjectToRhino(json: JSONObject): Scriptable = {
+ val o:Scriptable = newObj();
+ val names:Array[String] = JSONObject.getNames(json);
+ if (names != null) {
+ for (n <- names) {
+ val i = try { Some(n.toInt); } catch { case (e:NumberFormatException) => None };
+ if (i.isDefined) {
+ o.put(i.get, o, jsonToRhino(json.get(n)));
+ }
+ else {
+ o.put(n, o, jsonToRhino(json.get(n)));
+ }
+ }
+ }
+ return o;
+ }
+
+}
+
+
diff --git a/infrastructure/net.appjet.oui/GeneratedConfigParam.java b/infrastructure/net.appjet.oui/GeneratedConfigParam.java
new file mode 100644
index 0000000..0986015
--- /dev/null
+++ b/infrastructure/net.appjet.oui/GeneratedConfigParam.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface GeneratedConfigParam {
+} \ No newline at end of file
diff --git a/infrastructure/net.appjet.oui/config.scala b/infrastructure/net.appjet.oui/config.scala
new file mode 100644
index 0000000..46e73cf
--- /dev/null
+++ b/infrastructure/net.appjet.oui/config.scala
@@ -0,0 +1,240 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import scala.collection.mutable.HashMap;
+import java.util.regex.Pattern;
+import java.net.URL;
+import org.mortbay.jetty.servlet.Context;
+import org.mozilla.javascript.{Scriptable, ScriptableObject, Context => JSContext};
+
+import net.appjet.common.util.BetterFile;
+
+
+object config {
+ val values = new HashMap[String, String];
+ def stringOrElse(name: String, default: String): String = {
+ val v = values.getOrElse(name, default);
+ if (v != null) {
+ val m = propertiesPattern.matcher(v);
+ val sb = new StringBuffer();
+ while (m.find()) {
+ m.appendReplacement(sb, getClass.getDeclaredMethod(m.group(1), Array[Class[_]](): _*).invoke(this, Array[Class[_]](): _*).asInstanceOf[String]);
+ }
+ m.appendTail(sb);
+ sb.toString();
+ } else {
+ null;
+ }
+ }
+ def boolOrElse(name: String, default: Boolean) = values.get(name).map(_.equals("true")).getOrElse(default);
+ def intOrElse(name: String, default: Int) = values.get(name).map(Integer.parseInt(_)).getOrElse(default);
+ def longOrElse(name: String, default: Long) = values.get(name).map(java.lang.Long.parseLong(_)).getOrElse(default);
+
+ @ConfigParam("Read configuration options from this file before processing any command-line flags.")
+ { val argName = "file" }
+ def configFile = stringOrElse("configFile", null);
+
+ // configuation parameters
+ var specialDebug = false;
+
+ @ConfigParam("Enable additional logging output.")
+ def verbose = boolOrElse("verbose", false);
+
+ @ConfigParam("Activate \"developer\" mode.")
+ def devMode = boolOrElse("devMode", false);
+
+ @ConfigParam("Activate \"profiling\" mode.")
+ def profile = boolOrElse("profile", false);
+
+ @ConfigParam("Directory to use for storing appjet support files, logs, etc. This directory will be created if it does not exist and must be writeable by the user who runs appjet.jar. Defaults to current working directory.")
+ { val argName = "directory" }
+ def appjetHome = stringOrElse("appjetHome", "appjet");
+
+ @ConfigParam("Directory to use for storing built-in database (Apache Derby) files. Will be created if it doesn't exist. Defaults to [appjetHome]/db")
+ def derbyHome = stringOrElse("derbyHome", "[appjetHome]/derbydb");
+
+ @ConfigParam("Directory to use for storing appserver logs. Defaults to [appjetHome]/log/appserver")
+ { val argName = "directory" }
+ def logDir = stringOrElse("logDir", "[appjetHome]/log/appserver");
+
+ @ConfigParam("Optional alternative directory to load built-in libraries from. Used by AppJet platform hackers to develop and debug built-in libraries. Default: use built-in libraries.")
+ { val argName = "directory" }
+ def ajstdlibHome = stringOrElse("ajstdlibHome", null);
+
+ @ConfigParam("Optional directory to specify as the \"app home\".")
+ { val argName = "directory" }
+ def appHome = stringOrElse("appHome", "");
+
+
+ @ConfigParam("Search path for modules imported via \"import\". Defaults to current working directory.")
+ { val argName = "dir1:dir2:..." }
+ def modulePath = stringOrElse("modulePath", null);
+ def moduleRoots =
+ Array.concat(Array("."), if (modulePath != null) modulePath.split(":") else Array[String](), Array(ajstdlibHome));
+
+ @ConfigParam("Where to read the static files from on the local filesystem. Don't specify this to read static files from the classpath/JAR.")
+ { val argName = "directory" }
+ def useVirtualFileRoot = stringOrElse("useVirtualFileRoot", null);
+
+ @ConfigParam("Directory to use for storing the temporary sessions file on shutdown. Will be created if it does not exist.")
+ { val argName = "directory" }
+ def sessionStoreDir = stringOrElse("sessionStoreDir", "[appjetHome]/sessions");
+
+ // performance tuning
+ @ConfigParam("Create this many runners before opening up the server.")
+ { val argName = "count" }
+ def preloadRunners = intOrElse("preloadRunners", 0);
+
+ @ConfigParam("Have this many JDBC connections available in the pool.")
+ { val argName = "count" }
+ def jdbcPoolSize = intOrElse("jdbcPoolSize", 10);
+ @ConfigParam("Max count of worker threads.")
+ { val argName = "num" }
+ def maxThreads = intOrElse("maxThreads", 250);
+
+ // specifying ports and such
+ def extractHostAndPort(s: String): (String, Int) =
+ if (s.indexOf(":") >= 0)
+ (s.split(":")(0), Integer.parseInt(s.split(":")(1)))
+ else
+ ("", Integer.parseInt(s))
+
+ @ConfigParam("[host:]port on which to serve the app. Default: 8080.")
+ { val argName = "[host:]port" }
+ def listen = stringOrElse("listen", "8080");
+ @GeneratedConfigParam
+ def listenHost = extractHostAndPort(listen)._1;
+ @GeneratedConfigParam
+ def listenPort = extractHostAndPort(listen)._2;
+
+ @ConfigParam("[host:]port on which to serve the app using SSL. Default: none.")
+ { val argName = "[host:]port" }
+ def listenSecure = stringOrElse("listenSecure", "0");
+ @GeneratedConfigParam
+ def listenSecureHost = extractHostAndPort(listenSecure)._1;
+ @GeneratedConfigParam
+ def listenSecurePort = extractHostAndPort(listenSecure)._2;
+
+ @ConfigParam("[host:]port:port on which to listen for monitoring. Default: none.")
+ { val argName = "[host:]primaryPort:secondaryPort" }
+ def listenMonitoring = stringOrElse("listenMonitoring", "0:0");
+ def extractHostAndPortPort(s: String): (String, Int, Int) = {
+ val spl = s.split(":", 3);
+ if (spl.length > 2)
+ (spl(0), Integer.parseInt(spl(1)), Integer.parseInt(spl(2)))
+ else
+ ("", Integer.parseInt(spl(0)), Integer.parseInt(spl(1)));
+ }
+ @GeneratedConfigParam
+ def listenMonitoringHost = extractHostAndPortPort(listenMonitoring)._1;
+ @GeneratedConfigParam
+ def listenMonitoringPrimaryPort = extractHostAndPortPort(listenMonitoring)._2;
+ @GeneratedConfigParam
+ def listenMonitoringSecondaryPort = extractHostAndPortPort(listenMonitoring)._3;
+
+ @ConfigParam("[host:]port on which to listen for RPCs (via SARS). Default: none.")
+ { val argName = "[host:]port" }
+ def listenSars = stringOrElse("listenSars", "0");
+ @GeneratedConfigParam
+ def listenSarsHost = extractHostAndPort(listenSars)._1;
+ @GeneratedConfigParam
+ def listenSarsPort = extractHostAndPort(listenSars)._2;
+
+ // Licensing
+ @ConfigParam("Private key for generating license keys.")
+ { val argName = "pathToKey" }
+ def licenseGeneratorKey = stringOrElse("licenseGeneratorKey", null);
+
+ // SARS
+ @ConfigParam("SARS auth key. Default: \"appjet\".")
+ { val argName = "authkey" }
+ def sarsAuthKey = stringOrElse("sarsAuthKey", "appjet");
+
+ // SSL
+ @ConfigParam("[SSL] Keystore location. Default: appjetHome/sslkeystore.")
+ { val argName = "keystore" }
+ def sslKeyStore = stringOrElse("sslKeyStore", appjetHome+"/sslkeystore");
+ def sslKeyStore_isSet = values.contains("sslKeyStore");
+ @ConfigParam("[SSL] Key password. Default: same as store password.")
+ { val argName = "password" }
+ def sslKeyPassword = stringOrElse("sslKeyPassword", "[sslStorePassword]");
+ @ConfigParam("[SSL] Store password. Default: 'appjet'.")
+ { val argName = "password" }
+ def sslStorePassword = stringOrElse("sslStorePassword", "appjet");
+
+ // email
+ @ConfigParam("host:port of mail server to use for sending email. Default: localhost:25.")
+ { val argName = "host:port" }
+ def smtpServer = stringOrElse("smtpServer", "localhost:25");
+ def smtpServerHost = extractHostAndPort(smtpServer)._1;
+ def smtpServerPort = extractHostAndPort(smtpServer)._2;
+ @ConfigParam("username for authentication to mail server. Default: no authentication.")
+ { val argName = "username" }
+ def smtpUser = stringOrElse("smtpUser", "");
+ @ConfigParam("password for authentication to mail server. Default: no authentication.")
+ { val argName = "password" }
+ def smtpPass = stringOrElse("smtpPass", "");
+
+ // comet
+ @ConfigParam("prefix for all comet requests. Required to use Comet system.")
+ { val argName = "path" }
+ def transportPrefix = stringOrElse("transportPrefix", null);
+ @ConfigParam("Use a subdomain for all comet requests.")
+ def transportUseWildcardSubdomains = boolOrElse("transportUseWildcardSubdomains", false);
+ @ConfigParam("Don't use short polling, ever.")
+ def disableShortPolling = boolOrElse("disableShortPolling", false);
+
+ // helpers
+ val allProperties =
+ for (m <- getClass.getDeclaredMethods() if (m.getAnnotation(classOf[ConfigParam]) != null || m.getAnnotation(classOf[GeneratedConfigParam]) != null))
+ yield m;
+ val configParamNames =
+ for (m <- allProperties if m.getAnnotation(classOf[ConfigParam]) != null) yield m.getName
+ lazy val allPropertiesMap =
+ Map((for (m <- allProperties) yield ((m.getName, () => m.invoke(this)))): _*);
+ val propertiesPattern = Pattern.compile("\\[("+allProperties.map(x => "(?:"+x.getName()+")").mkString("|")+")\\]");
+
+ override def toString() =
+ (allProperties.map(m => m.getName()+" -> "+m.invoke(this)) ++
+ values.keys.toList.filter(! allPropertiesMap.contains(_)).map(k => k+" -> "+values(k))).mkString("[Config ", ", ", "]");
+ def print {
+ for (m <- allProperties) {
+ println(m.getName() + " -> " + m.invoke(this));
+ }
+ for ((k, v) <- values if (! allPropertiesMap.contains(k))) {
+ println(k + " -> " + v);
+ }
+ }
+ def configObject(globalScope: Scriptable) =
+ new ScriptableAdapter {
+ val keys = (Set.empty[Object] ++ allProperties.map(m => m.getName) ++ values.keySet).toList.toArray;
+ override def get(n: String, start: Scriptable) =
+ allPropertiesMap.getOrElse(n, () => values.getOrElse(n, JSContext.getUndefinedValue()))();
+ override def put(n: String, start: Scriptable, value: Object) =
+ values(n) = value.toString();
+ override def getIds() = keys;
+ override def getPrototype() = ScriptableObject.getObjectPrototype(globalScope);
+ override def has(n: String, start: Scriptable) =
+ allPropertiesMap.contains(n) || values.contains(n);
+ override def getDefaultValue(hint: Class[_]) = config.toString();
+ }
+}
+
+object global {
+ var context: Context = null;
+}
diff --git a/infrastructure/net.appjet.oui/dynamicvar.scala b/infrastructure/net.appjet.oui/dynamicvar.scala
new file mode 100644
index 0000000..b1f8c2e
--- /dev/null
+++ b/infrastructure/net.appjet.oui/dynamicvar.scala
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+class NoninheritedDynamicVariable[T](init: T) {
+ private val tl = new ThreadLocal[T] {
+ override def initialValue = init.asInstanceOf[T with AnyRef]
+ }
+
+ /** Retrieve the current value */
+ def value: T = tl.get.asInstanceOf[T]
+
+
+ /** Set the value of the variable while executing the specified
+ * thunk.
+ *
+ * @param newval The value to which to set the fluid
+ * @param thunk The code to evaluate under the new setting
+ */
+ def withValue[S](newval: T)(thunk: =>S): S = {
+ val oldval = value
+ tl.set(newval)
+
+ try { thunk } finally {
+ tl.set(oldval)
+ }
+ }
+
+ /** Change the currently bound value, discarding the old value.
+ * Usually <code>withValue()</code> gives better semantics.
+ */
+ def value_=(newval: T) = { tl.set(newval) }
+
+ override def toString: String = "NoninheritedDynamicVariable(" + value +")"
+}
diff --git a/infrastructure/net.appjet.oui/encryption.scala b/infrastructure/net.appjet.oui/encryption.scala
new file mode 100644
index 0000000..92d463b
--- /dev/null
+++ b/infrastructure/net.appjet.oui/encryption.scala
@@ -0,0 +1,267 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import scala.collection.mutable.ArrayBuffer;
+
+import javax.crypto.Cipher;
+import java.security._;
+import java.security.spec._;
+import java.math.BigInteger;
+import java.io.{ObjectInputStream, ObjectOutputStream, FileInputStream, FileOutputStream, PrintWriter, OutputStreamWriter, ByteArrayOutputStream, ByteArrayInputStream, InputStream, InputStreamReader, BufferedReader, DataOutputStream, DataInputStream};
+
+import net.appjet.common.util.BetterFile;
+
+// object EncryptomaticTest {
+// def main(args: Array[String]) {
+// args(0) match {
+// case "genkeys" => {
+// val keyPair = Encryptomatic.generateKeyPair;
+// println("made key pair.")
+// Encryptomatic.writeKeyPair(keyPair, args(1), args(2));
+// println("done.");
+// }
+// case "printkeys" => {
+// val keyPair = Encryptomatic.generateKeyPair;
+// val Pair(pubBytes, privBytes) = Encryptomatic.keyPairBytes(keyPair);
+// println("Public key: "+Encryptomatic.bytesToAscii(pubBytes))
+// println("Private key: "+Encryptomatic.bytesToAscii(privBytes));
+// }
+// case "sign" => {
+// println(Encryptomatic.sign(java.lang.System.in, Encryptomatic.readPrivateKey(new FileInputStream(args(1)))));
+// }
+// case "verify" => {
+// if (Encryptomatic.verify(java.lang.System.in, Encryptomatic.readPublicKey(new FileInputStream(args(1))), args(2))) {
+// println("Verification succeeded.");
+// } else {
+// println("Verification failed.");
+// }
+// }
+// case "test" => {
+// val out = new PrintWriter(new OutputStreamWriter(System.out, "UTF-8"), true);
+// val src = "Hey dudes, this is a test of ã“ã®é­šã¯ç¯‰åœ°ã‹ã‚‰ã®ã§ã™ã‹ï¼Ÿ";
+// out.println(src);
+// val bytes = Encryptomatic.bytesToAscii(src.getBytes("UTF-8"));
+// out.println("bytes: "+bytes);
+// val done = new String(Encryptomatic.asciiToBytes(bytes), "UTF-8");
+// out.println(done);
+// out.println("Match? "+(done == src));
+// }
+// case "keytest" => {
+// val keyPair = Encryptomatic.generateKeyPair;
+// val bytes = Encryptomatic.keyPairBytes(keyPair);
+// try {
+// val newKeyPair = Encryptomatic.readKeyPair(new ByteArrayInputStream(Encryptomatic.bytesToAscii(bytes._1).getBytes()),
+// new ByteArrayInputStream(Encryptomatic.bytesToAscii(bytes._2).getBytes()));
+// println("equal? "+(keyPair.getPublic.getEncoded.deepEquals(newKeyPair.getPublic.getEncoded) && keyPair.getPrivate.getEncoded.deepEquals(newKeyPair.getPrivate.getEncoded)));
+// } catch {
+// case e: InvalidKeySpecException => {
+// println("equality failed.")
+// println("public key 1 is: "+bytes._1.mkString("(", ",", ")"));
+// println("public key 2 is: "+BetterFile.getStreamBytes(new Encryptomatic.AsciiToBytesInputStream(new ByteArrayInputStream(Encryptomatic.bytesToAscii(bytes._1).getBytes()))).mkString("(", ",", ")"));
+// println("pk1 enc to: "+Encryptomatic.bytesToAscii(bytes._1));
+// }
+// }
+// }
+// }
+// }
+// }
+
+object Encryptomatic {
+ private val chars = "0123456789abcdefghijlkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ def bytesToAscii(bytes: Array[Byte]) = {
+ var i = BigInt(bytes);
+ val neg = i < 0;
+ if (neg)
+ i = BigInt(0)-i;
+ val sb = new StringBuffer();
+ while (i > BigInt(chars.length-1)) {
+ val Pair(div, mod) = i /% BigInt(chars.length);
+ sb.append(chars(mod.intValue));
+ i = div;
+ }
+ sb.append(chars(i.intValue));
+ (if (neg) "-" else "")+sb.toString.reverse;
+ }
+ def asciiToBytes(src: String) = {
+ var i = BigInt(0);
+ val Pair(isNegative, b) =
+ if (src.startsWith("-"))
+ (true, src.substring(1))
+ else
+ (false, src);
+ for (c <- b) {
+ i = i * chars.length + chars.indexOf(c);
+ }
+ if (isNegative)
+ i = BigInt(0)-i;
+ i.toByteArray
+ }
+
+ def generateKeyPair(keyType: String) = {
+ val keyGen = KeyPairGenerator.getInstance(keyType);
+ val random = SecureRandom.getInstance("SHA1PRNG", "SUN");
+ keyGen.initialize(1024, random);
+ keyGen.generateKeyPair();
+ }
+
+ def keyPairBytes(keyPair: KeyPair) = {
+ val pubKey = keyPair.getPublic();
+ if (pubKey.getFormat != "X.509")
+ throw new RuntimeException("Can't produce public key in format: "+pubKey.getFormat);
+
+ val privKey = keyPair.getPrivate();
+ if (privKey.getFormat != "PKCS#8")
+ throw new RuntimeException("Can't produce private key in format: "+privKey.getFormat);
+
+ (pubKey.getEncoded, privKey.getEncoded)
+ }
+
+ def writeKeyPair(keyPair: KeyPair, publicKey: String, privateKey: String) {
+ val pubOutputStream = new PrintWriter(new FileOutputStream(publicKey));
+ val privOutputStream = new PrintWriter(new FileOutputStream(privateKey));
+ val Pair(pubBytes, privBytes) = keyPairBytes(keyPair);
+ pubOutputStream.print(bytesToAscii(pubBytes));
+ privOutputStream.print(bytesToAscii(privBytes));
+ List(pubOutputStream, privOutputStream).foreach(x => {x.flush(); x.close()});
+ }
+
+ class AsciiToBytesInputStream(in: InputStream) extends InputStream {
+ val reader = new BufferedReader(new InputStreamReader(in));
+ val bytes = new ByteArrayInputStream(asciiToBytes(reader.readLine()));
+ def read(): Int = bytes.read();
+ }
+
+ def readPublicKey(keyType: String, publicKey: InputStream) = {
+ val pubKeySpec = new X509EncodedKeySpec(BetterFile.getStreamBytes(new AsciiToBytesInputStream(publicKey)));
+ KeyFactory.getInstance(keyType).generatePublic(pubKeySpec);
+ }
+ def readPrivateKey(keyType: String, privateKey: InputStream) = {
+ val privKeySpec = new PKCS8EncodedKeySpec(BetterFile.getStreamBytes(new AsciiToBytesInputStream(privateKey)));
+ KeyFactory.getInstance(keyType).generatePrivate(privKeySpec);
+ }
+
+ def readKeyPair(keyType: String, publicKey: InputStream, privateKey: InputStream) = {
+ new KeyPair(readPublicKey(keyType, publicKey),
+ readPrivateKey(keyType, privateKey));
+ }
+
+ def sign(source: InputStream, key: PrivateKey): Array[byte] = {
+ val dsa = Signature.getInstance("SHA1withDSA");
+ dsa.initSign(key);
+ val inBytes = new Array[Byte](4096);
+ var count = source.read(inBytes);
+ while (count > 0) {
+ dsa.update(inBytes, 0, count);
+ count = source.read(inBytes);
+ }
+ dsa.sign();
+ }
+
+ def verify(source: InputStream, key: PublicKey, sig: Array[byte]): Boolean = {
+ val dsa = Signature.getInstance("SHA1withDSA");
+ dsa.initVerify(key);
+ val inBytes = new Array[Byte](4096);
+ var count = source.read(inBytes);
+ while (count > 0) {
+ dsa.update(inBytes, 0, count);
+ count = source.read(inBytes);
+ }
+ dsa.verify(sig)
+ }
+
+ def encrypt(source: InputStream, key: PublicKey): Array[byte] = {
+ val cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ val inBytes = new Array[Byte](100);
+ val outBytesStream = new ByteArrayOutputStream();
+ val dataOut = new DataOutputStream(outBytesStream);
+
+ var count = source.read(inBytes);
+ while (count > 0) {
+ val arr = cipher.doFinal(inBytes, 0, count);
+ dataOut.writeShort(arr.length);
+ dataOut.write(arr, 0, arr.length);
+ count = source.read(inBytes);
+ }
+ dataOut.writeShort(0);
+ outBytesStream.toByteArray();
+ }
+
+ def decrypt(source: InputStream, key: PrivateKey): Array[byte] = {
+ val in = new DataInputStream(source);
+ def readBlock() = {
+ val length = in.readShort();
+ if (length > 0) {
+ val bytes = new Array[Byte](length);
+ in.readFully(bytes);
+ Some(bytes);
+ } else {
+ None;
+ }
+ }
+ val outBytes = new ArrayBuffer[Byte];
+ val cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ var block = readBlock();
+ while (block.isDefined) {
+ outBytes ++= cipher.doFinal(block.get);
+ block = readBlock();
+ }
+ outBytes.toArray;
+ }
+}
+
+object Encryptor {
+ def main(args: Array[String]) {
+ args(0) match {
+ case "genkeys" => {
+ println("generating keys...");
+ val keyPair = Encryptomatic.generateKeyPair(args(1));
+ println("saving public key to: "+args(2)+"; private key to: "+args(3));
+ Encryptomatic.writeKeyPair(keyPair, args(2), args(3));
+ println("done.");
+ }
+ case "test" => {
+ val plaintext = "This is a test of some data that's actually pretty long once you really start thinking about it. I mean, it needs to be more than 117 bytes for it to be a reasonable test, and I suppose it's pretty close to that now. OK, let's just go for it and see what happens.".getBytes("UTF-8");
+ val keys = Encryptomatic.generateKeyPair("RSA");
+ val ciphertext = Encryptomatic.bytesToAscii(Encryptomatic.encrypt(new ByteArrayInputStream(plaintext), keys.getPublic()));
+ println(ciphertext);
+ println(new String(Encryptomatic.decrypt(new ByteArrayInputStream(Encryptomatic.asciiToBytes(ciphertext)), keys.getPrivate()), "UTF-8"));
+ }
+ case "decode" => {
+ val key = Encryptomatic.readPrivateKey(args(1), new FileInputStream(args(2)));
+ val plaintext = Encryptomatic.decrypt(new ByteArrayInputStream(Encryptomatic.asciiToBytes(args(3))), key);
+ println(new String(plaintext, "UTF-8"));
+ }
+ case "decodeFile" => {
+ println("Enter private key (assuming type RSA):");
+ val key = Encryptomatic.readPrivateKey("RSA", java.lang.System.in);
+ val file = new java.io.File(args(1));
+ println("Reading "+file.getName()+"...");
+ val reader = new java.io.BufferedReader(new java.io.InputStreamReader(new FileInputStream(file)));
+ var line = reader.readLine();
+ while (line != null) {
+ val bytes = Encryptomatic.decrypt(new ByteArrayInputStream(Encryptomatic.asciiToBytes(line)), key);
+ println(new String(bytes, "UTF-8"));
+ line = reader.readLine();
+ }
+ }
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.oui/execution.scala b/infrastructure/net.appjet.oui/execution.scala
new file mode 100644
index 0000000..63749b1
--- /dev/null
+++ b/infrastructure/net.appjet.oui/execution.scala
@@ -0,0 +1,654 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.net.URLDecoder;
+import java.util.Enumeration;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.servlet.http.{HttpServletRequest, HttpServletResponse, HttpServlet};
+
+import scala.collection.mutable.{ListBuffer, LinkedHashSet, HashMap, ArrayBuffer};
+import scala.collection.immutable.Map;
+import scala.collection.jcl.Conversions;
+
+import org.mozilla.javascript.{Scriptable, Context, Function, ScriptableObject, JavaScriptException};
+import org.mortbay.jetty.RetryRequest;
+
+import net.appjet.bodylock.{BodyLock, Executable, JSRuntimeException, JSCompileException};
+import net.appjet.common.util.{HttpServletRequestFactory, BetterFile};
+
+import Util.enumerationToRichEnumeration;
+
+class RequestWrapper(val req: HttpServletRequest) {
+ req.setCharacterEncoding("UTF-8");
+// private lazy val parameterNames =
+// (for (i <- Conversions.convertSet(req.getParameterMap.keySet().asInstanceOf[java.util.Set[String]])) yield i).toList.toArray
+// private def parameterValues(k: String) = req.getParameterValues(k);
+ def headerCapitalize(s: String) =
+ s.split("-").map(
+ s =>
+ if (s == null || s.length < 1) s
+ else s.substring(0, 1).toUpperCase()+s.substring(1).toLowerCase()
+ ).mkString("-");
+ def isFake = false;
+ lazy val path = req.getRequestURI();
+ lazy val host = {
+ val hostFromHeader = req.getHeader("Host");
+ if ((hostFromHeader ne null) && hostFromHeader.indexOf(':') >= 0) {
+ // fix the port, which may be wrong in Host header (e.g. IE 6)
+ hostFromHeader.substring(0, hostFromHeader.indexOf(':')) + ":" +
+ req.getLocalPort;
+ }
+ else {
+ hostFromHeader;
+ }
+ }
+ lazy val query = req.getQueryString();
+ lazy val method = req.getMethod();
+ lazy val scheme = req.getScheme();
+ lazy val clientAddr = req.getRemoteAddr();
+
+ def decodeWwwFormUrlencoded(content: => String): Map[String, Array[String]] = {
+ val map = new HashMap[String, ArrayBuffer[String]];
+ if (content != null) {
+ for (pair <- content.split("&").map(_.split("=", 2))) {
+ val key = URLDecoder.decode(pair(0), "UTF-8");
+ val list = map.getOrElseUpdate(key, new ArrayBuffer[String]);
+ if (pair.length > 1) {
+ list += URLDecoder.decode(pair(1), "UTF-8");
+ }
+ }
+ }
+ Map((for ((k, v) <- map) yield (k, v.toArray)).toSeq: _*);
+ }
+
+ def postParams = decodeWwwFormUrlencoded(content.asInstanceOf[String]);
+ def getParams = decodeWwwFormUrlencoded(query);
+
+ lazy val params_i = {
+ if (contentType != null && contentType.startsWith("application/x-www-form-urlencoded")) {
+ if (req.getAttribute("ajcache_parameters") == null) {
+ req.setAttribute("ajcache_parameters",
+ Map((for (k <- (postParams.keys ++ getParams.keys).toList)
+ yield (k, postParams.getOrElse(k, Array[String]()) ++
+ getParams.getOrElse(k, Array[String]()))).toSeq: _*));
+ }
+ req.getAttribute("ajcache_parameters").asInstanceOf[Map[String, Array[String]]];
+ } else {
+ Conversions.convertMap(req.getParameterMap().asInstanceOf[java.util.Map[String, Array[String]]]);
+ }
+ }
+
+ def params(globalScope: Scriptable) = new ScriptableFromMapOfStringArrays(
+ globalScope,
+ params_i.keys.toList,
+ params_i.get(_),
+ false);
+ def headers(globalScope: Scriptable) = new ScriptableFromMapOfStringArrays(
+ globalScope,
+ req.getHeaderNames().asInstanceOf[Enumeration[String]]
+ .map(headerCapitalize).toList,
+ h => h match {
+ case "Host" => Some(Array(host));
+ case hh => Some(Util.enumerationToArray(req.getHeaders(headerCapitalize(hh)).asInstanceOf[Enumeration[String]])) },
+ true);
+ lazy val protocol = req.getProtocol();
+ lazy val contentType = req.getHeader("Content-Type");
+ lazy val postParamsInBody = contentType != null && contentType.startsWith("application/x-www-form-urlencoded");
+ lazy val content =
+ if ((contentType != null && contentType.startsWith("text/")) || postParamsInBody) {
+ val reader = req.getReader();
+ if (reader != null)
+ BetterFile.getReaderString(req.getReader());
+ else
+ null;
+ } else {
+ val stream = req.getInputStream();
+ if (stream != null)
+ BetterFile.getStreamBytes(req.getInputStream());
+ else
+ null;
+ }
+ def files(globalScope: Scriptable): Object = {
+// if (! req.isInstanceOf[com.oreilly.servlet.MultipartWrapper]) {
+ new ScriptableAdapter();
+// } else {
+// val r = req.asInstanceOf[com.oreilly.servlet.MultipartWrapper];
+// val fileScriptables = new HashMap[String, Scriptable]();
+// val fileBytes = new HashMap[String, Array[byte]]();
+// new ScriptableFromMapOfScriptableArrays(globalScope,
+// r.getFileNames().asInstanceOf[Enumeration[String]].toList,
+// name => {
+// if (r.getFile(name) == null)
+// None
+// else
+// Some(Array(fileScriptables.getOrElseUpdate(name,
+// new ScriptableFromMapOfArrays[Object](globalScope,
+// Set("contentType", "filesystemName", "bytes").toSeq,
+// _ match {
+// case "contentType" => Some(Array(r.getContentType(name)));
+// case "filesystemName" =>
+// Some(Array(r.getFilesystemName(name)));
+// case "bytes" =>
+// Some(Array(Context.javaToJS(fileBytes.getOrElseUpdate(name,
+// BetterFile.getFileBytes(r.getFile(name))), globalScope)));
+// case _ => None;
+// },
+// true))))
+// },
+// true);
+// }
+ }
+}
+
+class ResponseWrapper(val res: HttpServletResponse) {
+ private lazy val outputStrings = new ListBuffer[String];
+ private lazy val outputBytes = new ListBuffer[Array[byte]];
+ private var statusCode = 200;
+ private var contentType = "text/html";
+ private var redirect: String = null;
+ private lazy val headers = new LinkedHashSet[(String, String, HttpServletResponse => Unit)] {
+ def removeAll(k: String) {
+ this.foreach(x => if (x._1 == k) remove(x));
+ }
+ }
+
+ private[oui] def overwriteOutputWithError(code: Int, errorStr: String) {
+ statusCode = code;
+ outputStrings.clear();
+ outputStrings += errorStr;
+ outputBytes.clear();
+ headers.clear();
+ Util.noCacheHeaders.foreach(x => headers += (x._1, x._2, res => res.setHeader(x._1, x._2)));
+ redirect = null;
+ contentType = "text/html; charset=utf-8";
+ }
+
+ def reset() {
+ outputStrings.clear();
+ outputBytes.clear();
+ redirect = null;
+ headers.clear();
+ Util.noCacheHeaders.foreach(x => headers += (x._1, x._2, res => res.setHeader(x._1, x._2)));
+ statusCode = 200;
+ contentType = "text/html; charset=utf-8";
+ }
+ def error(code: Int, errorStr: String) {
+ overwriteOutputWithError(code, errorStr);
+ stop();
+ }
+ def stop() {
+ throw AppGeneratedStopException;
+ }
+
+ def write(s: String) {
+ outputStrings += s;
+ }
+ def getOutput() = outputStrings.mkString("");
+ def writeBytes(bytes: String) {
+ val a = new Array[byte](bytes.length());
+ bytes.getBytes(0, bytes.length(), a, 0);
+ outputBytes += a;
+ }
+ def writeBytes(bytes: Array[Byte]) {
+ outputBytes += bytes;
+ }
+ def getOutputBytes() = outputBytes.flatMap(x => x).toArray
+ def setContentType(s: String) {
+ contentType = s;
+ }
+ def getCharacterEncoding() = {
+ res.setContentType(contentType);
+ res.getCharacterEncoding();
+ }
+ def setStatusCode(sc: Int) {
+ statusCode = sc;
+ }
+ def getStatusCode() = statusCode;
+ def redirect(loc: String) {
+ statusCode = 302;
+ redirect = loc;
+ stop();
+ }
+ def setHeader(name: String, value: String) {
+ headers += ((name, value, res => res.setHeader(name, value)));
+ }
+ def addHeader(name: String, value: String) {
+ headers += ((name, value, res => res.addHeader(name, value)));
+ }
+ def getHeader(name: String) = {
+ headers.filter(_._1 == name).map(_._2).toSeq.toArray;
+ }
+ def removeHeader(name: String) {
+ headers.removeAll(name);
+ }
+
+ var gzipOutput = false;
+ def setGzip(gzip: Boolean) {
+ gzipOutput = gzip;
+ }
+
+ def print() {
+ if (redirect != null && statusCode == 302) {
+ headers.foreach(_._3(res));
+ res.sendRedirect(redirect);
+ } else {
+ res.setStatus(statusCode);
+ res.setContentType(contentType);
+ headers.foreach(_._3(res));
+ if (gzipOutput) res.setHeader("Content-Encoding", "gzip");
+ if (outputStrings.length > 0) {
+ var bytes: Seq[Array[Byte]] = outputStrings.map(_.getBytes(res.getCharacterEncoding()));
+ if (gzipOutput) bytes = List(Util.gzip(Array.concat(bytes:_*)));
+ res.setContentLength((bytes :\ 0) {_.length + _});
+ bytes.foreach(res.getOutputStream.write(_));
+ } else if (outputBytes.length > 0) {
+ var bytes: Seq[Array[Byte]] = outputBytes;
+ if (gzipOutput) bytes = List(Util.gzip(Array.concat(bytes:_*)));
+ res.setContentLength((bytes :\ 0) {_.length + _});
+ bytes.foreach(res.getOutputStream.write(_));
+ }
+ }
+ }
+}
+
+class ScriptableAdapter extends Scriptable {
+ private def unsupported() = throw UnsupportedOperationException;
+ def delete(index: Int) { unsupported(); }
+ def delete(name: String) { unsupported(); }
+ def get(index: Int, start: Scriptable): Object = Context.getUndefinedValue();
+ def get(name: String, start: Scriptable): Object = Context.getUndefinedValue();
+ def getClassName() = getClass.getName();
+ def getDefaultValue(hint: Class[_]) = "[ScriptableAdapter]";
+ def getIds(): Array[Object] = Array[Object]();
+ def getParentScope: Scriptable = null;
+ def getPrototype: Scriptable = null;
+ def has(index: Int, start: Scriptable): Boolean = false;
+ def has(name: String, start: Scriptable): Boolean = false;
+ def hasInstance(instance: Scriptable): Boolean = false;
+ def put(index: Int, start: Scriptable, value: Object) { unsupported(); }
+ def put(name: String, start: Scriptable, value: Object) { unsupported(); }
+ def setParentScope(parent: Scriptable) { unsupported(); }
+ def setPrototype(prototype: Scriptable) { unsupported(); }
+}
+
+class ScriptableFromMapOfStringArrays(globalScope: Scriptable,
+ keys: Seq[String], values: String => Option[Array[String]],
+ zeroMeansNone: Boolean) extends ScriptableFromMapOfArrays[String](
+ globalScope, keys, values, zeroMeansNone);
+
+class ScriptableFromMapOfScriptableArrays(globalScope: Scriptable,
+ keys: Seq[String], values: String => Option[Array[Scriptable]],
+ zeroMeansNone: Boolean) extends ScriptableFromMapOfArrays[Scriptable](
+ globalScope, keys, values, zeroMeansNone);
+
+
+class ScriptableFromMapOfArrays[V <: Object](globalScope: Scriptable,
+ keys: Seq[String], values: String => Option[Array[V]],
+ zeroMeansNone: Boolean) extends ScriptableAdapter {
+ override def get(n: String, start: Scriptable): Object = {
+ val v = values(n);
+ if (v.isEmpty || (zeroMeansNone && v.get.length == 0)) {
+ Context.getUndefinedValue();
+ } else if (v.get.length == 1) {
+ v.get.apply(0);
+ } else {
+ Context.getCurrentContext().newArray(globalScope, v.get.map(x => x.asInstanceOf[Object]));
+ }
+ }
+ override def getIds(): Array[Object] = keys.toArray[Object];
+ override def getPrototype = ScriptableObject.getObjectPrototype(globalScope);
+ override def has(n: String, start: Scriptable): Boolean = ! (values(n).isEmpty || (zeroMeansNone && values(n).get.length == 0));
+}
+
+object AppGeneratedStopException extends JSRuntimeException("User-generated stop.", null);
+class NoHandlerException(msg: String) extends JSRuntimeException(msg, null);
+object UnsupportedOperationException extends JSRuntimeException("Unsupported operation.", null);
+
+object ExecutionContextUtils {
+ val uniqueIds = new AtomicLong(0);
+
+ val ecVar = new NoninheritedDynamicVariable[ExecutionContext](null);
+ def withContext[E](ec: ExecutionContext)(block: => E): E = {
+ ecVar.withValue(ec)(block);
+ }
+
+ def currentContext = ecVar.value;
+}
+
+case class ExecutionContext(
+ val request: RequestWrapper,
+ val response: ResponseWrapper,
+ var runner: ScopeReuseManager.Runner) {
+ val asyncs = new ListBuffer[Function];
+ lazy val attributes = new HashMap[String, Any];
+ var completed = false;
+ lazy val executionId = ""+ExecutionContextUtils.uniqueIds.incrementAndGet();
+ var result: AnyRef = null;
+}
+
+object CometSupport {
+ trait CometHandler {
+ def handleCometRequest(req: HttpServletRequest, res: HttpServletResponse);
+ }
+ var cometHandler: CometHandler = null;
+}
+
+class OuiServlet extends HttpServlet {
+ override def doGet(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doPost(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doHead(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doPut(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doDelete(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doTrace(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ override def doOptions(req: HttpServletRequest, res: HttpServletResponse) {
+ execute(req, res);
+ }
+
+ def execute(req: HttpServletRequest, res: HttpServletResponse) {
+ if (req.getProtocol() == "HTTP/1.1" && req.getHeader("Host") == null) {
+ res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid HTTP/1.1 request: No \"Host\" header found.");
+ } else if (config.transportPrefix != null && req.getRequestURI().startsWith(config.transportPrefix)) {
+ val runner = ScopeReuseManager.getRunner;
+ val ec = new ExecutionContext(new RequestWrapper(req), new ResponseWrapper(res), runner);
+ req.setAttribute("executionContext", ec);
+ req.setAttribute("isServerPushConnection", true);
+ try {
+ CometSupport.cometHandler.handleCometRequest(req, res);
+ } catch {
+ case e: RetryRequest => {
+ ec.runner = null;
+ ScopeReuseManager.freeRunner(runner);
+ throw e;
+ }
+ case _ => {};
+ }
+ try {
+ ec.response.print();
+ execution.onprint(ec, BodyLock.subScope(runner.mainScope));
+ } finally {
+ ec.runner = null;
+ ScopeReuseManager.freeRunner(runner);
+ }
+ } else {
+ execution.execute(req, res);
+ }
+ }
+}
+
+object execution {
+ // maybe find a better place for this?
+ { // initialize ajstdlib
+ val c = Class.forName("net.appjet.ajstdlib.ajstdlib$");
+ val m = c.getDeclaredMethod("init");
+ val o = c.getDeclaredField("MODULE$");
+ m.invoke(o.get(null));
+ }
+
+ val requestLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onrequest.js"));
+ val errorLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onerror.js"));
+ val printLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onprint.js"));
+ val syntaxErrorLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "syntaxerror.js"));
+ val onSyntaxErrorLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onsyntaxerror.js"));
+ val sarsLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onsars.js"));
+ val scheduledTaskLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onscheduledtask.js"));
+ def requestExecutable = requestLib.executable;
+ def errorExecutable = errorLib.executable;
+ def printExecutable = printLib.executable;
+ def syntaxErrorExecutable = syntaxErrorLib.executable;
+ def onSyntaxErrorExecutable = onSyntaxErrorLib.executable;
+ def sarsExecutable = sarsLib.executable;
+ def scheduledTaskExecutable = scheduledTaskLib.executable;
+
+ def postSuccessfulRun(ec: ExecutionContext) {
+ try {
+ for (f <- ec.asyncs) {
+ BodyLock.runInContext({ cx =>
+ f.call(cx, f.getParentScope(), ec.runner.mainScope, Array[Object]());
+ });
+ }
+ } catch {
+ case e => exceptionlog(e);
+ }
+ }
+
+ def onprint(ec: ExecutionContext, scope: Scriptable) {
+ try {
+// ec.runner.globalScope.put("_appjetcontext_", ec.runner.globalScope, ec);
+ printExecutable.execute(scope);
+ } catch {
+ case e => { exceptionlog(e); } // shrug. this was best-effort anyway.
+ }
+ }
+
+ def execute(req: HttpServletRequest, res: HttpServletResponse) {
+ val runner = try {
+ ScopeReuseManager.getRunner;
+ } catch {
+ case e: JSCompileException => {
+ val r = ScopeReuseManager.getEmpty { r =>
+ syntaxErrorExecutable.execute(r.globalScope)
+ }
+ val ec = ExecutionContext(new RequestWrapper(req), new ResponseWrapper(res), r);
+// r.globalScope.put("_appjetcontext_", r.globalScope, ec);
+ ExecutionContextUtils.withContext(ec) {
+ ec.attributes("error") = e;
+ ec.result = onSyntaxErrorExecutable.execute(r.globalScope);
+ ec.response.print();
+ }
+ return;
+ }
+ }
+ val ec = ExecutionContext(new RequestWrapper(req), new ResponseWrapper(res), runner);
+ val startTime = executionlatencies.time;
+ execute(ec,
+ (sc: Int, msg: String) => {
+ ec.response.overwriteOutputWithError(sc, msg);
+ },
+ () => { executionlatencies.log(Map(
+ "time" -> (executionlatencies.time - startTime)));
+ ec.response.print() },
+ () => { ScopeReuseManager.freeRunner(runner) },
+ None);
+ }
+
+ def errorToHTML(e: Throwable) = {
+ val trace = new java.io.StringWriter();
+ e.printStackTrace(new java.io.PrintWriter(trace));
+ trace.toString().split("\n").mkString("<br>\n");
+ }
+ def execute(ec: ExecutionContext,
+ errorHandler: (Int, String) => Unit,
+ doneWritingHandler: () => Unit,
+ completedHandler: () => Unit,
+ customExecutable: Option[Executable]) =
+ ExecutionContextUtils.withContext(ec) {
+// ec.runner.globalScope.put("_appjetcontext_", ec.runner.globalScope, ec);
+ val runScope = BodyLock.subScope(ec.runner.mainScope);
+ try {
+ ec.result = customExecutable.getOrElse(requestExecutable).execute(runScope);
+ ec.completed = true;
+ } catch {
+ case AppGeneratedStopException => { ec.completed = true; }
+ case e: NoHandlerException => errorHandler(500, "No request handler is defined.");
+ case e: RetryRequest => { completedHandler(); throw e; }
+ case e => {
+ ec.attributes("error") = e;
+ try {
+ ec.result = errorExecutable.execute(runScope);
+ } catch {
+ case AppGeneratedStopException => { }
+ case nhe: NoHandlerException => {
+ exceptionlog(e);
+ e.printStackTrace();
+ errorHandler(500, "An error occurred and no error handler is defined.");
+ }
+ case e2 => {
+ exceptionlog(e); exceptionlog(e2);
+ val etext = e2 match {
+ case jse: JavaScriptException => { (jse.getValue() match {
+ case ne: org.mozilla.javascript.IdScriptableObject => ne.get("message", ne)
+ case e => e.getClass.getName
+ }) + "<br>\n" + errorToHTML(jse); }
+ case _ => errorToHTML(e2);
+ }
+ errorHandler(
+ 500,
+ "You like apples? An error occurred in the error handler while handling an error. How do you like <i>them</i> apples?<br>\n"+
+ etext+"<br>\nCaused by:<br>\n"+errorToHTML(e));
+ }
+ }
+ }
+ }
+ onprint(ec, runScope);
+ doneWritingHandler();
+ if (ec.completed && ! ec.asyncs.isEmpty) {
+ main.server.getThreadPool().dispatch(new Runnable {
+ def run() {
+ postSuccessfulRun(ec);
+ completedHandler();
+ }
+ });
+ } else {
+ completedHandler();
+ }
+ }
+
+ def runOutOfBandSimply(executable: Executable,
+ props: Option[Map[String, Any]]) = {
+ // there must be a context already.
+ val currentContext = ExecutionContextUtils.currentContext;
+ val request =
+ if (currentContext != null) {
+ currentContext.request;
+ } else {
+ val fakeHeaders = scala.collection.jcl.Conversions.convertMap(
+ new java.util.HashMap[String, String]);
+ fakeHeaders("Host") = "unknown.local";
+ new RequestWrapper(HttpServletRequestFactory.createRequest(
+ "/", fakeHeaders.underlying, "GET", null)) {
+ override val isFake = true;
+ }
+ }
+ val response =
+ if (currentContext != null && currentContext.response != null) {
+ currentContext.response;
+ } else {
+ new ResponseWrapper(null);
+ }
+ val runner =
+ if (currentContext != null) {
+ (false, currentContext.runner);
+ } else {
+ (true, ScopeReuseManager.getRunner);
+ }
+ val ec = new ExecutionContext(request, response, runner._2)
+ if (props.isDefined) {
+ for ((k, v) <- props.get) {
+ ec.attributes(k) = v;
+ }
+ }
+ try {
+ ExecutionContextUtils.withContext(ec) {
+ executable.execute(BodyLock.subScope(ec.runner.mainScope));
+ }
+ } finally {
+ if (runner._1) {
+ ScopeReuseManager.freeRunner(runner._2);
+ }
+ }
+ }
+
+ def runOutOfBand(executable: Executable, name: String,
+ props: Option[Map[String, Any]],
+ onFailure: Any => Unit) = {
+ var ec: ExecutionContext = null;
+ try {
+ val runner = ScopeReuseManager.getRunner;
+ val currentContext = ExecutionContextUtils.currentContext;
+ val request =
+ if (currentContext != null) {
+ currentContext.request;
+ } else {
+ val fakeHeaders = scala.collection.jcl.Conversions.convertMap(
+ new java.util.HashMap[String, String]);
+ fakeHeaders("Host") = "unknown.local";
+ new RequestWrapper(HttpServletRequestFactory.createRequest(
+ "/", fakeHeaders.underlying, "GET", null)) {
+ override val isFake = true;
+ }
+ }
+ val response =
+ if (currentContext != null && currentContext.response != null) {
+ new ResponseWrapper(currentContext.response.res);
+ } else {
+ new ResponseWrapper(null);
+ }
+ ec = new ExecutionContext(request, response, runner);
+ if (props.isDefined)
+ for ((k, v) <- props.get) {
+ ec.attributes(k) = v;
+ }
+ execution.execute(ec,
+ (sc: Int, msg: String) => { println(name+" execution failed with error: "+sc+"\n"+msg); onFailure((sc, msg)); },
+ () => { },
+ () => { ScopeReuseManager.freeRunner(runner) },
+ Some(executable));
+ if (ec.response != null && ec.response.getStatusCode() != 200) {
+ println(name+" execution failed with non-200 response: "+ec.response.getStatusCode());
+ onFailure((ec.response.getStatusCode, ec.response.getOutput()));
+ }
+ ec;
+ } catch {
+ case e: JSCompileException => {
+ val r = ScopeReuseManager.getEmpty { r =>
+ execution.syntaxErrorExecutable.execute(r.globalScope);
+ }
+ val ec = ExecutionContext(null, null, r);
+// r.globalScope.put("_appjetcontext_", r.globalScope, ec);
+ ExecutionContextUtils.withContext(ec) {
+ ec.attributes("error") = e;
+ ec.result = execution.onSyntaxErrorExecutable.execute(r.globalScope);
+ onFailure(e);
+ }
+ ec;
+ }
+ case e => {
+ println(name+" execution failed with error."); onFailure(e); ec;
+ }
+ }
+ }
+}
diff --git a/infrastructure/net.appjet.oui/files.scala b/infrastructure/net.appjet.oui/files.scala
new file mode 100644
index 0000000..3df5c1c
--- /dev/null
+++ b/infrastructure/net.appjet.oui/files.scala
@@ -0,0 +1,355 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import net.appjet.bodylock.{BodyLock, Executable};
+import net.appjet.common.util.BetterFile;
+
+import java.io.{File, FileNotFoundException, FileInputStream, IOException, ByteArrayInputStream};
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.WeakHashMap;
+
+import scala.collection.mutable.{Subscriber, Message, Reset=>SReset};
+import scala.collection.jcl.Conversions._;
+
+trait WeakPublisher[A, This <: WeakPublisher[A, This]] { self: This =>
+ val subscribers = new WeakHashMap[Subscriber[A, This], Unit];
+
+ protected def publish(event: A): Unit = {
+ subscribers.synchronized {
+ val subsCopy = for (sub <- subscribers.keySet()) yield sub;
+ for (sub <- subsCopy) {
+ sub.notify(this, event);
+ }
+ }
+ }
+
+ def subscribe(sub: Subscriber[A, This]): Unit = {
+ subscribers.synchronized {
+ subscribers.put(sub, ());
+ }
+ }
+
+ def removeSubscription(sub: Subscriber[A, This]): Unit = {
+ subscribers.synchronized {
+ subscribers.remove(sub);
+ }
+ }
+}
+
+object Reset extends SReset[Unit];
+
+object FileCache {
+ val files = new ConcurrentHashMap[String, CachedFile];
+
+ def file(path: String): CachedFile = {
+ if (files.containsKey(path)) {
+ files.get(path);
+ } else {
+ val f = new CachedFile(new File(path));
+ val oldFile = files.putIfAbsent(path, f);
+ if (oldFile != null) {
+ oldFile
+ } else {
+ f
+ }
+ }
+ }
+
+ def file(path: String, subscriber: Subscriber[Message[Unit], CachedFile]): CachedFile = {
+ val f = file(path);
+ f.subscribe(subscriber);
+ f;
+ }
+
+ def testFiles() = {
+ val iter = files.values().iterator();
+ var filesHaveChanged = false;
+ while (iter.hasNext()) {
+ if (iter.next().test()) {
+ filesHaveChanged = true;
+ }
+ }
+ filesHaveChanged;
+ }
+}
+
+class CachedFile(f: File) extends WeakPublisher[Message[Unit], CachedFile] {
+ var cachedContent: Option[Array[Byte]] = None;
+ def content = synchronized {
+ if (cachedContent.isEmpty) {
+ cachedContent = Some(BetterFile.getFileBytes(f));
+ }
+ cachedContent.get;
+ }
+ def stream = new ByteArrayInputStream(content);
+
+ var cachedExistence: Option[Boolean] = None;
+ def exists = synchronized {
+ if (cachedExistence.isEmpty) {
+ cachedExistence = Some(f.exists());
+ }
+ cachedExistence.get;
+ }
+
+ var cachedDirectory: Option[Boolean] = None;
+ def isDirectory = synchronized {
+ if (cachedDirectory.isEmpty) {
+ cachedDirectory = Some(f.isDirectory());
+ }
+ cachedDirectory.get;
+ }
+
+ def underlyingLastModified = f.lastModified;
+ var lastModified = underlyingLastModified;
+
+ def hasBeenModified = underlyingLastModified != lastModified;
+
+ def test() = synchronized {
+ if (hasBeenModified) {
+ reset;
+ true;
+ } else {
+ false;
+ }
+ }
+
+ def reset = synchronized {
+ lastModified = underlyingLastModified;
+ cachedContent = None;
+ cachedExistence = None;
+ cachedDirectory = None;
+ publish(Reset);
+ }
+}
+
+class SpecialJarOrNotFile(root: String, fname: String) extends JarOrNotFile(root, fname) {
+ override val classBase = "/net/appjet/ajstdlib/";
+ override val fileSep = "/../";
+
+ override def clone(fname: String) = new SpecialJarOrNotFile(root, fname);
+}
+
+// A JarOrNotFile that reads from the /mirror directory in the classpath.
+class MirroredJarOrNotFile(root: String, fname: String) extends JarOrNotFile(root, fname) {
+ override val classBase = "/mirror/";
+ override def clone(fname: String) = new MirroredJarOrNotFile(root, fname);
+}
+
+class JarVirtualFile(fname: String) extends MirroredJarOrNotFile(config.useVirtualFileRoot, fname);
+
+class JarOrNotFile(root: String, fname: String) extends Subscriber[Message[Unit], CachedFile] with WeakPublisher[Message[Unit], JarOrNotFile] {
+ val classBase = "/net/appjet/ajstdlib/modules/";
+ val fileSep = "/";
+ val isJar = (root == null);
+ val streamBase = if (isJar) getClass().getResource((classBase+fname).replaceAll("/+", "/")) else null;
+ val file = if (! isJar) FileCache.file(root+fileSep+fname, this) else null;
+
+ def openStream() = {
+ if (isJar) streamBase.openStream;
+ else file.stream;
+ }
+
+ def exists = {
+ if (isJar) streamBase != null;
+ else file.exists;
+ }
+
+ def isDirectory = if (isJar) false else file.isDirectory;
+
+ lazy val streamModified = streamBase.openConnection().getLastModified();
+ def lastModified = {
+ if (isJar) streamModified;
+ else file.lastModified;
+ }
+
+ def name = fname;
+
+ override def toString() =
+ getClass.getName+": "+hashCode()+"; fname: "+fname+"; streambase: "+streamBase+"; file: "+file+(if (isJar) " from: "+classBase+fname else "");
+// override def equals(o: AnyRef) =
+// o match {
+// case jf: JarOrNotFile => {
+// classBase == jf.classBase &&
+// fileSep == jf.fileSep &&
+// root == jf.root &&
+// fname == jf.fname
+// }
+// case _ => false
+// }
+// override def hashCode() =
+// classBase.hashCode + fileSep.hashCode + root.hashCode + fname.hashCode
+
+ def notify(pub: CachedFile, event: Message[Unit]) = synchronized {
+ publish(event);
+ }
+
+ def clone(fname: String) = new JarOrNotFile(root, fname);
+}
+
+abstract class AutoUpdateFile(val fname: String) extends Subscriber[Message[Unit], JarOrNotFile] {
+ def files: Array[JarOrNotFile]; // = config.moduleRoots.map(f => new JarOrNotFile(f, libName));
+
+ def exists = files.exists(_.exists);
+ def file = files.find(_.exists).getOrElse(null);
+ def fileLastModified = if (exists) file.lastModified else 0L;
+
+ // var lastModified = fileLastModified;
+ // var cachedContents: Option[String] = None;
+
+ def fail(): Nothing = {
+ throw new FileNotFoundException("No such module: "+fname);
+ }
+
+ // def hasBeenModified = {
+ // if (exists) {
+ // val newModTime = try {
+ // fileLastModified
+ // } catch {
+ // case e: NoSuchElementException => fail();
+ // case e: NullPointerException => fail();
+ // }
+ // newModTime > lastModified;
+ // } else {
+ // false;
+ // }
+ // }
+
+ // def update() = synchronized {
+ // try {
+ // lastModified = fileLastModified;
+ // val contents = BetterFile.getStreamContents(file.openStream()).replace("\r\n", "\n").replace("\r", "\n");
+ // if (contents == null) {
+ // fail();
+ // }
+ // cachedContents = Some(contents);
+ // } catch {
+ // case e: IOException => {
+ // exceptionlog(e);
+ // e.printStackTrace();
+ // fail();
+ // }
+ // }
+ // }
+
+ def notify(pub: JarOrNotFile, event: Message[Unit]) {
+ event match {
+ case Reset => cachedContents = None;
+ }
+ }
+
+ var cachedContents: Option[String] = None;
+ def update() = synchronized {
+ if (cachedContents.isEmpty) {
+ cachedContents = Some(BetterFile.getStreamContents(file.openStream()).replace("\r\n", "\n").replace("\r", "\n"));
+ }
+ }
+
+ def contents = synchronized {
+ update();
+ cachedContents.get;
+ }
+
+ override def toString() = "[AutoUpdateFile: "+fname+"]";
+}
+
+class FixedDiskResource(srcfile: JarOrNotFile) extends AutoUpdateFile(srcfile.name) {
+ lazy val files0 = Array(srcfile);
+ files0.foreach(_.subscribe(this));
+
+ override def files = files0;
+}
+
+abstract class DiskLibrary(fname: String) extends AutoUpdateFile(fname) {
+ var cachedExecutable: Option[Executable] = None;
+
+ lazy val classFiles = files.map({ f =>
+ val parts = f.name.split("/");
+ val pathIfAny = parts.reverse.drop(1).reverse.mkString("/");
+ val newFname =
+ if (pathIfAny == "")
+ className(f.name);
+ else
+ pathIfAny+"/"+className(parts.last);
+ val newFile = f.clone(newFname+".class");
+ newFile.subscribe(this);
+ newFile;
+ });
+ def className(fname: String): String = "JS$"+fname.split("\\.").reverse.drop(1).reverse.mkString(".").replaceAll("[^A-Za-z0-9]", "\\$");
+ def className: String = classFile.name.split("\\.").reverse.drop(1).reverse.mkString(".");
+
+ override def exists = super.exists || classFiles.exists(_.exists);
+ override def file = if (super.exists) super.file else classFile;
+ def classFile = classFiles.find(_.exists).getOrElse(null);
+
+// println("Made DiskLibrary on "+fname+", with classFile: "+classFile);
+
+ def updateExecutable() = synchronized {
+ if (classFile == null)
+ super.update();
+ if (cachedExecutable.isEmpty) {
+ try {
+ if (classFile != null) {
+ cachedExecutable = Some(BodyLock.executableFromBytes(BetterFile.getStreamBytes(classFile.openStream()), className.split("/").last));
+ } else {
+ cachedExecutable = Some(BodyLock.compileString(contents, "module "+fname, 1));
+ }
+ } catch {
+ case e => { cachedExecutable = None; throw e; }
+ }
+ }
+ }
+
+ def executable = synchronized {
+ updateExecutable();
+ cachedExecutable.get
+ }
+
+ override def notify(pub: JarOrNotFile, event: Message[Unit]) = synchronized {
+ super.notify(pub, event);
+ event match {
+ case Reset => cachedExecutable = None;
+ }
+ }
+
+ override def equals(o: Any) =
+ o match {
+ case dl: DiskLibrary => {
+ getClass.getName == dl.getClass.getName &&
+ fname == dl.fname
+ }
+ case _ => false;
+ }
+ override def hashCode() =
+ getClass.getName.hashCode + fname.hashCode
+}
+
+class FixedDiskLibrary(srcfile: JarOrNotFile) extends DiskLibrary(srcfile.name) {
+ lazy val files0 = Array(srcfile);
+ files0.foreach(_.subscribe(this));
+
+ override def files = files0;
+}
+
+class VariableDiskLibrary(libName: String) extends DiskLibrary(libName) {
+ lazy val files0 =
+ Array.concat(Array(new MirroredJarOrNotFile(null, libName)),
+ config.moduleRoots.map(f => new JarOrNotFile(f, libName)))
+ files0.foreach(_.subscribe(this));
+
+ override def files = files0;
+}
diff --git a/infrastructure/net.appjet.oui/logging.scala b/infrastructure/net.appjet.oui/logging.scala
new file mode 100644
index 0000000..9c384d2
--- /dev/null
+++ b/infrastructure/net.appjet.oui/logging.scala
@@ -0,0 +1,530 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.text.SimpleDateFormat;
+import java.io.{File, FileWriter, StringWriter, PrintWriter};
+import java.util.Date;
+import java.util.concurrent.{ConcurrentLinkedQueue, ConcurrentHashMap, CopyOnWriteArraySet};
+import java.util.concurrent.atomic.AtomicInteger;
+
+import scala.util.Sorting;
+import scala.ref.WeakReference;
+import scala.collection.mutable.{Map, HashMap};
+import scala.collection.jcl.{SetWrapper, Conversions};
+
+import org.json.{JSONObject, JSONArray};
+import org.mozilla.javascript.{Scriptable, Context};
+
+import Util.iteratorToRichIterator;
+import scala.collection.jcl.Conversions._;
+
+trait LoggablePropertyBag {
+ def date: Date;
+ def `type`: String = value("type").asInstanceOf[String];
+ def json: String;
+ def tabDelimited: String;
+ def keys: Array[String];
+ def value(k: String): Any;
+}
+
+class LoggableFromScriptable(
+ scr: Scriptable,
+ extra: Option[scala.collection.Map[String, String]])
+ extends LoggablePropertyBag {
+ def this(scr: Scriptable) = this(scr, None);
+ if (extra.isDefined) {
+ for ((k, v) <- extra.get if (! scr.has(k, scr))) {
+ scr.put(k, scr, v);
+ }
+ }
+
+ val keys =
+ scr.getIds()
+ .map(_.asInstanceOf[String])
+ .filter(scr.get(_, scr) != Context.getUndefinedValue());
+ Sorting.quickSort(keys);
+ if (! scr.has("date", scr)) {
+ scr.put("date", scr, System.currentTimeMillis());
+ }
+ val date = new Date(scr.get("date", scr).asInstanceOf[Number].longValue);
+ val json = FastJSON.stringify(scr);
+ val tabDelimited = GenericLoggerUtils.dateString(date) + "\t" +
+ keys.filter("date" != _).map(value(_)).mkString("\t");
+
+ def value(k: String) = {
+ scr.get(k, scr);
+ }
+}
+
+class LoggableFromMap[T](
+ map: scala.collection.Map[String, T],
+ extra: Option[scala.collection.Map[String, String]])
+ extends LoggablePropertyBag {
+ def this(map: scala.collection.Map[String, T]) = this(map, None);
+ val keys = map.keys.collect.toArray ++
+ extra.map(_.keys.collect.toArray).getOrElse(Array[String]());
+ Sorting.quickSort(keys);
+
+ def fillJson(json: JSONObject,
+ map: scala.collection.Map[String, T]): JSONObject = {
+ for ((k, v) <- map) {
+ v match {
+ case b: Boolean => json.put(k, b);
+ case d: Double => json.put(k, d);
+ case i: Int => json.put(k, i);
+ case l: Long => json.put(k, l);
+ case m: java.util.Map[_,_] => json.put(k, m);
+ case m: scala.collection.Map[String,T] =>
+ json.put(k, fillJson(new JSONObject(), m));
+ case c: java.util.Collection[_] => json.put(k, c);
+ case o: Object => json.put(k, o);
+ case _ => {};
+ }
+ }
+ json;
+ }
+ val json0 = fillJson(new JSONObject(), map);
+ if (extra.isDefined) {
+ for ((k, v) <- extra.get if (! json0.has(k))) {
+ json0.put(k, v);
+ }
+ }
+ if (! json0.has("date")) {
+ json0.put("date", System.currentTimeMillis());
+ }
+ val date = new Date(json0.getLong("date"));
+ val json = json0.toString;
+ val tabDelimited =
+ GenericLoggerUtils.dateString(date) + "\t" +
+ keys.filter("date" != _).map(value(_)).mkString("\t");
+
+ def value(k: String) = {
+ map.orElse(extra.getOrElse(Map[String, Any]()))(k);
+ }
+}
+
+class LoggableFromJson(val json: String) extends LoggablePropertyBag {
+ val obj = new JSONObject(json);
+ val date = new Date(obj.getLong("date"));
+ val keys = obj.sortedKeys().map(String.valueOf(_)).collect.toArray;
+ def value(k: String) = obj.get(k);
+ val tabDelimited =
+ GenericLoggerUtils.dateString(date) + "\t"+
+ keys.filter("date" != _).map(value(_)).mkString("\t");
+}
+
+object GenericLoggerUtils {
+ lazy val df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
+ def dateString(date: Date) = df.format(date);
+ var extraPropertiesFunction: Option[() => Map[String, String]] = None;
+ def setExtraPropertiesFunction(f: () => Map[String, String]) {
+ extraPropertiesFunction = Some(() => {
+ try {
+ f();
+ } catch {
+ case e => withoutExtraProperties {
+ exceptionlog(e);
+ Map[String, String]();
+ }
+ }
+ });
+ }
+ def getExtraProperties: Option[Map[String, String]] = {
+ if (shouldGetExtraProperties) {
+ withoutExtraProperties(extraPropertiesFunction.map(_()));
+ } else {
+ None;
+ }
+ }
+
+ val registeredWranglers =
+ new ConcurrentHashMap[String, SetWrapper[WeakReference[LogWrangler]]];
+ def registerWrangler(name: String, wrangler: LogWrangler) {
+ wranglers(name) += wrangler.ref;
+ }
+ def clearWrangler(name: String, wrangler: LogWrangler) {
+ wranglers(name) -= wrangler.ref;
+ }
+ def wranglers(name: String) = {
+ if (! registeredWranglers.containsKey(name)) {
+ val set1 = Conversions.convertSet(
+ new CopyOnWriteArraySet[WeakReference[LogWrangler]]);
+ val set2 = registeredWranglers.putIfAbsent(
+ name, set1);
+ if (set2 == null) {
+ set1
+ } else {
+ set2
+ }
+ } else {
+ registeredWranglers.get(name);
+ }
+ }
+ def tellWranglers(name: String, lpb: LoggablePropertyBag) {
+ for (w <- wranglers(name)) {
+ w.get.foreach(_.tell(lpb));
+ if (! w.isValid) {
+ wranglers(name) -= w;
+ }
+ }
+ }
+
+ val shouldGetExtraProperties_var =
+ new NoninheritedDynamicVariable[Boolean](true);
+ def withoutExtraProperties[E](block: => E): E = {
+ shouldGetExtraProperties_var.withValue(false)(block);
+ }
+ def shouldGetExtraProperties = shouldGetExtraProperties_var.value;
+}
+
+class GenericLogger(path: String, logName: String, rotateDaily: Boolean) {
+ val queue = new ConcurrentLinkedQueue[LoggablePropertyBag];
+
+ var loggerThread: Thread = null;
+ var currentLogDay:Date = null;
+ var logWriter: FileWriter = null;
+ var logBase = config.logDir;
+ def setLogBase(p: String) { logBase = p }
+
+ var echoToStdOut = false;
+ def setEchoToStdOut(e: Boolean) {
+ echoToStdOut = e;
+ }
+ def stdOutPrefix = logName+": "
+
+ def initLogWriter(logDay: Date) {
+ currentLogDay = logDay;
+
+ // if rotating, log filename is logBase/[path/]logName/logName-<date>.jslog
+ // otherwise, log filename is logBase/[path/]logName.jslog
+ var fileName =
+ if (rotateDaily) {
+ val df = new SimpleDateFormat("yyyy-MM-dd");
+ logName + "/" + logName + "-" + df.format(logDay) + ".jslog";
+ } else {
+ logName + ".jslog";
+ }
+ if (path != null && path.length > 0) {
+ fileName = path + "/" + fileName;
+ }
+ val f = new File(logBase+"/"+fileName);
+ if (! f.getParentFile.exists) {
+ f.getParentFile().mkdirs();
+ }
+ logWriter = new FileWriter(f, true);
+ }
+
+ def rotateIfNecessary(messageDate: Date) {
+ if (rotateDaily) {
+ if (!((messageDate.getYear == currentLogDay.getYear) &&
+ (messageDate.getMonth == currentLogDay.getMonth) &&
+ (messageDate.getDate == currentLogDay.getDate))) {
+ logWriter.flush();
+ logWriter.close();
+ initLogWriter(messageDate);
+ }
+ }
+ }
+
+ def flush() {
+ flush(java.lang.Integer.MAX_VALUE);
+ }
+ def close() {
+ logWriter.close();
+ }
+
+ def flush(n: Int) = synchronized {
+ var count = 0;
+ while (count < n && ! queue.isEmpty()) {
+ val lpb = queue.poll();
+ rotateIfNecessary(lpb.date);
+ logWriter.write(lpb.json+"\n");
+ if (echoToStdOut)
+ print(lpb.tabDelimited.split("\n").mkString(stdOutPrefix, "\n"+stdOutPrefix, "\n"));
+ count += 1;
+ }
+ if (count > 0) {
+ logWriter.flush();
+ }
+ count;
+ }
+
+ def start() {
+ initLogWriter(new Date());
+
+ loggerThread = new Thread("GenericLogger "+logName) {
+ this.setDaemon(true);
+ override def run() {
+ while (true) {
+ if (queue.isEmpty()) {
+ Thread.sleep(500);
+ } else {
+ flush(1000);
+ }
+ }
+ }
+ }
+ main.loggers += this;
+ loggerThread.start();
+ }
+
+ def log(lpb: LoggablePropertyBag) {
+ if (loggerThread != null) {
+ queue.offer(lpb);
+ GenericLoggerUtils.tellWranglers(logName, lpb);
+ }
+ }
+ def logObject(scr: Scriptable) {
+ log(new LoggableFromScriptable(
+ scr, GenericLoggerUtils.getExtraProperties));
+ }
+ def log[T](m: scala.collection.Map[String, T]) {
+ log(new LoggableFromMap(
+ m, GenericLoggerUtils.getExtraProperties));
+ }
+ def log(s: String) {
+ log(Map("message" -> s));
+ }
+ def apply(s: String) {
+ log(s);
+ }
+ def apply(scr: Scriptable) {
+ logObject(scr);
+ }
+ def apply[T](m: scala.collection.Map[String, T]) {
+ log(m);
+ }
+}
+
+object profiler extends GenericLogger("backend", "profile", false) {
+ def apply(id: String, op: String, method: String, path: String, countAndNanos: (Long, Long)) {
+ if (loggerThread != null)
+ log(id+":"+op+":"+method+":"+path+":"+
+ Math.round(countAndNanos._2/1000)+
+ (if (countAndNanos._1 > 1) ":"+countAndNanos._1 else ""));
+ }
+// def apply(state: RequestState, op: String, nanos: long) {
+// apply(state.requestId, op, state.req.getMethod(), state.req.getRequestURI(), nanos);
+// }
+
+ def time =
+ System.nanoTime();
+
+ // thread-specific stuff.
+ val map = new ThreadLocal[HashMap[String, Any]] {
+ override def initialValue = new HashMap[String, Any];
+ }
+ val idGen = new java.util.concurrent.atomic.AtomicLong(0);
+ val id = new ThreadLocal[Long] {
+ override def initialValue = idGen.getAndIncrement();
+ }
+ def reset() = {
+ map.remove();
+ id.remove();
+ }
+
+ def record(key: String, time: Long) {
+ map.get()(key) = (1L, time);
+ }
+ def recordCumulative(key: String, time: Long) {
+ map.get()(key) = map.get().getOrElse(key, (0L, 0L)) match {
+ case (count: Long, time0: Long) => (count+1, time0+time);
+ case _ => { } // do nothing, but maybe shoud error.
+ }
+ }
+ def print() {
+ for ((k, t) <- map.get()) {
+ profiler(""+id.get(), k, "/", "/", t match {
+ case (count: Long, time0: Long) => (count, time0);
+ case _ => (-1L, -1L);
+ });
+ }
+ }
+
+ def printTiming[E](name: String)(block: => E): E = {
+ val startTime = time;
+ val r = block;
+ val endTime = time;
+ println(name+": "+((endTime - startTime)/1000)+" us.");
+ r;
+ }
+}
+
+object eventlog extends GenericLogger("backend", "server-events", true) {
+ start();
+}
+
+object streaminglog extends GenericLogger("backend", "streaming-events", true) {
+ start();
+}
+
+object exceptionlog extends GenericLogger("backend", "exceptions", true) {
+ def apply(e: Throwable) {
+ val s = new StringWriter;
+ e.printStackTrace(new PrintWriter(s));
+ log(Map(
+ "description" -> e.toString(),
+ "trace" -> s.toString()));
+ }
+
+ echoToStdOut = config.devMode
+ override def stdOutPrefix = "(exlog): ";
+
+ start();
+}
+
+// object dprintln extends GenericLogger("backend", "debug", true) {
+// echoToStdOut = config.devMode;
+// }
+
+class STFULogger extends org.mortbay.log.Logger {
+ def debug(m: String, a0: Object, a1: Object) { }
+ def debug(m: String, t: Throwable) { }
+ def getLogger(m: String) = { this }
+ def info(m: String, a0: Object, a2: Object) { }
+ def isDebugEnabled() = { false }
+ def setDebugEnabled(t: Boolean) { }
+ def warn(m: String, a0: Object, a1: Object) { }
+ def warn(m: String, t: Throwable) { }
+}
+
+case class Percentile(count: Int, p50: Int, p90: Int, p95: Int, p99: Int, max: Int);
+
+object cometlatencies {
+ var latencies = new java.util.concurrent.ConcurrentLinkedQueue[Int];
+ def register(t: Int) = latencies.offer(t);
+
+ var loggerThread: Thread = null;
+ var lastCount: Option[Map[String, Int]] = None;
+ var lastStats: Option[Percentile] = None;
+ def start() {
+ loggerThread = new Thread("latencies logger") {
+ this.setDaemon(true);
+ override def run() {
+ while(true) {
+ Thread.sleep(60*1000); // every minute
+ try {
+ val oldLatencies = latencies;
+ latencies = new java.util.concurrent.ConcurrentLinkedQueue[Int];
+ val latArray = oldLatencies.toArray().map(_.asInstanceOf[int]);
+ Sorting.quickSort(latArray);
+ def pct(p: Int) =
+ if (latArray.length > 0)
+ latArray(Math.floor((p/100.0)*latArray.length).toInt);
+ else
+ 0;
+ def s(a: Any) = String.valueOf(a);
+ lastStats = Some(Percentile(latArray.length,
+ pct(50), pct(90), pct(95), pct(99),
+ if (latArray.length > 0) latArray.last else 0));
+ eventlog.log(Map(
+ "type" -> "streaming-message-latencies",
+ "count" -> s(lastStats.get.count),
+ "p50" -> s(lastStats.get.p50),
+ "p90" -> s(lastStats.get.p90),
+ "p95" -> s(lastStats.get.p95),
+ "p99" -> s(lastStats.get.p99),
+ "max" -> s(lastStats.get.max)));
+ lastCount = Some({
+ val c = Class.forName("net.appjet.ajstdlib.Comet$");
+ c.getDeclaredMethod("connectionStatus")
+ .invoke(c.getDeclaredField("MODULE$").get(null))
+ }.asInstanceOf[Map[String, Int]]);
+ eventlog.log(
+ Map("type" -> "streaming-connection-count") ++
+ lastCount.get.elements.map(p => (p._1, String.valueOf(p._2))));
+ } catch {
+ case e: Exception => {
+ exceptionlog(e);
+ }
+ }
+ }
+ }
+ }
+ loggerThread.start();
+ }
+
+ start();
+}
+
+object executionlatencies extends GenericLogger("backend", "latency", true) {
+ start();
+
+ def time = System.currentTimeMillis();
+}
+
+abstract class LogWrangler {
+ def tell(lpb: LoggablePropertyBag);
+ def tell(json: String) { tell(new LoggableFromJson(json)); }
+ lazy val ref = new WeakReference(this);
+
+ def watch(logName: String) {
+ GenericLoggerUtils.registerWrangler(logName, this);
+ }
+}
+
+// you probably want to subclass this, or at least set data.
+class FilterWrangler(
+ `type`: String,
+ filter: LoggablePropertyBag => Boolean,
+ field: String) extends LogWrangler {
+ def tell(lpb: LoggablePropertyBag) {
+ if ((`type` == null || lpb.`type` == `type`) &&
+ (filter == null || filter(lpb))) {
+ val entry = lpb.value(field);
+ data(lpb.date, entry);
+ }
+ }
+ var data: (Date, Any) => Unit = null;
+ def setData(data0: (Date, Any) => Unit) {
+ data = data0;
+ }
+}
+
+class TopNWrangler(n: Int, `type`: String,
+ filter: LoggablePropertyBag => Boolean,
+ field: String)
+ extends FilterWrangler(`type`, filter, field) {
+ val entries = new ConcurrentHashMap[String, AtomicInteger]();
+ def sortedEntries = {
+ Sorting.stableSort(
+ convertMap(entries).toSeq,
+ (p1: (String, AtomicInteger), p2: (String, AtomicInteger)) =>
+ p1._2.get() > p2._2.get());
+ }
+ def count = {
+ (convertMap(entries) :\ 0) { (x, y) => x._2.get() + y }
+ }
+
+ def topNItems(n: Int): Array[(String, Int)] =
+ sortedEntries.take(n).map(p => (p._1, p._2.get())).toArray;
+ def topNItems: Array[(String, Int)] = topNItems(n);
+
+ data = (date: Date, value: Any) => {
+ val entry = value.asInstanceOf[String];
+ val i =
+ if (! entries.containsKey(entry)) {
+ val newInt = new AtomicInteger(0);
+ val oldInt = entries.putIfAbsent(entry, newInt);
+ if (oldInt == null) { newInt } else { oldInt }
+ } else {
+ entries.get(entry);
+ }
+ i.incrementAndGet();
+ }
+}
diff --git a/infrastructure/net.appjet.oui/main.scala b/infrastructure/net.appjet.oui/main.scala
new file mode 100644
index 0000000..42cd268
--- /dev/null
+++ b/infrastructure/net.appjet.oui/main.scala
@@ -0,0 +1,386 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import net.appjet.bodylock.{BodyLock, Executable};
+
+import java.io.File;
+import java.util.{Properties, Date};
+import java.lang.annotation.Annotation;
+import java.text.SimpleDateFormat;
+
+import scala.collection.mutable.{HashMap, SynchronizedMap, HashSet};
+import scala.collection.jcl.{IterableWrapper, Conversions};
+
+import org.mortbay.thread.QueuedThreadPool;
+import org.mortbay.jetty.servlet.{Context, HashSessionIdManager, FilterHolder, ServletHolder};
+import org.mortbay.jetty.handler.{HandlerCollection, RequestLogHandler, HandlerList};
+import org.mortbay.jetty.{Server, NCSARequestLog, Request, Response};
+import org.mortbay.servlet.GzipFilter;
+
+// removed due to license restrictions
+// import com.oreilly.servlet.MultipartFilter;
+
+import net.appjet.common.util.{BetterFile, HttpServletRequestFactory};
+import net.appjet.common.cli._;
+import net.appjet.bodylock.JSCompileException;
+
+import Util.enumerationToRichEnumeration;
+
+object main {
+ val startTime = new java.util.Date();
+
+ def quit(status: Int) {
+ java.lang.Runtime.getRuntime().halt(status);
+ }
+
+ def setupFilesystem() {
+ val logdir = new File(config.logDir+"/backend/access");
+ if (! logdir.isDirectory())
+ if (! logdir.mkdirs())
+ quit(1);
+ }
+
+ val options =
+ for (m <- config.allProperties if (m.getAnnotation(classOf[ConfigParam]) != null)) yield {
+ val cp = m.getAnnotation(classOf[ConfigParam])
+ new CliOption(m.getName(), cp.value(), if (cp.argName().length > 0) Some(cp.argName()) else None);
+ }
+
+ def printUsage() {
+ println("\n--------------------------------------------------------------------------------");
+ println("usage:");
+ println((new CliParser(options)).usage);
+ println("--------------------------------------------------------------------------------\n");
+ }
+
+ def extractOptions(args: Array[String]) {
+ val parser = new CliParser(options);
+ val opts =
+ try {
+ parser.parseOptions(args)._1;
+ } catch {
+ case e: ParseException => {
+ println("error: "+e.getMessage());
+ printUsage();
+ System.exit(1);
+ null;
+ }
+ }
+ if (opts.contains("configFile")) {
+ val p = new Properties();
+ p.load(new java.io.FileInputStream(opts("configFile")));
+ extractOptions(p);
+ }
+ for ((k, v) <- opts) {
+ config.values(k) = v;
+ }
+ }
+
+ def extractOptions(props: Properties) {
+ for (k <- for (o <- props.propertyNames()) yield o.asInstanceOf[String]) {
+ config.values(k) = props.getProperty(k);
+ }
+ }
+
+ val startupExecutable = (new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onstartup.js"))).executable;
+ def runOnStartup() {
+ execution.runOutOfBand(startupExecutable, "Startup", None, { error =>
+ error match {
+ case e: JSCompileException => { }
+ case e: Throwable => { e.printStackTrace(); }
+ case (sc: Int, msg: String) => { println(msg); }
+ case x => println(x);
+ }
+ System.exit(1);
+ });
+ }
+
+ lazy val shutdownExecutable = (new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onshutdown.js"))).executable;
+ def runOnShutdown() {
+ execution.runOutOfBand(shutdownExecutable, "Shutdown", None, { error =>
+ error match {
+ case e: JSCompileException => { }
+ case e: Throwable => { }
+ case (sc: Int, msg: String) => { println(msg); }
+ case x => println(x);
+ }
+ });
+ }
+
+ def runOnSars(q: String) = {
+ val ec = execution.runOutOfBand(execution.sarsExecutable, "SARS", Some(Map("sarsRequest" -> q)), { error =>
+ error match {
+ case e: JSCompileException => { throw e; }
+ case e: Throwable => { exceptionlog(e); throw e; }
+ case (sc: Int, msg: String) => { println(msg); throw new RuntimeException(""+sc+": "+msg) }
+ case x => { println(x); throw new RuntimeException(x.toString()) }
+ }
+ });
+ ec.attributes.get("sarsResponse").map(_.toString());
+ }
+
+ def stfu() {
+ System.setProperty("org.mortbay.log.class", "net.appjet.oui.STFULogger");
+ System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
+ System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "OFF");
+ }
+ var server: Server = null;
+ var sarsServer: net.appjet.common.sars.SarsServer = null;
+
+ var loggers = new HashSet[GenericLogger];
+ def main(args: Array[String]) {
+ val etherpadProperties = getClass.getResource("/etherpad.properties");
+ if (etherpadProperties != null) {
+ val p = new Properties();
+ p.load(etherpadProperties.openStream);
+ extractOptions(p);
+ }
+ extractOptions(args);
+
+ if (! config.verbose)
+ stfu();
+ setupFilesystem();
+ if (config.devMode)
+ config.print;
+ if (config.profile)
+ profiler.start();
+ if (config.listenMonitoring != "0:0")
+ monitoring.startMonitoringServer();
+
+ // this needs a better place.
+ if (config.devMode)
+ BodyLock.map = Some(new HashMap[String, String] with SynchronizedMap[String, String]);
+
+ server = new Server();
+ if (config.maxThreads > 0)
+ server.setThreadPool(new QueuedThreadPool(config.maxThreads));
+ else
+ server.setThreadPool(new QueuedThreadPool());
+ // set up socket connectors
+ val nioconnector = new CometSelectChannelConnector;
+ var sslconnector: CometSslSelectChannelConnector = null;
+ nioconnector.setPort(config.listenPort);
+ if (config.listenHost.length > 0)
+ nioconnector.setHost(config.listenHost);
+ if (config.listenSecurePort == 0) {
+ server.setConnectors(Array(nioconnector));
+ } else {
+ sslconnector = new CometSslSelectChannelConnector;
+ sslconnector.setPort(config.listenSecurePort);
+ if (config.listenSecureHost.length > 0)
+ sslconnector.setHost(config.listenSecureHost);
+ if (! config.sslKeyStore_isSet) {
+ val url = getClass.getResource("/mirror/snakeoil-ssl-cert");
+ if (url != null)
+ sslconnector.setKeystore(url.toString());
+ else
+ sslconnector.setKeystore(config.sslKeyStore);
+ } else {
+ sslconnector.setKeystore(config.sslKeyStore);
+ }
+ sslconnector.setPassword(config.sslStorePassword);
+ sslconnector.setKeyPassword(config.sslKeyPassword);
+ sslconnector.setTrustPassword(config.sslStorePassword);
+ sslconnector.setExcludeCipherSuites(Array[String](
+ "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_WITH_DES_CBC_SHA",
+ "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_RSA_WITH_NULL_MD5",
+ "SSL_RSA_WITH_NULL_SHA",
+ "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+ "SSL_DH_anon_WITH_DES_CBC_SHA",
+ "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+ "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"));
+ server.setConnectors(Array(nioconnector, sslconnector));
+ }
+
+ // set up Context and Servlet
+ val handler = new Context(server, "/", Context.NO_SESSIONS | Context.NO_SECURITY);
+ handler.addServlet(new ServletHolder(new OuiServlet), "/");
+
+// val filterHolder = new FilterHolder(new MultipartFilter());
+// filterHolder.setInitParameter("uploadDir", System.getProperty("java.io.tmpdir"));
+// handler.addFilter(filterHolder, "/*", 1);
+
+ global.context = handler;
+
+ // set up apache-style logging
+ val requestLogHandler = new RequestLogHandler();
+ val requestLog = new NCSARequestLog(config.logDir+"/backend/access/access-yyyy_mm_dd.request.log") {
+ override def log(req: Request, res: Response) {
+ try {
+ if (config.devMode || config.specialDebug)
+ super.log(req, res);
+ else if (res.getStatus() != 200 || config.transportPrefix == null || ! req.getRequestURI().startsWith(config.transportPrefix))
+ super.log(req, res);
+ val d = new Date();
+ appstats.stati.foreach(_(if (res.getStatus() < 0) 404 else res.getStatus()).hit(d));
+ } catch {
+ case e => { exceptionlog("Error writing to log?"); exceptionlog(e); }
+ }
+ }
+ };
+ requestLog.setRetainDays(365);
+ requestLog.setAppend(true);
+ requestLog.setExtended(true);
+ requestLog.setLogServer(true);
+ requestLog.setLogLatency(true);
+ requestLog.setLogTimeZone("PST");
+ requestLogHandler.setRequestLog(requestLog);
+
+ // set handlers with server
+ val businessHandlers = new HandlerList();
+ businessHandlers.setHandlers(Array(handler));
+ val allHandlers = new HandlerCollection();
+ allHandlers.setHandlers(Array(businessHandlers, requestLogHandler));
+ server.setHandler(allHandlers);
+
+ // fix slow startup bug
+ server.setSessionIdManager(new HashSessionIdManager(new java.util.Random()));
+
+ // run the onStartup script.
+ runOnStartup();
+
+ // preload some runners, if necessary.
+ if (config.preloadRunners > 0) {
+ val b = new java.util.concurrent.CountDownLatch(config.preloadRunners);
+ for (i <- 0 until config.preloadRunners)
+ (new Thread {
+ ScopeReuseManager.freeRunner(ScopeReuseManager.newRunner);
+ b.countDown();
+ }).start();
+ while (b.getCount() > 0) {
+ b.await();
+ }
+ println("Preloaded "+config.preloadRunners+" runners.");
+ }
+
+ // start SARS server.
+ if (config.listenSarsPort > 0) {
+ try {
+ import net.appjet.common.sars._;
+ sarsServer = new SarsServer(config.sarsAuthKey,
+ new SarsMessageHandler { override def handle(q: String) = runOnSars(q) },
+ if (config.listenSarsHost.length > 0) Some(config.listenSarsHost) else None,
+ config.listenSarsPort);
+ sarsServer.daemon = true;
+ sarsServer.start();
+ } catch {
+ case e: java.net.SocketException => {
+ println("SARS: A socket exception occurred: "+e.getMessage()+" on SARS server at "+config.listenSarsHost+":"+config.listenSarsPort);
+ java.lang.Runtime.getRuntime().halt(1);
+ }
+ }
+ }
+
+ // start server
+ java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
+ override def run() {
+ val df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
+ def printts(str: String) {
+ println("["+df.format(new Date())+"]: "+str);
+ }
+ printts("Shutting down...");
+ handler.setShutdown(true);
+ Thread.sleep(if (config.devMode) 500 else 3000);
+ printts("...done, running onshutdown.");
+ runOnShutdown();
+ printts("...done, stopping server.");
+ server.stop();
+ server.join();
+ printts("...done, flushing logs.");
+ for (l <- loggers) { l.flush(); l.close(); }
+ printts("...done.");
+ }
+ });
+
+ def socketError(c: org.mortbay.jetty.Connector, e: java.net.SocketException) {
+ var msg = e.getMessage();
+ println("SOCKET ERROR: "+msg+" - "+(c match {
+ case null => "(unknown socket)";
+ case x => {
+ (x.getHost() match {
+ case null => "localhost";
+ case y => y;
+ })+":"+x.getPort();
+ }
+ }));
+ if (msg.contains("Address already in use")) {
+ println("Did you make sure that ports "+config.listenPort+" and "+config.listenSecurePort+" are not in use?");
+ }
+ if (msg.contains("Permission denied")) {
+ println("Perhaps you need to run as the root user or as an Administrator?");
+ }
+ }
+
+ var c: org.mortbay.jetty.Connector = null;
+
+ try {
+ c = nioconnector;
+ c.open();
+ if (sslconnector != null) {
+ c = sslconnector;
+ c.open();
+ }
+ c = null;
+ allHandlers.start();
+ server.start();
+ } catch {
+ case e: java.net.SocketException => {
+ socketError(c, e);
+ java.lang.Runtime.getRuntime().halt(1);
+ }
+ case e: org.mortbay.util.MultiException => {
+ println("SERVER ERROR: Couldn't start server; multiple errors.");
+ for (i <- new IterableWrapper[Throwable] { override val underlying = e.getThrowables.asInstanceOf[java.util.List[Throwable]] }) {
+ i match {
+ case se: java.net.SocketException => {
+ socketError(c, se);
+ }
+ case e =>
+ println("SERVER ERROR: Couldn't start server: "+i.getMessage());
+ }
+ }
+ java.lang.Runtime.getRuntime().halt(1);
+ }
+ case e => {
+ println("SERVER ERROR: Couldn't start server: "+e.getMessage());
+ java.lang.Runtime.getRuntime().halt(1);
+ }
+ }
+
+ println("HTTP server listening on http://"+
+ (if (config.listenHost.length > 0) config.listenHost else "localhost")+
+ ":"+config.listenPort+"/");
+ if (config.listenSecurePort > 0)
+ println("HTTPS server listening on https://"+
+ (if (config.listenSecureHost.length > 0) config.listenSecureHost else "localhost")+
+ ":"+config.listenSecurePort+"/");
+ if (config.listenSarsPort > 0)
+ println("SARS server listening on "+
+ (if (config.listenSarsHost.length > 0) config.listenSarsHost else "localhost")+
+ ":"+config.listenSarsPort);
+ }
+}
diff --git a/infrastructure/net.appjet.oui/monitoring.scala b/infrastructure/net.appjet.oui/monitoring.scala
new file mode 100644
index 0000000..e380b84
--- /dev/null
+++ b/infrastructure/net.appjet.oui/monitoring.scala
@@ -0,0 +1,125 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+object monitoring {
+
+ def startMonitoringServer() {
+ // remote JMX monitoring
+ // see: http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
+
+ import java.rmi.registry.LocateRegistry;
+ import java.lang.management.ManagementFactory;
+ import javax.management.ObjectName;
+ import javax.management.remote.{JMXServiceURL, JMXConnectorServerFactory};
+
+ def REGISTRY_PORT = config.listenMonitoringPrimaryPort;
+ def SECONDARY_PORT = config.listenMonitoringSecondaryPort;
+ System.setProperty("java.rmi.server.randomIDs", "true");
+
+ // we must set 'java.rmi.server.hostname' to the host that the client machine
+ // should connect to; in production, it will be the dashboard host, but the property
+ // can also be specified on the command-line, in which case it takes precedence.
+ var listenHost = config.listenMonitoringHost
+ if (listenHost == null || listenHost.length == 0) listenHost = "localhost";
+ if (System.getProperty("java.rmi.server.hostname") == null) {
+ System.setProperty("java.rmi.server.hostname", listenHost);
+ }
+ else {
+ listenHost = System.getProperty("java.rmi.server.hostname");
+ }
+
+ LocateRegistry.createRegistry(REGISTRY_PORT);
+ val mbs = ManagementFactory.getPlatformMBeanServer();
+
+ mbs.createMBean(classOf[JSExecutor].getName, new ObjectName("net.appjet:type=JSExecutor"));
+
+ val env = new java.util.HashMap[String,Object]();
+ //val csf = new javax.rmi.ssl.SslRMIClientSocketFactory();
+ //val ssf = new javax.rmi.ssl.SslRMIServerSocketFactory();
+ //env.put(javax.management.remote.rmi.RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
+ //env.put(javax.management.remote.rmi.RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
+ val PASSWORD_FILE_PATH = "data/jconsole-password.properties";
+ val ACCESS_FILE_PATH = "data/jconsole-access.properties";
+ def writeStringToFile(str: String, path: String) {
+ val out = new java.io.PrintStream(new java.io.BufferedOutputStream(
+ new java.io.FileOutputStream(path)));
+ out.println(str);
+ out.close;
+ }
+ if (! new java.io.File(PASSWORD_FILE_PATH).exists) {
+ System.err.println("Creating "+PASSWORD_FILE_PATH+"...");
+ writeStringToFile("appjet foo", PASSWORD_FILE_PATH);
+ }
+ if (! new java.io.File(ACCESS_FILE_PATH).exists) {
+ System.err.println("Creating "+ACCESS_FILE_PATH+"...");
+ writeStringToFile("appjet readwrite", ACCESS_FILE_PATH);
+ }
+ env.put("jmx.remote.x.password.file", PASSWORD_FILE_PATH);
+ env.put("jmx.remote.x.access.file", ACCESS_FILE_PATH);
+ val url = new JMXServiceURL(
+ "service:jmx:rmi://localhost:"+SECONDARY_PORT+"/jndi/rmi://localhost:"+REGISTRY_PORT+"/server");
+ try {
+ val cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ cs.start();
+ System.err.println("Monitor server listening on "+listenHost+":{"+REGISTRY_PORT+
+ ","+SECONDARY_PORT+"}");
+ }
+ catch {
+ case e => {
+ System.err.println("!!Could not start monitor server on "+listenHost+":{"+REGISTRY_PORT+
+ ","+SECONDARY_PORT+"} due to:");
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+}
+
+trait JSExecutorMXBean {
+ def executeJS(code: String): String;
+}
+
+class JSExecutor extends JSExecutorMXBean {
+ import org.mozilla.javascript.{Context,ContextFactory,ContextAction};
+ import org.mozilla.javascript.tools.ToolErrorReporter;
+ import org.mozilla.javascript.tools.shell.{Global, ShellContextFactory};
+
+ def executeJS(code: String): String = {
+ val outStream = new java.io.ByteArrayOutputStream;
+ val out = new java.io.PrintStream(outStream, true, "UTF-8");
+
+ val contextFactory = new ShellContextFactory;
+ try {
+ contextFactory.call(new ContextAction { def run(cx: Context): Object = {
+ val global = new Global(cx);
+ global.setOut(out);
+ global.setErr(out);
+ val errorReporter = new ToolErrorReporter(false, global.getErr);
+ val result = cx.evaluateString(global, code, "<script>", 1, null);
+ out.println(Context.toString(result));
+ null;
+ } });
+ }
+ catch {
+ case e => {
+ e.printStackTrace(out);
+ }
+ }
+ return new String(outStream.toByteArray, "UTF-8");
+ }
+}
diff --git a/infrastructure/net.appjet.oui/network.scala b/infrastructure/net.appjet.oui/network.scala
new file mode 100644
index 0000000..2965b19
--- /dev/null
+++ b/infrastructure/net.appjet.oui/network.scala
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.{SslSelectChannelConnector, SslHttpChannelEndPoint};
+import org.mortbay.io.nio.SelectorManager;
+import org.mortbay.io.Buffers;
+import javax.net.ssl.SSLEngine;
+
+import java.nio.channels.{SocketChannel, SelectionKey};
+
+trait KnowsAboutDispatch extends SelectChannelConnector.ConnectorEndPoint {
+ def isDispatched: Boolean;
+}
+
+class CometConnectorEndPoint(channel: SocketChannel, selectSet: SelectorManager#SelectSet, key: SelectionKey)
+ extends SelectChannelConnector.ConnectorEndPoint(channel, selectSet, key) with KnowsAboutDispatch {
+ def isDispatched = _dispatched;
+}
+
+class CometSelectChannelConnector extends SelectChannelConnector {
+ override def newEndPoint(channel: SocketChannel, selectSet: SelectorManager#SelectSet, key: SelectionKey) =
+ new CometConnectorEndPoint(channel, selectSet, key);
+}
+
+class CometSslHttpChannelEndPoint(buffers: Buffers, channel: SocketChannel, selectSet: SelectorManager#SelectSet,
+ key: SelectionKey, engine: SSLEngine)
+ extends SslHttpChannelEndPoint(buffers, channel, selectSet, key, engine) with KnowsAboutDispatch {
+ def isDispatched = _dispatched;
+}
+
+class CometSslSelectChannelConnector extends SslSelectChannelConnector {
+ override def newEndPoint(channel: SocketChannel, selectSet: SelectorManager#SelectSet, key: SelectionKey) =
+ new CometSslHttpChannelEndPoint(this, channel, selectSet, key, createSSLEngine());
+}
diff --git a/infrastructure/net.appjet.oui/servermodel.scala b/infrastructure/net.appjet.oui/servermodel.scala
new file mode 100644
index 0000000..1e2363f
--- /dev/null
+++ b/infrastructure/net.appjet.oui/servermodel.scala
@@ -0,0 +1,209 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import scala.collection.mutable.{HashSet, SynchronizedSet};
+import java.util.concurrent.ConcurrentHashMap;
+
+import net.appjet.bodylock.{BodyLock, JSCompileException};
+
+object ScopeReuseManager {
+ // reset handling.
+ // val filesToWatch = new ConcurrentHashMap[CachedFile, Unit];
+ // def watch(libs: DiskLibrary*) {
+ // for(lib <- libs) {
+ // filesToWatch.put(lib,());
+ // }
+ // }
+ val t = new java.util.TimerTask {
+ def run() {
+ try {
+ // val t1 = System.currentTimeMillis;
+ // var doReset = false;
+ // val libIter = filesToWatch.keySet.iterator;
+ // while (libIter.hasNext) {
+ // if (libIter.next.hasBeenModified) {
+ // doReset = true;
+ // }
+ // }
+ // val t2 = System.currentTimeMillis;
+ // val elapsedMs = (t2 -t1).toInt;
+ // if (elapsedMs >= 500) {
+ // eventlog(Map(
+ // "type" -> "event",
+ // "event" -> "scopereusefilewatcher-slowtask",
+ // "elapsedMs" -> elapsedMs
+ // ));
+ // }
+ if (FileCache.testFiles()) {
+ reset();
+ }
+ } catch {
+ case e => e.printStackTrace();
+ }
+ }
+ }
+ val timerPeriod = if (! config.devMode) 5000 else 500;
+ val timer = new java.util.Timer(true);
+ timer.schedule(t, timerPeriod, timerPeriod);
+
+ // scope handling
+ val mainLib = new VariableDiskLibrary("main.js");
+ val preambleLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "preamble.js"));
+ val postambleLib = new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "postamble.js"));
+ def mainExecutable = mainLib.executable;
+ def preambleExecutable = preambleLib.executable;
+ def postambleExecutable = postambleLib.executable;
+
+ val mainGlobalScope = BodyLock.newScope;
+
+ val nextId = new AtomicLong(0);
+ val freeRunners = new ConcurrentLinkedQueue[Runner]();
+ var lastReset = new AtomicLong(0);
+ val resetLock = new ReentrantReadWriteLock(true);
+ def readLocked[E](block: => E): E = {
+ resetLock.readLock().lock();
+ try {
+ block;
+ } finally {
+ resetLock.readLock().unlock();
+ }
+ }
+ def writeLocked[E](block: => E): E = {
+ resetLock.writeLock().lock();
+ try {
+ block;
+ } finally {
+ resetLock.writeLock().unlock();
+ }
+ }
+
+ case class Runner(val globalScope: org.mozilla.javascript.Scriptable) {
+ var count = 0;
+ val created = timekeeper.time;
+ val id = nextId.incrementAndGet();
+ val mainScope = BodyLock.subScope(globalScope);
+ var reuseOk = true;
+ var trace: Option[Array[StackTraceElement]] = None;
+ override def finalize() {
+ trace.foreach(t => eventlog(Map(
+ "type" -> "error",
+ "error" -> "unreleased runner",
+ "runnerId" -> id,
+ "trace" -> t.mkString("\n"))));
+ super.finalize();
+ }
+ val attributes = new scala.collection.mutable.HashMap[String, Object];
+ }
+
+ def newRunner = {
+ // watch(mainLib, preambleLib, postambleLib);
+ val startTime = System.currentTimeMillis();
+ val scope = BodyLock.subScope(mainGlobalScope);
+ val r = Runner(scope);
+ ExecutionContextUtils.withContext(ExecutionContext(null, null, r)) {
+// scope.put("_appjetcontext_", scope, );
+ preambleExecutable.execute(scope);
+ mainExecutable.execute(r.mainScope);
+ postambleExecutable.execute(scope);
+ val endTime = System.currentTimeMillis();
+ eventlog(Map(
+ "type" -> "event",
+ "event" -> "runner-created",
+ "latency" -> (endTime - startTime).toString(),
+ "runnerId" -> r.id));
+ }
+ r;
+ }
+
+ def getRunner = readLocked {
+ val runner = freeRunners.poll();
+ if (runner == null) {
+ newRunner;
+ } else {
+ if (config.devMode) {
+ runner.trace = Some(Thread.currentThread().getStackTrace());
+ }
+ runner;
+ }
+ }
+
+ def getEmpty(block: Runner => Unit): Runner = readLocked {
+ // watch(preambleLib, postambleLib);
+ val scope = BodyLock.newScope;
+ val r = Runner(scope);
+// scope.put("_appjetcontext_", scope, ExecutionContext(null, null, r));
+ ExecutionContextUtils.withContext(ExecutionContext(null, null, r)) {
+ preambleExecutable.execute(scope);
+ block(r);
+ postambleExecutable.execute(scope);
+ }
+ r;
+ }
+
+ def getEmpty: Runner = getEmpty(r => {});
+
+ def freeRunner(r: Runner) {
+ r.trace = None;
+ if (r.reuseOk && r.created > lastReset.get()) {
+ freeRunners.offer(r);
+ } else {
+ if (r.reuseOk) {
+ eventlog(Map(
+ "type" -> "event",
+ "event" -> "runner-discarded",
+ "runnerId" -> r.id));
+ } else {
+ eventlog(Map(
+ "type" -> "event",
+ "event" -> "runner-retired",
+ "runnerId" -> r.id));
+ }
+ }
+ }
+
+ lazy val resetExecutable = (new FixedDiskLibrary(new SpecialJarOrNotFile(config.ajstdlibHome, "onreset.js"))).executable;
+ def runOnReset() {
+ execution.runOutOfBand(resetExecutable, "Reset", None, { error =>
+ error match {
+ case e: JSCompileException => { }
+ case e: Throwable => { exceptionlog(e); }
+ case (sc: Int, msg: String) => { exceptionlog("Reset failed: "+msg); }
+ case x => exceptionlog("Reset failed: "+String.valueOf(x));
+ }
+ });
+ }
+
+ def reset() = writeLocked {
+ eventlog(Map(
+ "type" -> "event",
+ "event" -> "files-reset"));
+ // filesToWatch.clear();
+ lastReset.set(timekeeper.time);
+ freeRunners.clear();
+ runOnReset();
+ }
+
+ eventlog(Map(
+ "type" -> "event",
+ "event" -> "server-restart"));
+}
+
diff --git a/infrastructure/net.appjet.oui/stats.scala b/infrastructure/net.appjet.oui/stats.scala
new file mode 100644
index 0000000..075182f
--- /dev/null
+++ b/infrastructure/net.appjet.oui/stats.scala
@@ -0,0 +1,220 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import java.util.Date;
+
+import scala.collection.mutable.{HashMap, HashSet, Set, Map, ArrayBuffer};
+import scala.util.Sorting;
+
+trait BucketMap extends scala.collection.mutable.Map[int, BucketedLastHits] {
+ def t = 1000*60;
+ override def apply(s: int) = synchronized { getOrElseUpdate(s, new BucketedLastHits(t)) };
+ def counts = { val p = this; new scala.collection.Map.Projection[int, int] {
+ def size = p.size;
+ def get(s: int) = p.get(s).map(_.count);
+ def elements = p.elements.map(o => (o._1, o._2.count));
+ }};
+}
+
+abstract class BucketKeeper[A, B](val size: Long, val numbuckets: int, val noUpdate: Boolean) {
+ def this(size: Long, noUpdate: Boolean) =
+ this(size, Math.max(100, if (noUpdate) 1 else (size/60000).toInt), noUpdate)
+ def this(size: Long) = this(size, false);
+
+ val buckets = new Array[A](numbuckets);
+
+ val millisPerBucket = size/numbuckets;
+ var lastSwitch = System.currentTimeMillis();
+ var currentBucket = 0;
+
+ def withSyncUpdate[E](block: E): E = synchronized {
+ updateBuckets();
+ block;
+ }
+
+ protected def bucketAtTime(d: Date) = {
+ val msAgo = lastSwitch - d.getTime();
+ val bucketsAgo = Math.floor(msAgo/millisPerBucket).asInstanceOf[Int];
+ if (bucketsAgo < numbuckets) {
+ val bucket = (currentBucket - bucketsAgo + numbuckets) % numbuckets
+ // println("Applying to old bucket: "+bucket+" / current: "+currentBucket+", old count: "+count);
+ Some(bucket);
+ } else {
+ // println("No bucket found for: "+d);
+ None;
+ }
+ }
+
+ protected def updateBuckets(): Unit = {
+ if (! noUpdate) {
+ val now = System.currentTimeMillis();
+ while (now > lastSwitch + millisPerBucket) {
+ lastSwitch += millisPerBucket;
+ currentBucket = (currentBucket + 1) % numbuckets;
+ bucketClear(currentBucket);
+ }
+ }
+ }
+
+ protected def bucketClear(index: Int);
+ protected def bucketsInOrder: Seq[A] =
+ buckets.slice((currentBucket+1)%numbuckets, numbuckets) ++
+ buckets.slice(0, currentBucket)
+
+ def mergeBuckets(b: Seq[A]): B;
+
+ def history(bucketsPerSample: Int, numSamples: Int): Array[B] = withSyncUpdate {
+ val bseq = bucketsInOrder.reverse.take(bucketsPerSample*numSamples);
+ val sampleCount = Math.min(numSamples, bseq.length);
+ val samples =
+ for (i <- 0 until sampleCount) yield {
+ mergeBuckets(bseq.slice(i*bucketsPerSample, (i+1)*bucketsPerSample));
+ }
+ samples.reverse.toArray;
+ }
+ def latest(bucketsPerSample: Int): B = history(bucketsPerSample, 1)(0);
+ def count: B = withSyncUpdate { mergeBuckets(buckets); }
+
+ for (i <- 0 until numbuckets) {
+ bucketClear(i);
+ }
+}
+
+class BucketedUniques(size: Long, noUpdate: Boolean)
+extends BucketKeeper[Set[Any], Int](size, noUpdate) {
+ def this(size: Long) = this(size, false);
+
+ override protected def bucketClear(index: Int): Unit = {
+ buckets(index) = new HashSet[Any];
+ }
+
+ override def mergeBuckets(b: Seq[Set[Any]]) = {
+ b.foldLeft(scala.collection.immutable.Set[Any]())(_ ++ _).size;
+ }
+
+ def hit(d: Date, value: Any): Unit = withSyncUpdate {
+ for (bucket <- bucketAtTime(d)) {
+ buckets(bucket) += value;
+ }
+ }
+}
+
+class BucketedValueCounts(size: Long, noUpdate: Boolean)
+extends BucketKeeper[HashMap[String, Int], (Int, Map[String, Int])](size, noUpdate) {
+ def this(size: Long) = this(size, false);
+
+ override protected def bucketClear(index: Int): Unit = {
+ buckets(index) = new HashMap[String, Int];
+ }
+
+ override def mergeBuckets(b: Seq[HashMap[String, Int]]) = {
+ val out = new HashMap[String, Int];
+ var total = 0;
+ for (m <- b) {
+ for ((k, v) <- m) {
+ out(k) = out.getOrElse(k, 0) + v;
+ total += v;
+ }
+ }
+ (total, out);
+ }
+
+ def hit(d: Date, value: String, increment: Int): Unit = withSyncUpdate {
+ for (bucket <- bucketAtTime(d)) {
+ buckets(bucket)(value) =
+ buckets(bucket).getOrElse(value, 0)+increment;
+ }
+ }
+
+ def hit(d: Date, value: String): Unit = hit(d, value, 1);
+}
+
+
+/**
+ * Keeps track of how many "hits" in the last size milliseconds.
+ * Has granularity speicified by numbuckets.
+ */
+class BucketedLastHits(size: Long, noUpdate: Boolean)
+extends BucketKeeper[Int, Int](size, noUpdate) {
+ def this(size: Long) = this(size, false);
+
+ override protected def bucketClear(index: int): Unit = {
+ buckets(index) = 0;
+ }
+
+ override def mergeBuckets(b: Seq[Int]) = {
+ b.foldRight(0)(_+_);
+ }
+
+ def hit(d: Date): Unit = hit(d, 1);
+ def hit(d: Date, n: Int): Unit = withSyncUpdate {
+ for (bucket <- bucketAtTime(d)) {
+ buckets(bucket) = buckets(bucket) + n;
+ }
+ }
+}
+
+class BucketedLastHitsHistogram(size: Long, noUpdate: Boolean)
+extends BucketKeeper[ArrayBuffer[Int], Function1[Float, Int]](size, noUpdate) {
+ def this(size: Long) = this(size, false);
+
+ override protected def bucketClear(index: Int): Unit = {
+ buckets(index) = new ArrayBuffer[Int];
+ }
+
+ // elements will end up sorted.
+ protected def histogramFunction(elements: Array[Int]): Function1[Float, Int] = {
+ Sorting.quickSort(elements);
+ (percentile: Float) => {
+ if (elements.length == 0) {
+ 0
+ } else {
+ elements(
+ Math.round(percentile/100.0f*(elements.length-1)));
+ }
+ }
+ }
+
+ override def mergeBuckets(b: Seq[ArrayBuffer[Int]]) = {
+ val elements = new Array[Int](b.foldRight(0)(_.size + _));
+ var currentIndex = 0;
+ for (bucket <- b if bucket.length > 0) {
+ // copyToArray is broken through scala 2.7.5, fixed in trunk.
+ // bucket.copyToArray(allElements, currentIndex);
+ val bucketArray = bucket.toArray;
+ System.arraycopy(bucketArray, 0, elements, currentIndex, bucketArray.length);
+ currentIndex += bucket.size
+ }
+ histogramFunction(elements);
+ }
+
+ def hit(d: Date): Unit = hit(d, 1);
+ def hit(d: Date, n: Int): Unit = withSyncUpdate {
+ for (bucket <- bucketAtTime(d)) {
+ buckets(bucket) += n;
+ }
+ }
+}
+
+object appstats {
+ val minutelyStatus = new HashMap[int, BucketedLastHits] with BucketMap;
+ val hourlyStatus = new HashMap[int, BucketedLastHits] with BucketMap { override val t = 1000*60*60 };
+ val dailyStatus = new HashMap[int, BucketedLastHits] with BucketMap { override val t = 1000*60*60*24 };
+ val weeklyStatus = new HashMap[int, BucketedLastHits] with BucketMap { override val t = 1000*60*60*24*7 };
+ val stati = Array(minutelyStatus, hourlyStatus, dailyStatus, weeklyStatus);
+}
diff --git a/infrastructure/net.appjet.oui/synchronizer.scala b/infrastructure/net.appjet.oui/synchronizer.scala
new file mode 100644
index 0000000..2a6d9c1
--- /dev/null
+++ b/infrastructure/net.appjet.oui/synchronizer.scala
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+class Synchronizer {
+ import java.util.concurrent.locks.ReentrantLock;
+ import java.util.concurrent.ConcurrentHashMap;
+
+ private val lockMap = new ConcurrentHashMap[Object, Lock];
+ private val monitor = new Object {};
+
+ private class Lock {
+ var users = 0;
+ val impl = new ReentrantLock;
+ }
+
+ def acquire(key: Object) {
+ val lock = monitor.synchronized {
+ var lck = lockMap.get(key);
+ if (lck == null) {
+ lck = new Lock;
+ lockMap.put(key, lck);
+ }
+ lck.users += 1;
+ lck;
+ }
+ lock.impl.lock();
+ }
+
+ def isHeld(key: Object): Boolean = {
+ monitor.synchronized {
+ val lck = lockMap.get(key);
+ if (lck == null) {
+ false;
+ }
+ else {
+ lck.impl.isLocked;
+ }
+ }
+ }
+
+ def release(key: Object) {
+ val lock = monitor.synchronized {
+ var lck = lockMap.get(key);
+ lck.users -= 1;
+ if (lck.users == 0) {
+ lockMap.remove(key);
+ }
+ lck;
+ }
+ lock.impl.unlock();
+ }
+}
+
+object GlobalSynchronizer extends Synchronizer;
diff --git a/infrastructure/net.appjet.oui/util.scala b/infrastructure/net.appjet.oui/util.scala
new file mode 100644
index 0000000..ba8a736
--- /dev/null
+++ b/infrastructure/net.appjet.oui/util.scala
@@ -0,0 +1,153 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.appjet.oui;
+
+import scala.collection.mutable.HashMap;
+
+import java.util.Enumeration;
+import java.util.zip.GZIPOutputStream;
+import java.io.ByteArrayOutputStream;
+
+object Util {
+ def noCacheHeaders =
+ Map("Expires" -> "Sat, 5 Feb 1983 07:07:07 GMT",
+ "Last-Modified" -> (new java.util.Date()).toGMTString(),
+ "Cache-Control" -> "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0",
+ "Pragma" -> "no-cache");
+
+
+ class RichEnumeration[T](enumeration: Enumeration[T]) extends Iterator[T] {
+ def hasNext: Boolean = enumeration.hasMoreElements();
+ def next: T = enumeration.nextElement();
+ }
+ class RichIterator[T](iterator: java.util.Iterator[T]) extends Iterator[T] {
+ def hasNext: Boolean = iterator.hasNext();
+ def next: T = iterator.next();
+ }
+ implicit def enumerationToRichEnumeration[T](
+ enumeration: Enumeration[T]): RichEnumeration[T] = {
+ new RichEnumeration(enumeration)
+ }
+ implicit def iteratorToRichIterator[T](
+ iterator: java.util.Iterator[T]): RichIterator[T] = {
+ new RichIterator(iterator);
+ }
+
+ def enumerationToArray[T](e: Enumeration[T]): Array[T] =
+ enumerationToRichEnumeration(e).toList.toArray;
+
+ def stringToHTML(str: String): String = {
+ val result = new StringBuilder(str.length);
+ var lastCharBlank = false;
+ for(i <- 0 until str.length) {
+ val c = str.charAt(i);
+ if (c == ' ') {
+ // every second consecutive space becomes a &nbsp;
+ if (lastCharBlank) {
+ lastCharBlank = false;
+ result.append("&nbsp;");
+ }
+ else {
+ lastCharBlank = true;
+ result.append(' ');
+ }
+ } else {
+ lastCharBlank = false;
+ if (c == '&') result.append("&amp;");
+ else if (c == '<') result.append("&lt;");
+ else if (c == '>') result.append("&gt;");
+ else if (c == '\n') result.append("<br/>\n");
+ else if (c == '\t') {
+ for(j <- 1 to 7) {
+ result.append("&nbsp;");
+ }
+ result.append(' ');
+ }
+ else {
+ val code = c.toInt;
+ if (code < 127) {
+ result.append(c);
+ }
+ else {
+ // use character code
+ result.append("&#");
+ result.append(code);
+ result.append(';');
+ }
+ }
+ }
+ }
+ return result.toString;
+ }
+
+ def gzip(bytes: Array[Byte]): Array[Byte] = {
+ val baos = new ByteArrayOutputStream();
+ val gzos = new GZIPOutputStream(baos);
+ gzos.write(bytes, 0, bytes.length);
+ gzos.close();
+ baos.toByteArray();
+ }
+}
+
+object timekeeper {
+ var timestamp: Long = 0;
+ def time: Long = {
+ val t = System.currentTimeMillis();
+ synchronized {
+ if (t <= timestamp) {
+ timestamp += 1
+ } else {
+ timestamp = t
+ }
+ timestamp
+ }
+ }
+ def update(t: Long) = synchronized {
+ if (t > timestamp)
+ timestamp = t+1;
+ }
+}
+
+trait LoggingHandler extends org.mortbay.jetty.handler.AbstractHandler {
+ abstract override def handle(target: String, req: javax.servlet.http.HttpServletRequest, res: javax.servlet.http.HttpServletResponse, dispatch: Int) {
+ println("all ("+isStarted+") handling: "+(this match {
+ case hc: org.mortbay.jetty.handler.HandlerCollection => hc.getHandlers.mkString(", ");
+ case ahc: org.mortbay.jetty.handler.AbstractHandlerContainer => ahc.getChildHandlers.mkString(", ");
+ case x => "(unknown)";
+ }));
+ super.handle(target, req, res, dispatch);
+ }
+ override def doStart() {
+ println("all started.");
+ // Thread.dumpStack();
+ try {
+ super.doStart();
+ } catch {
+ case e: Exception => {
+ e.printStackTrace();
+ throw e;
+ }
+ } finally {
+ println("and: "+isStarted);
+ }
+ }
+ override def doStop() {
+ println("all stopped.");
+ // Thread.dumpStack();
+ super.doStop();
+ }
+}
diff --git a/infrastructure/rhino1_7R1/apiClasses.properties b/infrastructure/rhino1_7R1/apiClasses.properties
new file mode 100644
index 0000000..d116ee4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/apiClasses.properties
@@ -0,0 +1,65 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+apiClasses=\
+ src/org/mozilla/javascript/Callable.java,\
+ src/org/mozilla/javascript/ClassCache.java,\
+ src/org/mozilla/javascript/ClassShutter.java,\
+ src/org/mozilla/javascript/CompilerEnvirons.java,\
+ src/org/mozilla/javascript/Context.java,\
+ src/org/mozilla/javascript/ContextAction.java,\
+ src/org/mozilla/javascript/ContextFactory.java,\
+ src/org/mozilla/javascript/GeneratedClassLoader.java,\
+ src/org/mozilla/javascript/EcmaError.java,\
+ src/org/mozilla/javascript/ErrorReporter.java,\
+ src/org/mozilla/javascript/EvaluatorException.java,\
+ src/org/mozilla/javascript/Function.java,\
+ src/org/mozilla/javascript/FunctionObject.java,\
+ src/org/mozilla/javascript/GeneratedClassLoader.java,\
+ src/org/mozilla/javascript/ImporterTopLevel.java,\
+ src/org/mozilla/javascript/JavaScriptException.java,\
+ src/org/mozilla/javascript/RefCallable.java,\
+ src/org/mozilla/javascript/RhinoException.java,\
+ src/org/mozilla/javascript/Script.java,\
+ src/org/mozilla/javascript/Scriptable.java,\
+ src/org/mozilla/javascript/ScriptableObject.java,\
+ src/org/mozilla/javascript/SecurityController.java,\
+ src/org/mozilla/javascript/WrapFactory.java,\
+ src/org/mozilla/javascript/WrappedException.java,\
+ src/org/mozilla/javascript/Wrapper.java,\
+ src/org/mozilla/javascript/Synchronizer.java,\
+ src/org/mozilla/javascript/optimizer/ClassCompiler.java,\
+ src/org/mozilla/javascript/debug/DebuggableScript.java,\
+ src/org/mozilla/javascript/serialize/ScriptableInputStream.java,\
+ src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
diff --git a/infrastructure/rhino1_7R1/build-date b/infrastructure/rhino1_7R1/build-date
new file mode 100644
index 0000000..e6132e5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/build-date
@@ -0,0 +1 @@
+This version was built on March 6 2008.
diff --git a/infrastructure/rhino1_7R1/build.properties b/infrastructure/rhino1_7R1/build.properties
new file mode 100644
index 0000000..4477ee0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/build.properties
@@ -0,0 +1,65 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released
+# May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Igor Bukanov
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+name: rhino
+Name: Rhino
+version: 1_7R1
+# See Context#getImplementationVersion() for format of this!
+implementation.version: Rhino 1.7 release 1 ${implementation.date}
+
+build.dir: build
+rhino.jar: js.jar
+small-rhino.jar: smalljs.jar
+rhino-14.jar: js-14.jar
+small-rhino-14.jar: smalljs-14.jar
+dist.name: rhino${version}
+dist.dir: ${build.dir}/${dist.name}
+
+# compilation destionation
+classes: ${build.dir}/classes
+
+# compilation settings
+debug: on
+target-jvm: 1.5
+source-level: 1.5
+
+# jar generation settings
+jar-compression: true
+
+# optional external packages
+xmlbeans: .
+xbean.jar: ${xmlbeans}/lib/xbean.jar
+jsr173.jar: ${xmlbeans}/lib/jsr173_1.0_api.jar
diff --git a/infrastructure/rhino1_7R1/build.xml b/infrastructure/rhino1_7R1/build.xml
new file mode 100644
index 0000000..fabbffa
--- /dev/null
+++ b/infrastructure/rhino1_7R1/build.xml
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<!--
+ Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
+ Requires Ant version 1.2 or later
+
+ Compilation currently requires JDK 1.5 or later. Can cross-compile to
+ support JDK 1.4.
+-->
+
+<project name="Rhino" default="help" basedir=".">
+
+ <target name="properties">
+ <!-- Allow user to override default settings from build.properties -->
+ <property file="build.local.properties" />
+ <tstamp>
+ <!-- Specify date part of Context#getImplementationVersion() -->
+ <format property="implementation.date" pattern="yyyy MM dd"/>
+ </tstamp>
+ <property file="build.properties"/>
+
+ <property name="dist.file" value="rhino${version}.zip"/>
+ <property name="dist.source-only-zip" value="rhino${version}-sources.zip"/>
+
+ <property file="apiClasses.properties"/>
+ <property name="xmlimplsrc-build-file"
+ location="xmlimplsrc/build.xml"/>
+
+ <available property="xmlimplsrc-present?"
+ file="${xmlimplsrc-build-file}" />
+
+ </target>
+
+ <target name="init" depends="properties">
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${classes}"/>
+ <mkdir dir="${dist.dir}"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <ant antfile="src/build.xml" target="compile"/>
+ <ant antfile="toolsrc/build.xml" target="compile"/>
+ <antcall target="xmlimplsrc-compile" />
+ </target>
+
+ <target name="compile-all" depends="compile">
+ <ant antfile="deprecatedsrc/build.xml" target="compile"/>
+ </target>
+
+ <target name="copy-source" depends="init">
+ <ant antfile="src/build.xml" target="copy-source"/>
+ <ant antfile="toolsrc/build.xml" target="copy-source"/>
+ <ant antfile="testsrc/build.xml" target="copy-source"/>
+ <antcall target="xmlimplsrc-copy-source" />
+ <ant antfile="deprecatedsrc/build.xml" target="copy-source"/>
+ <copy todir="${dist.dir}" file="build.xml"/>
+ <copy todir="${dist.dir}" file="build.properties"/>
+ <copy todir="${dist.dir}" file="apiClasses.properties"/>
+ </target>
+
+ <target name="xmlimplsrc-compile" if="xmlimplsrc-present?">
+ <echo>Calling ${xmlimplsrc-build-file}</echo>
+ <!-- Ignore compilation errors under JDK less then 1.4 -->
+ <property name="xmlimpl.compile.failonerror" value="no"/>
+ <ant antfile="${xmlimplsrc-build-file}" target="compile"/>
+ </target>
+
+ <target name="xmlimplsrc-copy-source" if="xmlimplsrc-present?">
+ <echo>Calling ${xmlimplsrc-build-file}</echo>
+ <ant antfile="${xmlimplsrc-build-file}" target="copy-source"/>
+ </target>
+
+ <target name="jar" depends="compile-all">
+ <property name="jarfile" location="${dist.dir}/${rhino.jar}"/>
+ <jar jarfile="${jarfile}"
+ basedir="${classes}"
+ manifest="src/manifest"
+ compress="${jar-compression}"
+ />
+ </target>
+
+ <target name="retrotranslator" depends="retrotranslator-check,retrotranslator-download">
+ <taskdef name="retrotranslator" classpath="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"
+ classname="net.sf.retrotranslator.transformer.RetrotranslatorTask"/>
+ </target>
+
+
+ <target name="retrotranslator-check">
+ <condition property="retrotranslator.available">
+ <and>
+ <available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"/>
+ <available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-runtime-1.2.3.jar"/>
+ <available file="build/download/Retrotranslator-1.2.3-bin/backport-util-concurrent-3.1.jar"/>
+ </and>
+ </condition>
+ </target>
+
+ <target name="retrotranslator-download" unless="retrotranslator.available">
+ <mkdir dir="build/download"/>
+ <get src="http://downloads.sourceforge.net/retrotranslator/Retrotranslator-1.2.3-bin.zip" dest="build/download/Retrotranslator-1.2.3-bin.zip" usetimestamp="true"/>
+ <unzip src="build/download/Retrotranslator-1.2.3-bin.zip" dest="build/download"/>
+ </target>
+
+ <target name="retrojar" depends="jar,retrotranslator">
+ <retrotranslator
+ srcjar="${jarfile}"
+ destjar="${dist.dir}/${rhino-14.jar}"
+ embed="org.mozilla.javascript"
+ />
+ </target>
+
+ <target name="smalljar" depends="compile">
+ <property name="smalljarfile" location="${dist.dir}/${small-rhino.jar}"/>
+ <jar basedir="${classes}" destfile="${smalljarfile}"
+ compress="${jar-compression}">
+ <include name="org/mozilla/javascript/*.class"/>
+
+ <include name="org/mozilla/javascript/debug/*.class"/>
+ <include name="org/mozilla/javascript/resources/*.properties"/>
+ <include name="org/mozilla/javascript/xml/*.class"/>
+ <include name="org/mozilla/javascript/continuations/*.class"/>
+ <include name="org/mozilla/javascript/jdk13/*.class"/>
+
+ <!-- exclude classes that defines only int constants -->
+ <exclude name="org/mozilla/javascript/Token.class"/>
+
+ <!-- exclude classes that uses class generation library -->
+ <exclude name="org/mozilla/javascript/JavaAdapter*.class"/>
+
+ <include name="org/mozilla/javascript/regexp/*.class"
+ unless="no-regexp"/>
+ </jar>
+
+ </target>
+
+ <target name="retrosmalljar" depends="smalljar,retrotranslator">
+ <retrotranslator
+ srcjar="${smalljarfile}"
+ destjar="${dist.dir}/${small-rhino-14.jar}"
+ embed="org.mozilla.javascript"
+ />
+ </target>
+
+ <target name="copy-examples" depends="init">
+ <mkdir dir="${dist.dir}/examples"/>
+ <copy todir="${dist.dir}/examples">
+ <fileset dir="examples" includes="**/*.java,**/*.js,**/*.html" />
+ </copy>
+ </target>
+
+ <target name="copy-misc" depends="init">
+ <filter token="datestamp" value="${TODAY}"/>
+ <copy todir="${dist.dir}" filtering="yes">
+ <fileset dir=".">
+ <patternset>
+ <include name="build-date"/>
+ </patternset>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="copy-all" depends="copy-source,copy-examples,copy-misc">
+ </target>
+
+ <target name="javadoc" depends="init">
+ <mkdir dir="${dist.dir}/javadoc"/>
+ <javadoc sourcefiles="${apiClasses}"
+ sourcepath="src"
+ destdir="${dist.dir}/javadoc"
+ version="true"
+ author="true"
+ windowtitle="${Name}" />
+ </target>
+
+ <target name="dist" depends="deepclean,jar,retrojar,copy-all,javadoc">
+ <delete file="${dist.file}" />
+ <zip destfile="${dist.file}">
+ <fileset dir="${build.dir}" includes="${dist.name}/**"/>
+ </zip>
+ </target>
+
+ <target name="source-zip" depends="copy-source,copy-examples,javadoc">
+ <delete file="${dist.source-only-zip}" />
+ <zip destfile="${dist.source-only-zip}">
+ <zipfileset prefix="${dist.name}" dir="${dist.dir}">
+ <include name="*src/**"/>
+ <include name="build.xml"/>
+ <include name="*.properties"/>
+ <include name="examples/**"/>
+ </zipfileset>
+ </zip>
+ </target>
+
+ <target name="compile-debugger">
+ <ant antfile="toolsrc/build.xml" target="compile-debugger"/>
+ </target>
+
+ <target name="clean" depends="properties">
+ <delete quiet="true" file="${dist.dir}/${rhino.jar}"/>
+ <delete quiet="true" file="${dist.dir}/${small-rhino.jar}"/>
+ <delete quiet="true" dir="${build.dir}"/>
+ </target>
+
+ <target name="deepclean" depends="properties">
+ <delete quiet="true" dir="${build.dir}"/>
+ <delete quiet="true" file="${dist.file}"/>
+ <delete quiet="true" file="${dist.source-only-zip}"/>
+ </target>
+
+ <!--
+ The next two targets run the JavaScript Test Library tests. Note that these tests are quite extensive and take a long time
+ to run. They are not documented in the 'help' target for now.
+ -->
+
+ <!--
+ Run the tests using JUnit. Beware that if you are using Ant from the command-line, there are some difficulties you may
+ encounter setting this up correctly; see http://ant.apache.org/faq.html#delegating-classloader
+
+ IDEs that use Ant as the build system probably handle this fine.
+ -->
+ <target name="junit-all" depends="compile">
+ <ant antfile="testsrc/build.xml" target="junit-coveragereport"/>
+ </target>
+
+ <!--
+ Run the tests using the Java port of jsdriver.pl. Note that running this port
+ from the command-line may be more useful running this Ant target, as running
+ from the command line allows configuration options, such as running with a
+ non-default optimization level, or running only a subset of the tests.
+ -->
+ <target name="jsdriver-run" depends="compile">
+ <ant antfile="testsrc/build.xml" target="jsdriver" />
+ </target>
+
+ <!--
+ Compile the JsDriver test driver.
+ -->
+ <target name="jsdriver" depends="compile">
+ <ant antfile="testsrc/build.xml" target="clean" />
+ <ant antfile="testsrc/build.xml" target="compile" />
+ </target>
+
+ <target name="help" depends="properties">
+<echo>The following targets are available with this build file:
+
+ clean remove all compiled classes and copied property files
+
+ compile compile classes and copy all property files
+ into ${classes} directory
+ excluding deprecated code
+
+ compile-all compile all classes and copy all property files
+ into ${classes} directory
+ including deprecated code
+
+ deepclean remove all generated files and directories
+
+ dist create ${dist.file} with full Rhino distribution
+
+ help print this help
+
+ jar create ${rhino.jar} in ${dist.dir}
+
+ smalljar create ${small-rhino.jar} in ${dist.dir} with
+ minimalist set of Rhino classes. See footprint.html
+ from the doc directory for details.
+
+ javadoc generate Rhino API documentation
+ in ${dist.dir}/javadoc
+
+ source-zip create ${dist.source-only-zip} with all Rhino
+ source files necessary to recreate ${dist.file}
+</echo>
+ </target>
+
+</project>
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/build.xml b/infrastructure/rhino1_7R1/deprecatedsrc/build.xml
new file mode 100644
index 0000000..4250fcf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/build.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<project name="src" default="compile" basedir="..">
+
+ <property file="build.properties"/>
+
+ <target name="compile">
+ <javac srcdir="deprecatedsrc"
+ destdir="${classes}"
+ includes="org/mozilla/javascript/*.java"
+ deprecation="on"
+ debug="${debug}"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ </javac>
+ </target>
+
+ <target name="copy-source">
+ <mkdir dir="${dist.dir}/deprecatedsrc"/>
+ <copy todir="${dist.dir}/deprecatedsrc">
+ <fileset dir="deprecatedsrc"
+ includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
+ </copy>
+ </target>
+
+</project>
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/ClassDefinitionException.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/ClassDefinitionException.java
new file mode 100644
index 0000000..2197063
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/ClassDefinitionException.java
@@ -0,0 +1,53 @@
+
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * @deprecated The exception is no longer thrown by Rhino runtime as
+ * {@link EvaluatorException} is used instead.
+ */
+public class ClassDefinitionException extends RuntimeException
+{
+ static final long serialVersionUID = -5637830967241712746L;
+
+ public ClassDefinitionException(String detail) {
+ super(detail);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/NotAFunctionException.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/NotAFunctionException.java
new file mode 100644
index 0000000..3de53a8
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/NotAFunctionException.java
@@ -0,0 +1,52 @@
+
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * @deprecated The exception is no longer thrown by Rhino runtime as
+ * {@link EvaluatorException} is used instead.
+ */
+public class NotAFunctionException extends RuntimeException
+{
+ static final long serialVersionUID = 6461524852170711724L;
+
+ public NotAFunctionException() { }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/PropertyException.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/PropertyException.java
new file mode 100644
index 0000000..8d786c7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/PropertyException.java
@@ -0,0 +1,54 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * @deprecated This exception is no longer thrown by Rhino runtime.
+ */
+public class PropertyException extends RuntimeException
+{
+ static final long serialVersionUID = -8221564865490676219L;
+
+ public PropertyException(String detail) {
+ super(detail);
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.java
new file mode 100644
index 0000000..b525aff
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/LogicalEquality.java
@@ -0,0 +1,367 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.apache.xmlbeans.XmlCursor;
+
+import java.util.*;
+
+
+public class LogicalEquality
+{
+ public static boolean nodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = false;
+
+ if (xmlOne.isStartdoc())
+ {
+ xmlOne.toFirstContentToken();
+ }
+
+ if (xmlTwo.isStartdoc())
+ {
+ xmlTwo.toFirstContentToken();
+ }
+
+ if (xmlOne.currentTokenType() == xmlTwo.currentTokenType())
+ {
+ if (xmlOne.isEnddoc())
+ {
+ // Both empty
+ result = true;
+ }
+ else if (xmlOne.isAttr())
+ {
+ result = attributesEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isText())
+ {
+ result = textNodesEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isComment())
+ {
+ result = commentsEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isProcinst())
+ {
+ result = processingInstructionsEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isStart())
+ {
+ // Compare root elements
+ result = elementsEqual(xmlOne, xmlTwo);
+ }
+ }
+
+ return result;
+ }
+
+ private static boolean elementsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = true;
+
+ if (!qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
+ {
+ result = false;
+ }
+ else
+ {
+ // These filter out empty text nodes.
+ nextToken(xmlOne);
+ nextToken(xmlTwo);
+
+ do
+ {
+ if (xmlOne.currentTokenType() != xmlTwo.currentTokenType())
+ {
+ // Not same token
+ result = false;
+ break;
+ }
+ else if (xmlOne.isEnd())
+ {
+ // Done with this element, step over end
+ break;
+ }
+ else if (xmlOne.isEnddoc())
+ {
+ // Shouldn't get here
+ break;
+ }
+ else if (xmlOne.isAttr())
+ {
+ // This one will move us to the first non-attr token.
+ result = attributeListsEqual(xmlOne, xmlTwo);
+ }
+ else
+ {
+ if (xmlOne.isText())
+ {
+ result = textNodesEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isComment())
+ {
+ result = commentsEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isProcinst())
+ {
+ result = processingInstructionsEqual(xmlOne, xmlTwo);
+ }
+ else if (xmlOne.isStart())
+ {
+ result = elementsEqual(xmlOne, xmlTwo);
+ }
+ else
+ {
+ //XML.log("Unknown token type" + xmlOne.currentTokenType());
+ }
+
+ // These filter out empty text nodes.
+ nextToken(xmlOne);
+ nextToken(xmlTwo);
+ }
+ }
+ while(result);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xmlOne
+ * @param xmlTwo
+ * @return
+ */
+ private static boolean attributeListsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = true;
+ TreeMap mapOne = loadAttributeMap(xmlOne);
+ TreeMap mapTwo = loadAttributeMap(xmlTwo);
+
+ if (mapOne.size() != mapTwo.size())
+ {
+ result = false;
+ }
+ else
+ {
+ Set keysOne = mapOne.keySet();
+ Set keysTwo = mapTwo.keySet();
+ Iterator itOne = keysOne.iterator();
+ Iterator itTwo = keysTwo.iterator();
+
+ while (result && itOne.hasNext())
+ {
+ String valueOne = (String) itOne.next();
+ String valueTwo = (String) itTwo.next();
+
+ if (!valueOne.equals(valueTwo))
+ {
+ result = false;
+ }
+ else
+ {
+ javax.xml.namespace.QName qnameOne = (javax.xml.namespace.QName) mapOne.get(valueOne);
+ javax.xml.namespace.QName qnameTwo = (javax.xml.namespace.QName) mapTwo.get(valueTwo);
+
+ if (!qnamesEqual(qnameOne, qnameTwo))
+ {
+ result = false;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ private static TreeMap loadAttributeMap(XmlCursor xml)
+ {
+ TreeMap result = new TreeMap();
+
+ while (xml.isAttr())
+ {
+ result.put(xml.getTextValue(), xml.getName());
+ nextToken(xml);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xmlOne
+ * @param xmlTwo
+ * @return
+ */
+ private static boolean attributesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = false;
+
+ if (xmlOne.isAttr() && xmlTwo.isAttr())
+ {
+ if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
+ {
+ if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
+ {
+ result = true;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xmlOne
+ * @param xmlTwo
+ * @return
+ */
+ private static boolean textNodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = false;
+
+ if (xmlOne.isText() && xmlTwo.isText())
+ {
+ if (xmlOne.getChars().equals(xmlTwo.getChars()))
+ {
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xmlOne
+ * @param xmlTwo
+ * @return
+ */
+ private static boolean commentsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = false;
+
+ if (xmlOne.isComment() && xmlTwo.isComment())
+ {
+ if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
+ {
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xmlOne
+ * @param xmlTwo
+ * @return
+ */
+ private static boolean processingInstructionsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
+ {
+ boolean result = false;
+
+ if (xmlOne.isProcinst() && xmlTwo.isProcinst())
+ {
+ if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
+ {
+ if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
+ {
+ result = true;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param qnameOne
+ * @param qnameTwo
+ * @return
+ */
+ private static boolean qnamesEqual(javax.xml.namespace.QName qnameOne, javax.xml.namespace.QName qnameTwo)
+ {
+ boolean result = false;
+
+ if (qnameOne.getNamespaceURI().equals(qnameTwo.getNamespaceURI()))
+ {
+ if (qnameOne.getLocalPart().equals(qnameTwo.getLocalPart()))
+ {
+ return true;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * filter out empty textNodes here
+ *
+ * @param xml
+ */
+ private static void nextToken(XmlCursor xml)
+ {
+ do
+ {
+ xml.toNextToken();
+
+ if (!xml.isText())
+ {
+ // Not a text node
+ break;
+ }
+ else if (xml.getChars().trim().length() > 0)
+ {
+ // Text node is not empty
+ break;
+ }
+ }
+ while (true);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.java
new file mode 100644
index 0000000..3a16320
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/Namespace.java
@@ -0,0 +1,335 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class Namespace
+ *
+ */
+class Namespace extends IdScriptableObject
+{
+ static final long serialVersionUID = -5765755238131301744L;
+
+ private static final Object NAMESPACE_TAG = new Object();
+
+ private XMLLibImpl lib;
+ private String prefix;
+ private String uri;
+
+ public Namespace(XMLLibImpl lib, String uri)
+ {
+ super(lib.globalScope(), lib.namespacePrototype);
+
+ if (uri == null)
+ throw new IllegalArgumentException();
+
+ this.lib = lib;
+ this.prefix = (uri.length() == 0) ? "" : null;
+ this.uri = uri;
+ }
+
+
+ public Namespace(XMLLibImpl lib, String prefix, String uri)
+ {
+ super(lib.globalScope(), lib.namespacePrototype);
+
+ if (uri == null)
+ throw new IllegalArgumentException();
+ if (uri.length() == 0) {
+ // prefix should be "" for empty uri
+ if (prefix == null)
+ throw new IllegalArgumentException();
+ if (prefix.length() != 0)
+ throw new IllegalArgumentException();
+ }
+
+ this.lib = lib;
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+
+ public void exportAsJSClass(boolean sealed)
+ {
+ exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String uri()
+ {
+ return uri;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String prefix()
+ {
+ return prefix;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String toString ()
+ {
+ return uri();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String toLocaleString ()
+ {
+ return toString();
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof Namespace)) return false;
+ return equals((Namespace)obj);
+ }
+
+ protected Object equivalentValues(Object value)
+ {
+ if (!(value instanceof Namespace)) return Scriptable.NOT_FOUND;
+ boolean result = equals((Namespace)value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ private boolean equals(Namespace n)
+ {
+ return uri().equals(n.uri());
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getClassName ()
+ {
+ return "Namespace";
+ }
+
+ /**
+ *
+ * @param hint
+ * @return
+ */
+ public Object getDefaultValue (Class hint)
+ {
+ return uri();
+ }
+
+// #string_id_map#
+ private static final int
+ Id_prefix = 1,
+ Id_uri = 2,
+ MAX_INSTANCE_ID = 2;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2004-07-20 19:50:50 CEST
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==3) { X="uri";id=Id_uri; }
+ else if (s_length==6) { X="prefix";id=Id_prefix; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_prefix:
+ case Id_uri:
+ attr = PERMANENT | READONLY;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_prefix: return "prefix";
+ case Id_uri: return "uri";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_prefix:
+ if (prefix == null) return Undefined.instance;
+ return prefix;
+ case Id_uri:
+ return uri;
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+
+// #string_id_map#
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2004-08-21 12:07:01 CEST
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=2; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(NAMESPACE_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f,
+ Context cx,
+ Scriptable scope,
+ Scriptable thisObj,
+ Object[] args)
+ {
+ if (!f.hasTag(NAMESPACE_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return jsConstructor(cx, (thisObj == null), args);
+ case Id_toString:
+ return realThis(thisObj, f).toString();
+ case Id_toSource:
+ return realThis(thisObj, f).js_toSource();
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private Namespace realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if(!(thisObj instanceof Namespace))
+ throw incompatibleCallError(f);
+ return (Namespace)thisObj;
+ }
+
+ private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
+ {
+ if (!inNewExpr && args.length == 1) {
+ return lib.castToNamespace(cx, args[0]);
+ }
+
+ if (args.length == 0) {
+ return lib.constructNamespace(cx);
+ } else if (args.length == 1) {
+ return lib.constructNamespace(cx, args[0]);
+ } else {
+ return lib.constructNamespace(cx, args[0], args[1]);
+ }
+ }
+
+ private String js_toSource()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ toSourceImpl(prefix, uri, sb);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ static void toSourceImpl(String prefix, String uri, StringBuffer sb)
+ {
+ sb.append("new Namespace(");
+ if (uri.length() == 0) {
+ if (!"".equals(prefix)) throw new IllegalArgumentException(prefix);
+ } else {
+ sb.append('\'');
+ if (prefix != null) {
+ sb.append(ScriptRuntime.escapeString(prefix, '\''));
+ sb.append("', '");
+ }
+ sb.append(ScriptRuntime.escapeString(uri, '\''));
+ sb.append('\'');
+ }
+ sb.append(')');
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.java
new file mode 100644
index 0000000..fc99c7e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/NamespaceHelper.java
@@ -0,0 +1,350 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import java.util.*;
+import org.apache.xmlbeans.XmlCursor;
+
+import org.mozilla.javascript.*;
+
+class NamespaceHelper
+{
+ private XMLLibImpl lib;
+ private final Map prefixToURI = new HashMap();
+ private final Map uriToPrefix = new HashMap();
+ // A set of URIs that are used without explicit namespace declaration in scope.
+ private final Set undeclared = new HashSet();
+
+ private NamespaceHelper(XMLLibImpl lib)
+ {
+ this.lib = lib;
+ // Insert the default namespace
+ prefixToURI.put("", "");
+ Set prefixes = new HashSet();
+ prefixes.add("");
+ uriToPrefix.put("", prefixes);
+ }
+
+ /**
+ * Declared a new namespace
+ *
+ * @param prefix
+ * @param uri
+ * @param declarations
+ */
+ private void declareNamespace(String prefix, String uri, ObjArray declarations)
+ {
+ Set prefixes = (Set)uriToPrefix.get(uri);
+ if(prefixes == null)
+ {
+ prefixes = new HashSet();
+ uriToPrefix.put(uri, prefixes);
+ }
+
+ if(!prefixes.contains(prefix))
+ {
+ String oldURI = (String)prefixToURI.get(prefix);
+
+ // Add the new mapping
+ prefixes.add(prefix);
+ prefixToURI.put(prefix, uri);
+ if(declarations != null)
+ declarations.add(new Namespace(lib, prefix, uri));
+
+ if(oldURI != null)
+ {
+ // Update the existing mapping
+ prefixes = (Set)uriToPrefix.get(oldURI);
+ prefixes.remove(prefix);
+ }
+ }
+ }
+
+ /**
+ * Updates the internal state of this NamespaceHelper to reflect the
+ * existance of the XML token pointed to by the cursor.
+ */
+ private void processName(XmlCursor cursor, ObjArray declarations)
+ {
+ javax.xml.namespace.QName qname = cursor.getName();
+ String uri = qname.getNamespaceURI();
+ Set prefixes = (Set)uriToPrefix.get(uri);
+ if(prefixes == null || prefixes.size() == 0)
+ {
+ undeclared.add(uri);
+ if(declarations != null)
+ declarations.add(new Namespace(lib, uri));
+ }
+ }
+
+ /**
+ * Updates the internal state of this NamespaceHelper with the
+ * namespace information of the element pointed to by the cursor.
+ */
+ private void update(XmlCursor cursor, ObjArray declarations)
+ {
+ // Process the Namespace declarations
+ cursor.push();
+ while(cursor.toNextToken().isAnyAttr())
+ {
+ if(cursor.isNamespace())
+ {
+ javax.xml.namespace.QName name = cursor.getName();
+ String prefix = name.getLocalPart();
+ String uri = name.getNamespaceURI();
+
+ declareNamespace(prefix, uri, declarations);
+ }
+ }
+ cursor.pop();
+
+ // Process the element
+ processName(cursor, declarations);
+
+ // Process the attributes
+ cursor.push();
+ boolean hasNext = cursor.toFirstAttribute();
+ while(hasNext)
+ {
+ processName(cursor, declarations);
+ hasNext = cursor.toNextAttribute();
+ }
+ cursor.pop();
+ }
+
+ /**
+ * @return Object[] array of Namespace objects in scope at the cursor.
+ */
+ public static Object[] inScopeNamespaces(XMLLibImpl lib, XmlCursor cursor)
+ {
+ ObjArray namespaces = new ObjArray();
+ NamespaceHelper helper = new NamespaceHelper(lib);
+
+ cursor.push();
+
+ int depth = 0;
+ while(cursor.hasPrevToken())
+ {
+ if(cursor.isContainer())
+ {
+ cursor.push();
+ depth++;
+ }
+
+ cursor.toParent();
+ }
+
+ for(int i = 0; i < depth; i++)
+ {
+ cursor.pop();
+ helper.update(cursor, null);
+ }
+
+ Iterator i = helper.prefixToURI.entrySet().iterator();
+ while(i.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ Namespace ns = new Namespace(lib, (String)entry.getKey(),
+ (String)entry.getValue());
+ namespaces.add(ns);
+ }
+
+ i = helper.undeclared.iterator();
+ while(i.hasNext())
+ {
+ Namespace ns = new Namespace(lib, (String)i.next());
+ namespaces.add(ns);
+ }
+
+ cursor.pop();
+
+ return namespaces.toArray();
+ }
+
+ static Namespace getNamespace(XMLLibImpl lib, XmlCursor cursor,
+ Object[] inScopeNamespaces)
+ {
+ String uri;
+ String prefix;
+
+ if (cursor.isProcinst()) {
+ uri = "";
+ prefix = "";
+ } else {
+ javax.xml.namespace.QName qname = cursor.getName();
+ uri = qname.getNamespaceURI();
+ prefix = qname.getPrefix();
+ }
+
+ if (inScopeNamespaces == null)
+ return new Namespace(lib, prefix, uri);
+
+ Namespace result = null;
+ for (int i = 0; i != inScopeNamespaces.length; ++i) {
+ Namespace ns = (Namespace)inScopeNamespaces[i];
+ if(ns == null) continue;
+
+ String nsURI = ns.uri();
+ if(nsURI.equals(uri))
+ {
+ if(prefix.equals(ns.prefix()))
+ {
+ result = ns;
+ break;
+ }
+
+ if(result == null ||
+ (result.prefix() == null &&
+ ns.prefix() != null))
+ result = ns;
+ }
+ }
+
+ if(result == null)
+ result = new Namespace(lib, prefix, uri);
+
+ return result;
+ }
+
+ /**
+ * @return List of Namespace objects that are declared in the container pointed to by the cursor.
+ */
+ public static Object[] namespaceDeclarations(XMLLibImpl lib, XmlCursor cursor)
+ {
+ ObjArray declarations = new ObjArray();
+ NamespaceHelper helper = new NamespaceHelper(lib);
+
+ cursor.push();
+
+ int depth = 0;
+ while(cursor.hasPrevToken())
+ {
+ if(cursor.isContainer())
+ {
+ cursor.push();
+ depth++;
+ }
+
+ cursor.toParent();
+ }
+
+ for(int i = 0; i < depth - 1; i++)
+ {
+ cursor.pop();
+ helper.update(cursor, null);
+ }
+
+ if(depth > 0)
+ {
+ cursor.pop();
+ helper.update(cursor, declarations);
+ }
+
+ cursor.pop();
+
+ return declarations.toArray();
+ }
+
+ /**
+ * @return Prefix to URI map of all namespaces in scope at the cursor.
+ */
+ public static Map getAllNamespaces(XMLLibImpl lib, XmlCursor cursor)
+ {
+ NamespaceHelper helper = new NamespaceHelper(lib);
+
+ cursor.push();
+
+ int depth = 0;
+ while(cursor.hasPrevToken())
+ {
+ if(cursor.isContainer())
+ {
+ cursor.push();
+ depth++;
+ }
+
+ cursor.toParent();
+ }
+
+ for(int i = 0; i < depth; i++)
+ {
+ cursor.pop();
+ helper.update(cursor, null);
+ }
+
+ cursor.pop();
+
+ return helper.prefixToURI;
+ }
+
+ public static void getNamespaces(XmlCursor cursor, Map prefixToURI)
+ {
+ cursor.push();
+ while(cursor.toNextToken().isAnyAttr())
+ {
+ if(cursor.isNamespace())
+ {
+ javax.xml.namespace.QName name = cursor.getName();
+ String prefix = name.getLocalPart();
+ String uri = name.getNamespaceURI();
+
+ prefixToURI.put(prefix, uri);
+ }
+ }
+ cursor.pop();
+ }
+
+ public static void removeNamespace(XmlCursor cursor, String prefix)
+ {
+ cursor.push();
+ while(cursor.toNextToken().isAnyAttr())
+ {
+ if(cursor.isNamespace())
+ {
+ javax.xml.namespace.QName name = cursor.getName();
+ if(name.getLocalPart().equals(prefix))
+ {
+ cursor.removeXml();
+ break;
+ }
+ }
+ }
+ cursor.pop();
+ }
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/QName.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/QName.java
new file mode 100644
index 0000000..247da19
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/QName.java
@@ -0,0 +1,321 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class QName
+ *
+ */
+final class QName extends IdScriptableObject
+{
+ static final long serialVersionUID = 416745167693026750L;
+
+ private static final Object QNAME_TAG = new Object();
+
+ XMLLibImpl lib;
+ private String prefix;
+ private String localName;
+ private String uri;
+
+ QName(XMLLibImpl lib, String uri, String localName, String prefix)
+ {
+ super(lib.globalScope(), lib.qnamePrototype);
+ if (localName == null) throw new IllegalArgumentException();
+ this.lib = lib;
+ this.uri = uri;
+ this.prefix = prefix;
+ this.localName = localName;
+ }
+
+ void exportAsJSClass(boolean sealed)
+ {
+ exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String toString()
+ {
+ String result;
+
+ if (uri == null)
+ {
+ result = "*::".concat(localName);
+ }
+ else if(uri.length() == 0)
+ {
+ result = localName;
+ }
+ else
+ {
+ result = uri + "::" + localName;
+ }
+
+ return result;
+ }
+
+ public String localName()
+ {
+ return localName;
+ }
+
+ String prefix()
+ {
+ return (prefix == null) ? prefix : "";
+ }
+
+ String uri()
+ {
+ return uri;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(!(obj instanceof QName)) return false;
+ return equals((QName)obj);
+ }
+
+ protected Object equivalentValues(Object value)
+ {
+ if(!(value instanceof QName)) return Scriptable.NOT_FOUND;
+ boolean result = equals((QName)value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ private boolean equals(QName q)
+ {
+ boolean result;
+
+ if (uri == null) {
+ result = q.uri == null && localName.equals(q.localName);
+ } else {
+ result = uri.equals(q.uri) && localName.equals(q.localName);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getClassName ()
+ {
+ return "QName";
+ }
+
+ /**
+ *
+ * @param hint
+ * @return
+ */
+ public Object getDefaultValue (Class hint)
+ {
+ return toString();
+ }
+
+// #string_id_map#
+ private static final int
+ Id_localName = 1,
+ Id_uri = 2,
+ MAX_INSTANCE_ID = 2;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2004-07-18 12:32:51 CEST
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==3) { X="uri";id=Id_uri; }
+ else if (s_length==9) { X="localName";id=Id_localName; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_localName:
+ case Id_uri:
+ attr = PERMANENT | READONLY;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_localName: return "localName";
+ case Id_uri: return "uri";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_localName: return localName;
+ case Id_uri: return uri;
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+// #string_id_map#
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2004-08-21 12:45:13 CEST
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=2; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(QNAME_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f,
+ Context cx,
+ Scriptable scope,
+ Scriptable thisObj,
+ Object[] args)
+ {
+ if (!f.hasTag(QNAME_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return jsConstructor(cx, (thisObj == null), args);
+ case Id_toString:
+ return realThis(thisObj, f).toString();
+ case Id_toSource:
+ return realThis(thisObj, f).js_toSource();
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private QName realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if(!(thisObj instanceof QName))
+ throw incompatibleCallError(f);
+ return (QName)thisObj;
+ }
+
+ private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
+ {
+ if (!inNewExpr && args.length == 1) {
+ return lib.castToQName(cx, args[0]);
+ }
+ if (args.length == 0) {
+ return lib.constructQName(cx, Undefined.instance);
+ } else if (args.length == 1) {
+ return lib.constructQName(cx, args[0]);
+ } else {
+ return lib.constructQName(cx, args[0], args[1]);
+ }
+ }
+
+ private String js_toSource()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ toSourceImpl(uri, localName, prefix, sb);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ private static void toSourceImpl(String uri, String localName,
+ String prefix, StringBuffer sb)
+ {
+ sb.append("new QName(");
+ if (uri == null && prefix == null) {
+ if (!"*".equals(localName)) {
+ sb.append("null, ");
+ }
+ } else {
+ Namespace.toSourceImpl(prefix, uri, sb);
+ sb.append(", ");
+ }
+ sb.append('\'');
+ sb.append(ScriptRuntime.escapeString(localName, '\''));
+ sb.append("')");
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java
new file mode 100644
index 0000000..c8818a5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XML.java
@@ -0,0 +1,3092 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import java.io.Serializable;
+import java.util.*;
+
+import org.mozilla.javascript.*;
+
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlCursor.XmlBookmark;
+import org.apache.xmlbeans.XmlCursor.TokenType;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+
+class XML extends XMLObjectImpl
+{
+ static final long serialVersionUID = -630969919086449092L;
+
+ final static class XScriptAnnotation extends XmlBookmark implements Serializable
+ {
+ private static final long serialVersionUID = 1L;
+
+ javax.xml.namespace.QName _name;
+ XML _xScriptXML;
+
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Constructurs
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ XScriptAnnotation (XmlCursor curs)
+ {
+ _name = curs.getName();
+ }
+
+ }
+
+ /**
+ *
+ */
+ final static class NamespaceDeclarations
+ {
+ private int _prefixIdx;
+ private StringBuffer _namespaceDecls;
+ private String _defaultNSURI;
+
+
+ NamespaceDeclarations (XmlCursor curs)
+ {
+ _prefixIdx = 0;
+ _namespaceDecls = new StringBuffer();
+
+ skipNonElements(curs);
+ _defaultNSURI = curs.namespaceForPrefix("");
+
+ if (isAnyDefaultNamespace())
+ {
+ addDecl("", _defaultNSURI);
+ }
+ }
+
+
+ private void addDecl (String prefix, String ns)
+ {
+ _namespaceDecls.append((prefix.length() > 0 ?
+ "declare namespace " + prefix :
+ "default element namespace") +
+ " = \"" + ns + "\"" + "\n");
+ }
+
+
+ String getNextPrefix (String ns)
+ {
+ String prefix = "NS" + _prefixIdx++;
+
+ _namespaceDecls.append("declare namespace " + prefix + " = " + "\"" + ns + "\"" + "\n");
+
+ return prefix;
+ }
+
+
+ boolean isAnyDefaultNamespace ()
+ {
+ return _defaultNSURI != null ?_defaultNSURI.length() > 0 : false;
+ }
+
+
+ String getDeclarations()
+ {
+ return _namespaceDecls.toString();
+ }
+ }
+
+ // Fields
+ //static final XML prototype = new XML();
+ private XScriptAnnotation _anno;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Constructors
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ * @param anno
+ */
+ private XML(XMLLibImpl lib, XScriptAnnotation anno)
+ {
+ super(lib, lib.xmlPrototype);
+ _anno = anno;
+ _anno._xScriptXML = this;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Public factories for creating a XScript XML object given an XBean cursor.
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ static XML createEmptyXML(XMLLibImpl lib)
+ {
+ XScriptAnnotation anno;
+
+ XmlObject xo = XmlObject.Factory.newInstance();
+ XmlCursor curs = xo.newCursor();
+ try {
+ anno = new XScriptAnnotation(curs);
+ curs.setBookmark(anno);
+ } finally {
+ curs.dispose();
+ }
+
+ return new XML(lib, anno);
+ }
+
+ private static XML createXML (XMLLibImpl lib, XmlCursor curs)
+ {
+ if (curs.currentTokenType().isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ XScriptAnnotation anno = findAnnotation(curs);
+
+ return new XML(lib, anno);
+ }
+
+ /**
+ * Special constructor for making an attribute
+ *
+ */
+ private static XML createAttributeXML(XMLLibImpl lib, XmlCursor cursor)
+ {
+ if (!cursor.isAttr())
+ throw new IllegalArgumentException();
+
+ XScriptAnnotation anno = new XScriptAnnotation(cursor);
+ cursor.setBookmark(anno);
+
+ return new XML(lib, anno);
+ }
+
+
+ /**
+ *
+ * @param qname
+ * @param value
+ * @return
+ */
+ static XML createTextElement(XMLLibImpl lib, javax.xml.namespace.QName qname, String value)
+ {
+ XScriptAnnotation anno;
+
+ XmlObject xo = XmlObject.Factory.newInstance();
+ XmlCursor cursor = xo.newCursor();
+ try {
+ cursor.toNextToken();
+
+ cursor.beginElement(qname.getLocalPart(), qname.getNamespaceURI());
+ //if(namespace.length() > 0)
+ // cursor.insertNamespace("", namespace);
+ cursor.insertChars(value);
+
+ cursor.toStartDoc();
+ cursor.toNextToken();
+ anno = new XScriptAnnotation(cursor);
+ cursor.setBookmark(anno);
+ } finally {
+ cursor.dispose();
+ }
+
+ return new XML(lib, anno);
+ }
+
+ static XML createFromXmlObject(XMLLibImpl lib, XmlObject xo)
+ {
+ XScriptAnnotation anno;
+ XmlCursor curs = xo.newCursor();
+ if (curs.currentTokenType().isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+ try {
+ anno = new XScriptAnnotation(curs);
+ curs.setBookmark(anno);
+ } finally {
+ curs.dispose();
+ }
+ return new XML(lib, anno);
+ }
+
+ static XML createFromJS(XMLLibImpl lib, Object inputObject)
+ {
+ XmlObject xo;
+ boolean isText = false;
+ String frag;
+
+ if (inputObject == null || inputObject == Undefined.instance) {
+ frag = "";
+ } else if (inputObject instanceof XMLObjectImpl) {
+ // todo: faster way for XMLObjects?
+ frag = ((XMLObjectImpl) inputObject).toXMLString(0);
+ } else {
+ if (inputObject instanceof Wrapper) {
+ Object wrapped = ((Wrapper)inputObject).unwrap();
+ if (wrapped instanceof XmlObject) {
+ return createFromXmlObject(lib, (XmlObject)wrapped);
+ }
+ }
+ frag = ScriptRuntime.toString(inputObject);
+ }
+
+ if (frag.trim().startsWith("<>"))
+ {
+ throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <></>.");
+ }
+
+ if (frag.indexOf("<") == -1)
+ {
+ // Must be solo text node, wrap in XML fragment
+ isText = true;
+ frag = "<textFragment>" + frag + "</textFragment>";
+ }
+
+ XmlOptions options = new XmlOptions();
+
+ if (lib.ignoreComments)
+ {
+ options.put(XmlOptions.LOAD_STRIP_COMMENTS);
+ }
+
+ if (lib.ignoreProcessingInstructions)
+ {
+ options.put(XmlOptions.LOAD_STRIP_PROCINSTS);
+ }
+
+ if (lib.ignoreWhitespace)
+ {
+ options.put(XmlOptions.LOAD_STRIP_WHITESPACE);
+ }
+
+ try
+ {
+ xo = XmlObject.Factory.parse(frag, options);
+
+ // Apply the default namespace
+ Context cx = Context.getCurrentContext();
+ String defaultURI = lib.getDefaultNamespaceURI(cx);
+
+ if(defaultURI.length() > 0)
+ {
+ XmlCursor cursor = xo.newCursor();
+ boolean isRoot = true;
+ while(!cursor.toNextToken().isEnddoc())
+ {
+ if(!cursor.isStart()) continue;
+
+ // Check if this element explicitly sets the
+ // default namespace
+ boolean defaultNSDeclared = false;
+ cursor.push();
+ while(cursor.toNextToken().isAnyAttr())
+ {
+ if(cursor.isNamespace())
+ {
+ if(cursor.getName().getLocalPart().length() == 0)
+ {
+ defaultNSDeclared = true;
+ break;
+ }
+ }
+ }
+ cursor.pop();
+ if(defaultNSDeclared)
+ {
+ cursor.toEndToken();
+ continue;
+ }
+
+ // Check if this element's name is in no namespace
+ javax.xml.namespace.QName qname = cursor.getName();
+ if(qname.getNamespaceURI().length() == 0)
+ {
+ // Change the namespace
+ qname = new javax.xml.namespace.QName(defaultURI,
+ qname.getLocalPart());
+ cursor.setName(qname);
+ }
+
+ if(isRoot)
+ {
+ // Declare the default namespace
+ cursor.push();
+ cursor.toNextToken();
+ cursor.insertNamespace("", defaultURI);
+ cursor.pop();
+
+ isRoot = false;
+ }
+ }
+ cursor.dispose();
+ }
+ }
+ catch (XmlException xe)
+ {
+/*
+todo need to handle namespace prefix not found in XML look for namespace type in the scope change.
+
+ String errorMsg = "Use of undefined namespace prefix: ";
+ String msg = xe.getError().getMessage();
+ if (msg.startsWith(errorMsg))
+ {
+ String prefix = msg.substring(errorMsg.length());
+ }
+*/
+ String errMsg = xe.getMessage();
+ if (errMsg.equals("error: Unexpected end of file after null"))
+ {
+ // Create an empty document.
+ xo = XmlObject.Factory.newInstance();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError(xe.getMessage());
+ }
+ }
+ catch (Throwable e)
+ {
+ // todo: TLL Catch specific exceptions during parse.
+ throw ScriptRuntime.typeError("Not Parsable as XML");
+ }
+
+ XmlCursor curs = xo.newCursor();
+ if (curs.currentTokenType().isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ if (isText)
+ {
+ // Move it to point to the text node
+ curs.toFirstContentToken();
+ }
+
+ XScriptAnnotation anno;
+ try
+ {
+ anno = new XScriptAnnotation(curs);
+ curs.setBookmark(anno);
+ }
+ finally
+ {
+ curs.dispose();
+ }
+
+ return new XML(lib, anno);
+ }
+
+ static XML getFromAnnotation(XMLLibImpl lib, XScriptAnnotation anno)
+ {
+ if (anno._xScriptXML == null)
+ {
+ anno._xScriptXML = new XML(lib, anno);
+ }
+
+ return anno._xScriptXML;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Private functions:
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ * @param curs
+ * @return
+ */
+ private static TokenType skipNonElements (XmlCursor curs)
+ {
+ TokenType tt = curs.currentTokenType();
+ while (tt.isComment() || tt.isProcinst())
+ {
+ tt = curs.toNextToken();
+ }
+
+ return tt;
+ }
+
+ /**
+ *
+ * @param curs
+ * @return
+ */
+ protected static XScriptAnnotation findAnnotation(XmlCursor curs)
+ {
+ XmlBookmark anno = curs.getBookmark(XScriptAnnotation.class);
+ if (anno == null)
+ {
+ anno = new XScriptAnnotation(curs);
+ curs.setBookmark(anno);
+ }
+
+ return (XScriptAnnotation)anno;
+ }
+
+ /**
+ *
+ * @return
+ */
+ private XmlOptions getOptions()
+ {
+ XmlOptions options = new XmlOptions();
+
+ if (lib.ignoreComments)
+ {
+ options.put(XmlOptions.LOAD_STRIP_COMMENTS);
+ }
+
+ if (lib.ignoreProcessingInstructions)
+ {
+ options.put(XmlOptions.LOAD_STRIP_PROCINSTS);
+ }
+
+ if (lib.ignoreWhitespace)
+ {
+ options.put(XmlOptions.LOAD_STRIP_WHITESPACE);
+ }
+
+ if (lib.prettyPrinting)
+ {
+ options.put(XmlOptions.SAVE_PRETTY_PRINT, null);
+ options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, new Integer(lib.prettyIndent));
+ }
+
+ return options;
+ }
+
+
+ /**
+ *
+ * @param cursor
+ * @param opts
+ * @return
+ */
+ private static String dumpNode(XmlCursor cursor, XmlOptions opts)
+ {
+ if (cursor.isText())
+ return cursor.getChars();
+
+ if (cursor.isFinish())
+ return "";
+
+ cursor.push();
+ boolean wanRawText = cursor.isStartdoc() && !cursor.toFirstChild();
+ cursor.pop();
+
+ return wanRawText ? cursor.getTextValue() : cursor.xmlText( opts );
+ }
+
+ /**
+ *
+ * @return
+ */
+ private XmlCursor newCursor ()
+ {
+ XmlCursor curs;
+
+ if (_anno != null)
+ {
+ curs = _anno.createCursor();
+ if (curs == null)
+ {
+ // Orphaned case.
+ XmlObject doc = XmlObject.Factory.newInstance();
+ curs = doc.newCursor();
+
+ if (_anno._name != null)
+ {
+ curs.toNextToken();
+ curs.insertElement(_anno._name);
+ curs.toPrevSibling();
+ }
+
+ curs.setBookmark(_anno);
+ }
+ }
+ else
+ {
+ XmlObject doc = XmlObject.Factory.newInstance();
+ curs = doc.newCursor();
+ }
+
+ return curs;
+ }
+
+ /*
+ * fUseStartDoc used by child(int index) the index is at startDoc is the element at the top-level
+ * otherwise we always want to drill in.
+ */
+ private boolean moveToChild(XmlCursor curs, long index, boolean fFirstChild, boolean fUseStartDoc)
+ {
+ if (index < 0)
+ throw new IllegalArgumentException();
+
+ long idxChild = 0;
+
+ if (!fUseStartDoc && curs.currentTokenType().isStartdoc())
+ {
+ // We always move to the children of the top node.
+ // todo: This assumes that we want have multiple top-level nodes. Which we should be able tohave.
+ curs.toFirstContentToken();
+ }
+
+ TokenType tt = curs.toFirstContentToken();
+ if (!tt.isNone() && !tt.isEnd())
+ {
+ while (true)
+ {
+ if (index == idxChild)
+ {
+ return true;
+ }
+
+ tt = curs.currentTokenType();
+ if (tt.isText())
+ {
+ curs.toNextToken();
+ }
+ else if (tt.isStart())
+ {
+ // Need to do this we want to be pointing at the text if that after the end token.
+ curs.toEndToken();
+ curs.toNextToken();
+ }
+ else if (tt.isComment() || tt.isProcinst())
+ {
+ continue;
+ }
+ else
+ {
+ break;
+ }
+
+ idxChild++;
+ }
+ }
+ else if (fFirstChild && index == 0)
+ {
+ // Drill into where first child would be.
+// curs.toFirstContentToken();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ * @return
+ */
+ XmlCursor.TokenType tokenType()
+ {
+ XmlCursor.TokenType result;
+
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ result = curs.currentTokenType();
+
+ curs.dispose();
+
+ return result;
+ }
+ /**
+ *
+ * @param srcCurs
+ * @param destCurs
+ * @param fDontMoveIfSame
+ * @return
+ */
+ private boolean moveSrcToDest (XmlCursor srcCurs, XmlCursor destCurs, boolean fDontMoveIfSame)
+ {
+ boolean fMovedSomething = true;
+ TokenType tt;
+ do
+ {
+ if (fDontMoveIfSame && srcCurs.isInSameDocument(destCurs) && (srcCurs.comparePosition(destCurs) == 0))
+ {
+ // If the source and destination are pointing at the same place then there's nothing to move.
+ fMovedSomething = false;
+ break;
+ }
+
+ // todo ***TLL*** Use replaceContents (when added) and eliminate children removes (see above todo).
+ if (destCurs.currentTokenType().isStartdoc())
+ {
+ destCurs.toNextToken();
+ }
+
+ // todo ***TLL*** Can Eric support notion of copy instead of me copying then moving???
+ XmlCursor copyCurs = copy(srcCurs);
+
+ copyCurs.moveXml(destCurs);
+
+ copyCurs.dispose();
+
+ tt = srcCurs.currentTokenType();
+ } while (!tt.isStart() && !tt.isEnd() && !tt.isEnddoc());
+
+ return fMovedSomething;
+ }
+
+ /**
+ *
+ * @param cursToCopy
+ * @return
+ */
+ private XmlCursor copy (XmlCursor cursToCopy)
+ {
+ XmlObject xo = XmlObject.Factory.newInstance();
+
+ XmlCursor copyCurs = null;
+
+ if (cursToCopy.currentTokenType().isText())
+ {
+ try
+ {
+ // Try just as a textnode, to do that we need to wrap the text in a special fragment tag
+ // that is not visible from the XmlCursor.
+ copyCurs = XmlObject.Factory.parse("<x:fragment xmlns:x=\"http://www.openuri.org/fragment\">" +
+ cursToCopy.getChars() +
+ "</x:fragment>").newCursor();
+ if (!cursToCopy.toNextSibling())
+ {
+ if (cursToCopy.currentTokenType().isText())
+ {
+ cursToCopy.toNextToken(); // It's not an element it's text so skip it.
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ throw ScriptRuntime.typeError(ex.getMessage());
+ }
+ }
+ else
+ {
+ copyCurs = xo.newCursor();
+ copyCurs.toFirstContentToken();
+ if (cursToCopy.currentTokenType() == XmlCursor.TokenType.STARTDOC)
+ {
+ cursToCopy.toNextToken();
+ }
+
+ cursToCopy.copyXml(copyCurs);
+ if (!cursToCopy.toNextSibling()) // If element skip element.
+ {
+ if (cursToCopy.currentTokenType().isText())
+ {
+ cursToCopy.toNextToken(); // It's not an element it's text so skip it.
+ }
+ }
+
+ }
+
+ copyCurs.toStartDoc();
+ copyCurs.toFirstContentToken();
+
+ return copyCurs;
+ }
+
+ private static final int APPEND_CHILD = 1;
+ private static final int PREPEND_CHILD = 2;
+
+ /**
+ *
+ * @param curs
+ * @param xmlToInsert
+ */
+ private void insertChild(XmlCursor curs, Object xmlToInsert)
+ {
+ if (xmlToInsert == null || xmlToInsert instanceof Undefined)
+ {
+ // Do nothing
+ }
+ else if (xmlToInsert instanceof XmlCursor)
+ {
+ moveSrcToDest((XmlCursor)xmlToInsert, curs, true);
+ }
+ else if (xmlToInsert instanceof XML)
+ {
+ XML xmlValue = (XML) xmlToInsert;
+
+ // If it's an attribute, then change to text node
+ if (xmlValue.tokenType() == XmlCursor.TokenType.ATTR)
+ {
+ insertChild(curs, xmlValue.toString());
+ }
+ else
+ {
+ XmlCursor cursToInsert = ((XML) xmlToInsert).newCursor();
+
+ moveSrcToDest(cursToInsert, curs, true);
+
+ cursToInsert.dispose();
+ }
+ }
+ else if (xmlToInsert instanceof XMLList)
+ {
+ XMLList list = (XMLList) xmlToInsert;
+
+ for (int i = 0; i < list.length(); i++)
+ {
+ insertChild(curs, list.item(i));
+ }
+ }
+ else
+ {
+ // Convert to string and make XML out of it
+ String xmlStr = ScriptRuntime.toString(xmlToInsert);
+ XmlObject xo = XmlObject.Factory.newInstance(); // Create an empty document.
+
+ XmlCursor sourceCurs = xo.newCursor();
+ sourceCurs.toNextToken();
+
+ // To hold the text.
+ sourceCurs.insertChars(xmlStr);
+
+ sourceCurs.toPrevToken();
+
+ // Call us again with the cursor.
+ moveSrcToDest(sourceCurs, curs, true);
+ }
+ }
+
+ /**
+ *
+ * @param childToMatch
+ * @param xmlToInsert
+ * @param addToType
+ */
+ private void insertChild(XML childToMatch, Object xmlToInsert, int addToType)
+ {
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+ XmlCursor xmlChildCursor = childToMatch.newCursor();
+
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ tt = curs.toNextToken();
+
+ while (!tt.isEnd())
+ {
+ if (tt.isStart())
+ {
+ // See if this child is the same as the one thep passed in
+ if (curs.comparePosition(xmlChildCursor) == 0)
+ {
+ // Found it
+ if (addToType == APPEND_CHILD)
+ {
+ // Move the cursor to just past the end of this element
+ curs.toEndToken();
+ curs.toNextToken();
+ }
+
+ insertChild(curs, xmlToInsert);
+ break;
+ }
+ }
+
+ // Skip over child elements
+ if (tt.isStart())
+ {
+ tt = curs.toEndToken();
+ }
+
+ tt = curs.toNextToken();
+ }
+
+ }
+
+ xmlChildCursor.dispose();
+ curs.dispose();
+ }
+
+ /**
+ *
+ * @param curs
+ */
+ protected void removeToken (XmlCursor curs)
+ {
+ XmlObject xo = XmlObject.Factory.newInstance();
+
+ // Don't delete anything move to another document so it gets orphaned nicely.
+ XmlCursor tmpCurs = xo.newCursor();
+ tmpCurs.toFirstContentToken();
+
+
+ curs.moveXml(tmpCurs);
+
+ tmpCurs.dispose();
+ }
+
+ /**
+ *
+ * @param index
+ */
+ protected void removeChild(long index)
+ {
+ XmlCursor curs = newCursor();
+
+ if (moveToChild(curs, index, false, false))
+ {
+ removeToken(curs);
+ }
+
+ curs.dispose();
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ protected static javax.xml.namespace.QName computeQName (Object name)
+ {
+ if (name instanceof String)
+ {
+ String ns = null;
+ String localName = null;
+
+ String fullName = (String)name;
+ localName = fullName;
+ if (fullName.startsWith("\""))
+ {
+ int idx = fullName.indexOf(":");
+ if (idx != -1)
+ {
+ ns = fullName.substring(1, idx - 1); // Don't include the "" around the namespace
+ localName = fullName.substring(idx + 1);
+ }
+ }
+
+ if (ns == null)
+ {
+ return new javax.xml.namespace.QName(localName);
+ }
+ else
+ {
+ return new javax.xml.namespace.QName(ns, localName);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param destCurs
+ * @param newValue
+ */
+ private void replace(XmlCursor destCurs, XML newValue)
+ {
+ if (destCurs.isStartdoc())
+ {
+ // Can't overwrite a whole document (user really wants to overwrite the contents of).
+ destCurs.toFirstContentToken();
+ }
+
+ // Orphan the token -- don't delete it outright on the XmlCursor.
+ removeToken(destCurs);
+
+ XmlCursor srcCurs = newValue.newCursor();
+ if (srcCurs.currentTokenType().isStartdoc())
+ {
+ // Cann't append a whole document (user really wants to append the contents of).
+ srcCurs.toFirstContentToken();
+ }
+
+ moveSrcToDest(srcCurs, destCurs, false);
+
+ // Re-link a new annotation to this cursor -- we just deleted the previous annotation on entrance to replace.
+ if (!destCurs.toPrevSibling())
+ {
+ destCurs.toPrevToken();
+ }
+ destCurs.setBookmark(new XScriptAnnotation(destCurs));
+
+ // todo would be nice if destCurs.toNextSibling went to where the next token if the cursor was pointing at the last token in the stream.
+ destCurs.toEndToken();
+ destCurs.toNextToken();
+
+ srcCurs.dispose();
+ }
+
+ /**
+ *
+ * @param currXMLNode
+ * @param xmlValue
+ * @return
+ */
+ private boolean doPut(XMLName name, XML currXMLNode, XMLObjectImpl xmlValue)
+ {
+ boolean result = false;
+ XmlCursor curs = currXMLNode.newCursor();
+
+ try
+ {
+ // Replace the node with this new xml value.
+ XML xml;
+
+ int toAssignLen = xmlValue.length();
+
+ for (int i = 0; i < toAssignLen; i++)
+ {
+ if (xmlValue instanceof XMLList)
+ {
+ xml = ((XMLList) xmlValue).item(i);
+ }
+ else
+ {
+ xml = (XML) xmlValue;
+ }
+
+ // If it's an attribute or text node, make text node.
+ XmlCursor.TokenType tt = xml.tokenType();
+ if (tt == XmlCursor.TokenType.ATTR || tt == XmlCursor.TokenType.TEXT)
+ {
+ xml = makeXmlFromString(lib, name, xml.toString());
+ }
+
+ if (i == 0)
+ {
+ // 1st assignment is replaceChild all others are appendChild
+ replace(curs, xml);
+ }
+ else
+ {
+ insertChild(curs, xml);
+ }
+ }
+
+ // We're done we've blown away the node because the rvalue was XML...
+ result = true;
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ throw ScriptRuntime.typeError(ex.getMessage());
+ }
+ finally
+ {
+ curs.dispose();
+ }
+
+ return result;
+ }
+
+ /**
+ * Make a text node element with this element name and text value.
+ *
+ * @param name
+ * @param value
+ * @return
+ */
+ private XML makeXmlFromString(XMLLibImpl lib, XMLName name,
+ String value)
+ {
+ XML result;
+
+ javax.xml.namespace.QName qname;
+
+ try
+ {
+ qname = new javax.xml.namespace.QName(name.uri(), name.localName());
+ }
+ catch(Exception e)
+ {
+ throw ScriptRuntime.typeError(e.getMessage());
+ }
+
+ result = createTextElement(lib, qname, value);
+
+ return result;
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ private XMLList matchAttributes(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+ XmlCursor curs = newCursor();
+
+ if (curs.currentTokenType().isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ if (curs.isStart())
+ {
+ if (curs.toFirstAttribute())
+ {
+ do
+ {
+ if (qnameMatches(xmlName, curs.getName()))
+ {
+ result.addToList(createAttributeObject(curs));
+ }
+ } while (curs.toNextAttribute());
+ }
+ }
+
+ curs.dispose();
+
+ return result;
+ }
+
+ /**
+ *
+ * @param attrCurs
+ * @return
+ */
+ private XML createAttributeObject (XmlCursor attrCurs)
+ {
+ XML result = null;
+
+ if (attrCurs.currentTokenType().isAttr())
+ {
+ result = createAttributeXML(lib, attrCurs);
+ }
+
+ return result;
+ }
+
+ //
+ //
+ // methods overriding ScriptableObject
+ //
+ //
+
+ public String getClassName ()
+ {
+ return "XML";
+ }
+
+ //
+ //
+ // methods overriding IdScriptableObject
+ //
+ //
+
+ /**
+ * XML[0] should return this, all other indexes are Undefined
+ *
+ * @param index
+ * @param start
+ * @return
+ */
+ public Object get(int index, Scriptable start)
+ {
+ //Log("get index: " + index);
+
+ if (index == 0)
+ {
+ return this;
+ }
+ else
+ {
+ return Scriptable.NOT_FOUND;
+ }
+ }
+
+ /**
+ * Does the named property exist
+ *
+ * @param name
+ * @param start
+ * @return
+ */
+ boolean hasXMLProperty(XMLName xmlName)
+ {
+ boolean result = false;
+
+ if (prototypeFlag)
+ {
+ String name = xmlName.localName();
+
+ if (getMethod(name) != NOT_FOUND)
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ // Has now should return true if the property would have results > 0 or
+ // if it's a method name
+ String name = xmlName.localName();
+ if ((getPropertyList(xmlName).length() > 0) ||
+ (getMethod(name) != NOT_FOUND))
+ {
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+
+ /**
+ *
+ * @param index
+ * @param start
+ * @return
+ */
+ public boolean has(int index, Scriptable start)
+ {
+ return (index == 0);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Object[] getIds()
+ {
+ Object[] enumObjs;
+
+ if (prototypeFlag)
+ {
+ enumObjs = new Object[0];
+ }
+ else
+ {
+ enumObjs = new Object[1];
+
+ enumObjs[0] = new Integer(0);
+ }
+
+ return enumObjs;
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public Object [] getIdsForDebug()
+ {
+ return getIds();
+ }
+
+ /**
+ *
+ * @param name
+ * @param start
+ * @return
+ */
+ Object getXMLProperty(XMLName xmlName)
+ {
+ Object result = NOT_FOUND;
+
+ if (prototypeFlag)
+ {
+ String name = xmlName.localName();
+
+ result = getMethod(name);
+ }
+ else
+ {
+ result = getPropertyList(xmlName);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param name
+ * @param start
+ * @param value
+ */
+ void putXMLProperty(XMLName xmlName, Object value)
+ {
+ //Log("put property: " + name + " value: " + value.getClass());
+
+ if (prototypeFlag)
+ {
+ }
+ else
+ {
+ // Special-case checks for undefined and null
+ if (value == null)
+ {
+ value = "null";
+ }
+ else if (value instanceof Undefined)
+ {
+ value = "undefined";
+ }
+
+ // Get the named property
+ if (xmlName.isAttributeName())
+ {
+ setAttribute(xmlName, value);
+ }
+ else if (xmlName.uri() == null &&
+ xmlName.localName().equals("*"))
+ {
+ setChildren(value);
+ }
+ else
+ {
+ // Convert text into XML if needed.
+ XMLObjectImpl xmlValue = null;
+
+ if (value instanceof XMLObjectImpl)
+ {
+ xmlValue = (XMLObjectImpl) value;
+
+ // Check for attribute type and convert to textNode
+ if (xmlValue instanceof XML)
+ {
+ if (((XML) xmlValue).tokenType() == XmlCursor.TokenType.ATTR)
+ {
+ xmlValue = makeXmlFromString(lib, xmlName, xmlValue.toString());
+ }
+ }
+
+ if (xmlValue instanceof XMLList)
+ {
+ for (int i = 0; i < xmlValue.length(); i++)
+ {
+ XML xml = ((XMLList) xmlValue).item(i);
+
+ if (xml.tokenType() == XmlCursor.TokenType.ATTR)
+ {
+ ((XMLList) xmlValue).replace(i, makeXmlFromString(lib, xmlName, xml.toString()));
+ }
+ }
+ }
+ }
+ else
+ {
+ xmlValue = makeXmlFromString(lib, xmlName, ScriptRuntime.toString(value));
+ }
+
+ XMLList matches = getPropertyList(xmlName);
+
+ if (matches.length() == 0)
+ {
+ appendChild(xmlValue);
+ }
+ else
+ {
+ // Remove all other matches
+ for (int i = 1; i < matches.length(); i++)
+ {
+ removeChild(matches.item(i).childIndex());
+ }
+
+ // Replace first match with new value.
+ doPut(xmlName, matches.item(0), xmlValue);
+ }
+ }
+ }
+ }
+
+
+ /**
+ *
+ * @param index
+ * @param start
+ * @param value
+ */
+ public void put(int index, Scriptable start, Object value)
+ {
+ // Spec says assignment to indexed XML object should return type error
+ throw ScriptRuntime.typeError("Assignment to indexed XML is not allowed");
+ }
+
+
+ /**
+ *
+ * @param name
+ */
+ void deleteXMLProperty(XMLName name)
+ {
+ if (!name.isDescendants() && name.isAttributeName())
+ {
+ XmlCursor curs = newCursor();
+
+ // TODO: Cover the case *::name
+ if (name.localName().equals("*"))
+ {
+ // Delete all attributes.
+ if (curs.toFirstAttribute())
+ {
+ while (curs.currentTokenType().isAttr())
+ {
+ curs.removeXml();
+ }
+ }
+ }
+ else
+ {
+ // Delete an attribute.
+ javax.xml.namespace.QName qname = new javax.xml.namespace.QName(
+ name.uri(), name.localName());
+ curs.removeAttribute(qname);
+ }
+
+ curs.dispose();
+ }
+ else
+ {
+ XMLList matches = getPropertyList(name);
+
+ matches.remove();
+ }
+ }
+
+
+ /**
+ *
+ * @param index
+ */
+ public void delete(int index)
+ {
+ if (index == 0)
+ {
+ remove();
+ }
+ }
+
+ //
+ //
+ // package utility functions:
+ //
+ //
+
+ protected XScriptAnnotation getAnnotation ()
+ { return _anno; }
+
+
+ protected void changeNS (String oldURI, String newURI)
+ {
+ XmlCursor curs = newCursor();
+ while (curs.toParent()) {
+ /* Goto the top of the document */
+ }
+
+ TokenType tt = curs.currentTokenType();
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isStart())
+ {
+ do
+ {
+ if (tt.isStart() || tt.isAttr() || tt.isNamespace())
+ {
+ javax.xml.namespace.QName currQName = curs.getName();
+ if (oldURI.equals(currQName.getNamespaceURI()))
+ {
+ curs.setName(new javax.xml.namespace.QName(newURI, currQName.getLocalPart()));
+ }
+ }
+
+ tt = curs.toNextToken();
+ } while (!tt.isEnddoc() && !tt.isNone());
+ }
+
+ curs.dispose();
+ }
+
+
+ /**
+ *
+ */
+ void remove ()
+ {
+ XmlCursor childCurs = newCursor();
+
+ if (childCurs.currentTokenType().isStartdoc())
+ {
+ // Remove on the document removes all children.
+ TokenType tt = childCurs.toFirstContentToken();
+ while (!tt.isEnd() && !tt.isEnddoc())
+ {
+ removeToken(childCurs);
+ tt = childCurs.currentTokenType(); // Now see where we're pointing after the delete -- next token.
+ }
+ }
+ else
+ {
+ removeToken(childCurs);
+ }
+
+ childCurs.dispose();
+ }
+
+
+ /**
+ *
+ * @param value
+ */
+ void replaceAll(XML value)
+ {
+ XmlCursor curs = newCursor();
+
+ replace(curs, value);
+ _anno = value._anno;
+
+ curs.dispose();
+ }
+
+
+ /**
+ *
+ * @param attrName
+ * @param value
+ */
+ void setAttribute(XMLName xmlName, Object value)
+ {
+ if (xmlName.uri() == null &&
+ xmlName.localName().equals("*"))
+ {
+ throw ScriptRuntime.typeError("@* assignment not supported.");
+ }
+
+ XmlCursor curs = newCursor();
+
+ String strValue = ScriptRuntime.toString(value);
+ if (curs.currentTokenType().isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ javax.xml.namespace.QName qName;
+
+ try
+ {
+ qName = new javax.xml.namespace.QName(xmlName.uri(), xmlName.localName());
+ }
+ catch(Exception e)
+ {
+ throw ScriptRuntime.typeError(e.getMessage());
+ }
+
+ if (!curs.setAttributeText(qName, strValue))
+ {
+ if (curs.currentTokenType().isStart())
+ {
+ // Can only add attributes inside of a start.
+ curs.toNextToken();
+ }
+ curs.insertAttributeWithValue(qName, strValue);
+ }
+
+ curs.dispose();
+ }
+
+ /**
+ *
+ * @param namespace
+ * @return
+ */
+ private XMLList allChildNodes(String namespace)
+ {
+ XMLList result = new XMLList(lib);
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+ javax.xml.namespace.QName targetProperty = new javax.xml.namespace.QName(namespace, "*");
+
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ tt = curs.toFirstContentToken();
+
+ while (!tt.isEnd())
+ {
+ if (!tt.isStart())
+ {
+ // Not an element
+ result.addToList(findAnnotation(curs));
+
+ // Reset target property to null in this case
+ targetProperty = null;
+ }
+ else
+ {
+ // Match namespace as well if specified
+ if (namespace == null ||
+ namespace.length() == 0 ||
+ namespace.equals("*") ||
+ curs.getName().getNamespaceURI().equals(namespace))
+ {
+ // Add it to the list
+ result.addToList(findAnnotation(curs));
+
+ // Set target property if target name is "*",
+ // Otherwise if target property does not match current, then
+ // set to null
+ if (targetProperty != null)
+ {
+ if (targetProperty.getLocalPart().equals("*"))
+ {
+ targetProperty = curs.getName();
+ }
+ else if (!targetProperty.getLocalPart().equals(curs.getName().getLocalPart()))
+ {
+ // Not a match, unset target property
+ targetProperty = null;
+ }
+ }
+ }
+ }
+
+ // Skip over child elements
+ if (tt.isStart())
+ {
+ tt = curs.toEndToken();
+ }
+
+ tt = curs.toNextToken();
+ }
+ }
+
+ curs.dispose();
+
+ // Set the targets for this XMLList.
+ result.setTargets(this, targetProperty);
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ private XMLList matchDescendantAttributes(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+
+ // Set the targets for this XMLList.
+ result.setTargets(this, null);
+
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ int nestLevel = 1;
+
+ while (nestLevel > 0)
+ {
+ tt = curs.toNextToken();
+
+ // Only try to match names for attributes
+ if (tt.isAttr())
+ {
+ if (qnameMatches(xmlName, curs.getName()))
+ {
+ result.addToList(findAnnotation(curs));
+ }
+ }
+
+ if (tt.isStart())
+ {
+ nestLevel++;
+ }
+ else if (tt.isEnd())
+ {
+ nestLevel--;
+ }
+ else if (tt.isEnddoc())
+ {
+ // Shouldn't get here, but just in case.
+ break;
+ }
+ }
+ }
+
+ curs.dispose();
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ private XMLList matchDescendantChildren(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+
+ // Set the targets for this XMLList.
+ result.setTargets(this, null);
+
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ int nestLevel = 1;
+
+ while (nestLevel > 0)
+ {
+ tt = curs.toNextToken();
+
+ if (!tt.isAttr() && !tt.isEnd() && !tt.isEnddoc())
+ {
+ // Only try to match names for elements or processing instructions.
+ if (!tt.isStart() && !tt.isProcinst())
+ {
+ // Not an element or procinst, only add if qname is all
+ if (xmlName.localName().equals("*"))
+ {
+ result.addToList(findAnnotation(curs));
+ }
+ }
+ else
+ {
+ if (qnameMatches(xmlName, curs.getName()))
+ {
+ result.addToList(findAnnotation(curs));
+ }
+ }
+ }
+
+ if (tt.isStart())
+ {
+ nestLevel++;
+ }
+ else if (tt.isEnd())
+ {
+ nestLevel--;
+ }
+ else if (tt.isEnddoc())
+ {
+ // Shouldn't get here, but just in case.
+ break;
+ }
+ }
+ }
+
+ curs.dispose();
+
+ return result;
+ }
+
+ /**
+ *
+ * @param tokenType
+ * @return
+ */
+ private XMLList matchChildren(XmlCursor.TokenType tokenType)
+ {
+ return matchChildren(tokenType, XMLName.formStar());
+ }
+
+ /**
+ *
+ * @return
+ */
+ private XMLList matchChildren(XmlCursor.TokenType tokenType, XMLName name)
+ {
+ XMLList result = new XMLList(lib);
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+ javax.xml.namespace.QName qname = new javax.xml.namespace.QName(name.uri(), name.localName());
+ javax.xml.namespace.QName targetProperty = qname;
+
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ tt = curs.toFirstContentToken();
+
+ while (!tt.isEnd())
+ {
+ if (tt == tokenType)
+ {
+ // Only try to match names for elements or processing instructions.
+ if (!tt.isStart() && !tt.isProcinst())
+ {
+ // Not an element or no name specified.
+ result.addToList(findAnnotation(curs));
+
+ // Reset target property to null in this case
+ targetProperty = null;
+ }
+ else
+ {
+ // Match names as well
+ if (qnameMatches(name, curs.getName()))
+ {
+ // Add it to the list
+ result.addToList(findAnnotation(curs));
+
+ // Set target property if target name is "*",
+ // Otherwise if target property does not match current, then
+ // set to null
+ if (targetProperty != null)
+ {
+ if (targetProperty.getLocalPart().equals("*"))
+ {
+ targetProperty = curs.getName();
+ }
+ else if (!targetProperty.getLocalPart().equals(curs.getName().getLocalPart()))
+ {
+ // Not a match, unset target property
+ targetProperty = null;
+ }
+ }
+ }
+ }
+ }
+
+ // Skip over child elements
+ if (tt.isStart())
+ {
+ tt = curs.toEndToken();
+ }
+
+ tt = curs.toNextToken();
+ }
+ }
+
+ curs.dispose();
+
+ if (tokenType == XmlCursor.TokenType.START)
+ {
+ // Set the targets for this XMLList.
+ result.setTargets(this, targetProperty);
+ }
+
+ return result;
+
+ }
+
+ /**
+ *
+ * @param template
+ * @param match
+ * @return
+ */
+ private boolean qnameMatches(XMLName template, javax.xml.namespace.QName match)
+ {
+ boolean matches = false;
+
+ if (template.uri() == null ||
+ template.uri().equals(match.getNamespaceURI()))
+ {
+ // URI OK, test name
+ if (template.localName().equals("*") ||
+ template.localName().equals(match.getLocalPart()))
+ {
+ matches = true;
+ }
+ }
+
+ return matches;
+ }
+
+ //
+ //
+ // Methods from section 12.4.4 in the spec
+ //
+ //
+
+ /**
+ * The addNamespace method adds a namespace declaration to the in scope
+ * namespaces for this XML object and returns this XML object.
+ *
+ * @param toAdd
+ */
+ XML addNamespace(Namespace ns)
+ {
+ // When a namespace is used it will be added automatically
+ // to the inScopeNamespaces set. There is no need to add
+ // Namespaces with undefined prefixes.
+ String nsPrefix = ns.prefix();
+ if (nsPrefix == null) return this;
+
+ XmlCursor cursor = newCursor();
+
+ try
+ {
+ if(!cursor.isContainer()) return this;
+
+ javax.xml.namespace.QName qname = cursor.getName();
+ // Don't add a default namespace declarations to containers
+ // with QNames in no namespace.
+ if(qname.getNamespaceURI().equals("") &&
+ nsPrefix.equals("")) return this;
+
+ // Get all declared namespaces that are in scope
+ Map prefixToURI = NamespaceHelper.getAllNamespaces(lib, cursor);
+
+ String uri = (String)prefixToURI.get(nsPrefix);
+ if(uri != null)
+ {
+ // Check if the Namespace is not already in scope
+ if(uri.equals(ns.uri())) return this;
+
+ cursor.push();
+
+ // Let's see if we have to delete a namespace declaration
+ while(cursor.toNextToken().isAnyAttr())
+ {
+ if(cursor.isNamespace())
+ {
+ qname = cursor.getName();
+ String prefix = qname.getLocalPart();
+ if(prefix.equals(nsPrefix))
+ {
+ // Delete the current Namespace declaration
+ cursor.removeXml();
+ break;
+ }
+ }
+ }
+
+ cursor.pop();
+ }
+
+ cursor.toNextToken();
+ cursor.insertNamespace(nsPrefix, ns.uri());
+ }
+ finally
+ {
+ cursor.dispose();
+ }
+
+ return this;
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ XML appendChild(Object xml)
+ {
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ // Move the cursor to the end of this element
+ if (curs.isStart())
+ {
+ curs.toEndToken();
+ }
+
+ insertChild(curs, xml);
+
+ curs.dispose();
+
+ return this;
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ XMLList attribute(XMLName xmlName)
+ {
+ return matchAttributes(xmlName);
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList attributes()
+ {
+ XMLName xmlName = XMLName.formStar();
+ return matchAttributes(xmlName);
+ }
+
+ XMLList child(long index)
+ {
+ XMLList result = new XMLList(lib);
+ result.setTargets(this, null);
+ result.addToList(getXmlChild(index));
+ return result;
+ }
+
+ XMLList child(XMLName xmlName)
+ {
+ if (xmlName == null)
+ return new XMLList(lib);
+
+ XMLList result;
+ if (xmlName.localName().equals("*"))
+ {
+ result = allChildNodes(xmlName.uri());
+ }
+ else
+ {
+ result = matchChildren(XmlCursor.TokenType.START, xmlName);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ XML getXmlChild(long index)
+ {
+ XML result = null;
+ XmlCursor curs = newCursor();
+
+ if (moveToChild(curs, index, false, true))
+ {
+ result = createXML(lib, curs);
+ }
+
+ curs.dispose();
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ int childIndex()
+ {
+ int index = 0;
+
+ XmlCursor curs = newCursor();
+
+ TokenType tt = curs.currentTokenType();
+ while (true)
+ {
+ if (tt.isText())
+ {
+ index++;
+ if (!curs.toPrevSibling())
+ {
+ break;
+ }
+ }
+ else if (tt.isStart())
+ {
+ tt = curs.toPrevToken();
+ if (tt.isEnd())
+ {
+ curs.toNextToken();
+ if (!curs.toPrevSibling())
+ {
+ break;
+ }
+
+ index++;
+ }
+ else
+ {
+ // Hit the parent start tag so get out we're down counting children.
+ break;
+ }
+ }
+ else if (tt.isComment() || tt.isProcinst())
+ {
+ curs.toPrevToken();
+ }
+ else
+ {
+ break;
+ }
+
+ tt = curs.currentTokenType();
+ }
+
+ index = curs.currentTokenType().isStartdoc() ? -1 : index;
+
+ curs.dispose();
+
+ return index;
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList children()
+ {
+ return allChildNodes(null);
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList comments()
+ {
+ return matchChildren(XmlCursor.TokenType.COMMENT);
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ boolean contains(Object xml)
+ {
+ boolean result = false;
+
+ if (xml instanceof XML)
+ {
+ result = equivalentXml(xml);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object copy()
+ {
+ XmlCursor srcCurs = newCursor();
+
+ if (srcCurs.isStartdoc())
+ {
+ srcCurs.toFirstContentToken();
+ }
+
+ XML xml = createEmptyXML(lib);
+
+ XmlCursor destCurs = xml.newCursor();
+ destCurs.toFirstContentToken();
+
+ srcCurs.copyXml(destCurs);
+
+ destCurs.dispose();
+ srcCurs.dispose();
+
+ return xml;
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ XMLList descendants(XMLName xmlName)
+ {
+ XMLList result;
+ if (xmlName.isAttributeName())
+ {
+ result = matchDescendantAttributes(xmlName);
+ }
+ else
+ {
+ result = matchDescendantChildren(xmlName);
+ }
+
+ return result;
+ }
+
+ /**
+ * The inScopeNamespaces method returns an Array of Namespace objects
+ * representing the namespaces in scope for this XML object in the
+ * context of its parent.
+ *
+ * @return Array of all Namespaces in scope for this XML Object.
+ */
+ Object[] inScopeNamespaces()
+ {
+ XmlCursor cursor = newCursor();
+ Object[] namespaces = NamespaceHelper.inScopeNamespaces(lib, cursor);
+ cursor.dispose();
+ return namespaces;
+ }
+
+ /**
+ *
+ * @param child
+ * @param xml
+ */
+ XML insertChildAfter(Object child, Object xml)
+ {
+ if (child == null)
+ {
+ // Spec says inserting after nothing is the same as prepending
+ prependChild(xml);
+ }
+ else if (child instanceof XML)
+ {
+ insertChild((XML) child, xml, APPEND_CHILD);
+ }
+
+ return this;
+ }
+
+ /**
+ *
+ * @param child
+ * @param xml
+ */
+ XML insertChildBefore(Object child, Object xml)
+ {
+ if (child == null)
+ {
+ // Spec says inserting before nothing is the same as appending
+ appendChild(xml);
+ }
+ else if (child instanceof XML)
+ {
+ insertChild((XML) child, xml, PREPEND_CHILD);
+ }
+
+ return this;
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasOwnProperty(XMLName xmlName)
+ {
+ boolean hasProperty = false;
+
+ if (prototypeFlag)
+ {
+ String property = xmlName.localName();
+ hasProperty = (0 != findPrototypeId(property));
+ }
+ else
+ {
+ hasProperty = (getPropertyList(xmlName).length() > 0);
+ }
+
+ return hasProperty;
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasComplexContent()
+ {
+ return !hasSimpleContent();
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasSimpleContent()
+ {
+ boolean simpleContent = false;
+
+ XmlCursor curs = newCursor();
+
+ if (curs.isAttr() || curs.isText()) {
+ return true;
+ }
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ simpleContent = !(curs.toFirstChild());
+
+ curs.dispose();
+
+ return simpleContent;
+ }
+
+ /**
+ * Length of an XML object is always 1, it's a list of XML objects of size 1.
+ *
+ * @return
+ */
+ int length()
+ {
+ return 1;
+ }
+
+ /**
+ *
+ * @return
+ */
+ String localName()
+ {
+ XmlCursor cursor = newCursor();
+ if (cursor.isStartdoc())
+ cursor.toFirstContentToken();
+
+ String name = null;
+
+ if(cursor.isStart() ||
+ cursor.isAttr() ||
+ cursor.isProcinst())
+ {
+ javax.xml.namespace.QName qname = cursor.getName();
+ name = qname.getLocalPart();
+ }
+ cursor.dispose();
+
+ return name;
+ }
+
+ /**
+ * The name method returns the qualified name associated with this XML object.
+ *
+ * @return The qualified name associated with this XML object.
+ */
+ QName name()
+ {
+ XmlCursor cursor = newCursor();
+ if (cursor.isStartdoc())
+ cursor.toFirstContentToken();
+
+ QName name = null;
+
+ if(cursor.isStart() ||
+ cursor.isAttr() ||
+ cursor.isProcinst())
+ {
+ javax.xml.namespace.QName qname = cursor.getName();
+ if(cursor.isProcinst())
+ {
+ name = new QName(lib, "", qname.getLocalPart(), "");
+ }
+ else
+ {
+ String uri = qname.getNamespaceURI();
+ String prefix = qname.getPrefix();
+ name = new QName(lib, uri, qname.getLocalPart(), prefix);
+ }
+ }
+
+ cursor.dispose();
+
+ return name;
+ }
+
+ /**
+ *
+ * @param prefix
+ * @return
+ */
+ Object namespace(String prefix)
+ {
+ XmlCursor cursor = newCursor();
+ if (cursor.isStartdoc())
+ {
+ cursor.toFirstContentToken();
+ }
+
+ Object result = null;
+
+ if (prefix == null)
+ {
+ if(cursor.isStart() ||
+ cursor.isAttr())
+ {
+ Object[] inScopeNS = NamespaceHelper.inScopeNamespaces(lib, cursor);
+ // XXX Is it reaaly necessary to create the second cursor?
+ XmlCursor cursor2 = newCursor();
+ if (cursor2.isStartdoc())
+ cursor2.toFirstContentToken();
+
+ result = NamespaceHelper.getNamespace(lib, cursor2, inScopeNS);
+
+ cursor2.dispose();
+ }
+ }
+ else
+ {
+ Map prefixToURI = NamespaceHelper.getAllNamespaces(lib, cursor);
+ String uri = (String)prefixToURI.get(prefix);
+ result = (uri == null) ? Undefined.instance : new Namespace(lib, prefix, uri);
+ }
+
+ cursor.dispose();
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object[] namespaceDeclarations()
+ {
+ XmlCursor cursor = newCursor();
+ Object[] namespaces = NamespaceHelper.namespaceDeclarations(lib, cursor);
+ cursor.dispose();
+ return namespaces;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object nodeKind()
+ {
+ String result;
+ XmlCursor.TokenType tt = tokenType();
+
+ if (tt == XmlCursor.TokenType.ATTR)
+ {
+ result = "attribute";
+ }
+ else if (tt == XmlCursor.TokenType.TEXT)
+ {
+ result = "text";
+ }
+ else if (tt == XmlCursor.TokenType.COMMENT)
+ {
+ result = "comment";
+ }
+ else if (tt == XmlCursor.TokenType.PROCINST)
+ {
+ result = "processing-instruction";
+ }
+ else if (tt == XmlCursor.TokenType.START)
+ {
+ result = "element";
+ }
+ else
+ {
+ // A non-existant node has the nodeKind() of text
+ result = "text";
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ */
+ void normalize()
+ {
+ XmlCursor curs = newCursor();
+ TokenType tt = curs.currentTokenType();
+
+ // Walk through the tokens removing empty text nodes and merging adjacent text nodes.
+ if (tt.isStartdoc())
+ {
+ tt = curs.toFirstContentToken();
+ }
+
+ if (tt.isContainer())
+ {
+ int nestLevel = 1;
+ String previousText = null;
+
+ while (nestLevel > 0)
+ {
+ tt = curs.toNextToken();
+
+ if (tt == XmlCursor.TokenType.TEXT)
+ {
+ String currentText = curs.getChars().trim();
+
+ if (currentText.trim().length() == 0)
+ {
+ // Empty text node, remove.
+ removeToken(curs);
+ curs.toPrevToken();
+ }
+ else if (previousText == null)
+ {
+ // No previous text node, reset to trimmed version
+ previousText = currentText;
+ }
+ else
+ {
+ // It appears that this case never happens with XBeans.
+ // Previous text node exists, concatenate
+ String newText = previousText + currentText;
+
+ curs.toPrevToken();
+ removeToken(curs);
+ removeToken(curs);
+ curs.insertChars(newText);
+ }
+ }
+ else
+ {
+ previousText = null;
+ }
+
+ if (tt.isStart())
+ {
+ nestLevel++;
+ }
+ else if (tt.isEnd())
+ {
+ nestLevel--;
+ }
+ else if (tt.isEnddoc())
+ {
+ // Shouldn't get here, but just in case.
+ break;
+ }
+ }
+ }
+
+
+ curs.dispose();
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object parent()
+ {
+ Object parent;
+
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ // At doc level - no parent
+ parent = Undefined.instance;
+ }
+ else
+ {
+ if (curs.toParent())
+ {
+ if (curs.isStartdoc())
+ {
+ // Was top-level - no parent
+ parent = Undefined.instance;
+ }
+ else
+ {
+ parent = getFromAnnotation(lib, findAnnotation(curs));
+ }
+ }
+ else
+ {
+ // No parent
+ parent = Undefined.instance;
+ }
+ }
+
+ curs.dispose();
+
+ return parent;
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ XML prependChild (Object xml)
+ {
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ // Move the cursor to the first content token
+ curs.toFirstContentToken();
+
+ insertChild(curs, xml);
+
+ curs.dispose();
+
+ return this;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object processingInstructions(XMLName xmlName)
+ {
+ return matchChildren(XmlCursor.TokenType.PROCINST, xmlName);
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ boolean propertyIsEnumerable(Object name)
+ {
+ boolean result;
+ if (name instanceof Integer) {
+ result = (((Integer)name).intValue() == 0);
+ } else if (name instanceof Number) {
+ double x = ((Number)name).doubleValue();
+ // Check that number is posotive 0
+ result = (x == 0.0 && 1.0 / x > 0);
+ } else {
+ result = ScriptRuntime.toString(name).equals("0");
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @param namespace
+ */
+ XML removeNamespace(Namespace ns)
+ {
+ XmlCursor cursor = newCursor();
+
+ try
+ {
+ if(cursor.isStartdoc())
+ cursor.toFirstContentToken();
+ if(!cursor.isStart()) return this;
+
+ String nsPrefix = ns.prefix();
+ String nsURI = ns.uri();
+ Map prefixToURI = new HashMap();
+ int depth = 1;
+
+ while(!(cursor.isEnd() && depth == 0))
+ {
+ if(cursor.isStart())
+ {
+ // Get the namespaces declared in this element.
+ // The ones with undefined prefixes are not candidates
+ // for removal because they are used.
+ prefixToURI.clear();
+ NamespaceHelper.getNamespaces(cursor, prefixToURI);
+ ObjArray inScopeNSBag = new ObjArray();
+ Iterator i = prefixToURI.entrySet().iterator();
+ while(i.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ ns = new Namespace(lib, (String)entry.getKey(), (String)entry.getValue());
+ inScopeNSBag.add(ns);
+ }
+
+ // Add the URI we are looking for to avoid matching
+ // non-existing Namespaces.
+ ns = new Namespace(lib, nsURI);
+ inScopeNSBag.add(ns);
+
+ Object[] inScopeNS = inScopeNSBag.toArray();
+
+ // Check the element name
+ Namespace n = NamespaceHelper.getNamespace(lib, cursor,
+ inScopeNS);
+ if(nsURI.equals(n.uri()) &&
+ (nsPrefix == null ||
+ nsPrefix.equals(n.prefix())))
+ {
+ // This namespace is used
+ return this;
+ }
+
+ // Check the attributes
+ cursor.push();
+ boolean hasNext = cursor.toFirstAttribute();
+ while(hasNext)
+ {
+ n = NamespaceHelper.getNamespace(lib, cursor, inScopeNS);
+ if(nsURI.equals(n.uri()) &&
+ (nsPrefix == null ||
+ nsPrefix.equals(n.prefix())))
+ {
+ // This namespace is used
+ return this;
+ }
+
+ hasNext = cursor.toNextAttribute();
+ }
+ cursor.pop();
+
+ if(nsPrefix == null)
+ {
+ // Remove all namespaces declarations that match nsURI
+ i = prefixToURI.entrySet().iterator();
+ while(i.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ if(entry.getValue().equals(nsURI))
+ NamespaceHelper.removeNamespace(cursor, (String)entry.getKey());
+ }
+ }
+ else if(nsURI.equals(prefixToURI.get(nsPrefix)))
+ {
+ // Remove the namespace declaration that matches nsPrefix
+ NamespaceHelper.removeNamespace(cursor, String.valueOf(nsPrefix));
+ }
+ }
+
+ switch(cursor.toNextToken().intValue())
+ {
+ case XmlCursor.TokenType.INT_START:
+ depth++;
+ break;
+ case XmlCursor.TokenType.INT_END:
+ depth--;
+ break;
+ }
+ }
+ }
+ finally
+ {
+ cursor.dispose();
+ }
+
+ return this;
+ }
+
+ XML replace(long index, Object xml)
+ {
+ XMLList xlChildToReplace = child(index);
+ if (xlChildToReplace.length() > 0)
+ {
+ // One exists an that index
+ XML childToReplace = xlChildToReplace.item(0);
+ insertChildAfter(childToReplace, xml);
+ removeChild(index);
+ }
+ return this;
+ }
+
+ /**
+ *
+ * @param propertyName
+ * @param xml
+ * @return
+ */
+ XML replace(XMLName xmlName, Object xml)
+ {
+ putXMLProperty(xmlName, xml);
+ return this;
+ }
+
+ /**
+ *
+ * @param xml
+ */
+ XML setChildren(Object xml)
+ {
+ // remove all children
+ XMLName xmlName = XMLName.formStar();
+ XMLList matches = getPropertyList(xmlName);
+ matches.remove();
+
+ // append new children
+ appendChild(xml);
+
+ return this;
+ }
+
+ /**
+ *
+ * @param name
+ */
+ void setLocalName(String localName)
+ {
+ XmlCursor cursor = newCursor();
+
+ try
+ {
+ if(cursor.isStartdoc())
+ cursor.toFirstContentToken();
+
+ if(cursor.isText() || cursor.isComment()) return;
+
+
+ javax.xml.namespace.QName qname = cursor.getName();
+ cursor.setName(new javax.xml.namespace.QName(
+ qname.getNamespaceURI(), localName, qname.getPrefix()));
+ }
+ finally
+ {
+ cursor.dispose();
+ }
+ }
+
+ /**
+ *
+ * @param name
+ */
+ void setName(QName qname)
+ {
+ XmlCursor cursor = newCursor();
+
+ try
+ {
+ if(cursor.isStartdoc())
+ cursor.toFirstContentToken();
+
+ if(cursor.isText() || cursor.isComment()) return;
+
+ if(cursor.isProcinst())
+ {
+ String localName = qname.localName();
+ cursor.setName(new javax.xml.namespace.QName(localName));
+ }
+ else
+ {
+ String prefix = qname.prefix();
+ if (prefix == null) { prefix = ""; }
+ cursor.setName(new javax.xml.namespace.QName(
+ qname.uri(), qname.localName(), prefix));
+ }
+ }
+ finally
+ {
+ cursor.dispose();
+ }
+ }
+
+ /**
+ *
+ * @param ns
+ */
+ void setNamespace(Namespace ns)
+ {
+ XmlCursor cursor = newCursor();
+
+ try
+ {
+ if(cursor.isStartdoc())
+ cursor.toFirstContentToken();
+
+ if(cursor.isText() ||
+ cursor.isComment() ||
+ cursor.isProcinst()) return;
+
+ String prefix = ns.prefix();
+ if (prefix == null) {
+ prefix = "";
+ }
+ cursor.setName(new javax.xml.namespace.QName(
+ ns.uri(), localName(), prefix));
+ }
+ finally
+ {
+ cursor.dispose();
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList text()
+ {
+ return matchChildren(XmlCursor.TokenType.TEXT);
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String toString()
+ {
+ String result;
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ if (curs.isText())
+ {
+ result = curs.getChars();
+ }
+ else if (curs.isStart() && hasSimpleContent())
+ {
+ result = curs.getTextValue();
+ }
+ else
+ {
+ result = toXMLString(0);
+ }
+
+ return result;
+ }
+
+ String toSource(int indent)
+ {
+ // XXX Does toXMLString always return valid XML literal?
+ return toXMLString(indent);
+ }
+
+ /**
+ *
+ * @return
+ */
+ String toXMLString(int indent)
+ {
+ // XXX indent is ignored
+
+ String result;
+
+ XmlCursor curs = newCursor();
+
+ if (curs.isStartdoc())
+ {
+ curs.toFirstContentToken();
+ }
+
+ try
+ {
+ if (curs.isText())
+ {
+ result = curs.getChars();
+ }
+ else if (curs.isAttr())
+ {
+ result = curs.getTextValue();
+ }
+ else if (curs.isComment() || curs.isProcinst())
+ {
+ result = XML.dumpNode(curs, getOptions());
+
+ // todo: XBeans-dependent hack here
+ // If it's a comment or PI, take off the xml-frament stuff
+ String start = "<xml-fragment>";
+ String end = "</xml-fragment>";
+
+ if (result.startsWith(start))
+ {
+ result = result.substring(start.length());
+ }
+
+ if (result.endsWith(end))
+ {
+ result = result.substring(0, result.length() - end.length());
+ }
+ }
+ else
+ {
+ result = XML.dumpNode(curs, getOptions());
+ }
+ }
+ finally
+ {
+ curs.dispose();
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object valueOf()
+ {
+ return this;
+ }
+
+ //
+ // Other public Functions from XMLObject
+ //
+
+ /**
+ *
+ * @param target
+ * @return
+ */
+ boolean equivalentXml(Object target)
+ {
+ boolean result = false;
+
+ if (target instanceof XML)
+ {
+ XML otherXml = (XML) target;
+
+ // Compare with toString() if either side is text node or attribute
+ // otherwise compare as XML
+ XmlCursor.TokenType thisTT = tokenType();
+ XmlCursor.TokenType otherTT = otherXml.tokenType();
+ if (thisTT == XmlCursor.TokenType.ATTR || otherTT == XmlCursor.TokenType.ATTR ||
+ thisTT == XmlCursor.TokenType.TEXT || otherTT == XmlCursor.TokenType.TEXT)
+ {
+ result = toString().equals(otherXml.toString());
+ }
+ else
+ {
+ XmlCursor cursOne = newCursor();
+ XmlCursor cursTwo = otherXml.newCursor();
+
+ result = LogicalEquality.nodesEqual(cursOne, cursTwo);
+
+ cursOne.dispose();
+ cursTwo.dispose();
+
+// Old way of comparing by string.
+// boolean orgPrettyPrinting = prototype.prettyPrinting;
+// prototype.prettyPrinting = true;
+// result = toXMLString(0).equals(otherXml.toXMLString(0));
+// prototype.prettyPrinting = orgPrettyPrinting;
+ }
+ }
+ else if (target instanceof XMLList)
+ {
+ XMLList otherList = (XMLList) target;
+
+ if (otherList.length() == 1)
+ {
+ result = equivalentXml(otherList.getXmlFromAnnotation(0));
+ }
+ }
+ else if (hasSimpleContent())
+ {
+ String otherStr = ScriptRuntime.toString(target);
+
+ result = toString().equals(otherStr);
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param name
+ * @param start
+ * @return
+ */
+ XMLList getPropertyList(XMLName name)
+ {
+ XMLList result;
+
+ // Get the named property
+ if (name.isDescendants())
+ {
+ result = descendants(name);
+ }
+ else if (name.isAttributeName())
+ {
+ result = attribute(name);
+ }
+ else
+ {
+ result = child(name);
+ }
+
+ return result;
+ }
+
+ protected Object jsConstructor(Context cx, boolean inNewExpr,
+ Object[] args)
+ {
+ if (args.length == 0) {
+ return createFromJS(lib, "");
+ } else {
+ Object arg0 = args[0];
+ if (!inNewExpr && arg0 instanceof XML) {
+ // XML(XML) returns the same object.
+ return arg0;
+ }
+ return createFromJS(lib, arg0);
+ }
+ }
+
+ /**
+ * See ECMA 357, 11_2_2_1, Semantics, 3_f.
+ */
+ public Scriptable getExtraMethodSource(Context cx)
+ {
+ if (hasSimpleContent()) {
+ String src = toString();
+ return ScriptRuntime.toObjectOrNull(cx, src);
+ }
+ return null;
+ }
+
+ XmlObject getXmlObject()
+ {
+ XmlObject xo;
+ XmlCursor cursor = newCursor();
+ try {
+ xo = cursor.getObject();
+ } finally {
+ cursor.dispose();
+ }
+ return xo;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.java
new file mode 100644
index 0000000..987c8ed
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLCtor.java
@@ -0,0 +1,269 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.*;
+
+class XMLCtor extends IdFunctionObject
+{
+ static final long serialVersionUID = -8708195078359817341L;
+
+ private static final Object XMLCTOR_TAG = new Object();
+
+ private XMLLibImpl lib;
+
+ XMLCtor(XML xml, Object tag, int id, int arity)
+ {
+ super(xml, tag, id, arity);
+ this.lib = xml.lib;
+ activatePrototypeMap(MAX_FUNCTION_ID);
+ }
+
+ private void writeSetting(Scriptable target)
+ {
+ for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
+ int id = super.getMaxInstanceId() + i;
+ String name = getInstanceIdName(id);
+ Object value = getInstanceIdValue(id);
+ ScriptableObject.putProperty(target, name, value);
+ }
+ }
+
+ private void readSettings(Scriptable source)
+ {
+ for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
+ int id = super.getMaxInstanceId() + i;
+ String name = getInstanceIdName(id);
+ Object value = ScriptableObject.getProperty(source, name);
+ if (value == Scriptable.NOT_FOUND) {
+ continue;
+ }
+ switch (i) {
+ case Id_ignoreComments:
+ case Id_ignoreProcessingInstructions:
+ case Id_ignoreWhitespace:
+ case Id_prettyPrinting:
+ if (!(value instanceof Boolean)) {
+ continue;
+ }
+ break;
+ case Id_prettyIndent:
+ if (!(value instanceof Number)) {
+ continue;
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ setInstanceIdValue(id, value);
+ }
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_ignoreComments = 1,
+ Id_ignoreProcessingInstructions = 2,
+ Id_ignoreWhitespace = 3,
+ Id_prettyIndent = 4,
+ Id_prettyPrinting = 5,
+
+ MAX_INSTANCE_ID = 5;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s) {
+ int id;
+// #generated# Last update: 2004-07-19 13:03:52 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 12: X="prettyIndent";id=Id_prettyIndent; break L;
+ case 14: c=s.charAt(0);
+ if (c=='i') { X="ignoreComments";id=Id_ignoreComments; }
+ else if (c=='p') { X="prettyPrinting";id=Id_prettyPrinting; }
+ break L;
+ case 16: X="ignoreWhitespace";id=Id_ignoreWhitespace; break L;
+ case 28: X="ignoreProcessingInstructions";id=Id_ignoreProcessingInstructions; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_ignoreComments:
+ case Id_ignoreProcessingInstructions:
+ case Id_ignoreWhitespace:
+ case Id_prettyIndent:
+ case Id_prettyPrinting:
+ attr = PERMANENT | DONTENUM;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments: return "ignoreComments";
+ case Id_ignoreProcessingInstructions: return "ignoreProcessingInstructions";
+ case Id_ignoreWhitespace: return "ignoreWhitespace";
+ case Id_prettyIndent: return "prettyIndent";
+ case Id_prettyPrinting: return "prettyPrinting";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments:
+ return ScriptRuntime.wrapBoolean(lib.ignoreComments);
+ case Id_ignoreProcessingInstructions:
+ return ScriptRuntime.wrapBoolean(lib.ignoreProcessingInstructions);
+ case Id_ignoreWhitespace:
+ return ScriptRuntime.wrapBoolean(lib.ignoreWhitespace);
+ case Id_prettyIndent:
+ return ScriptRuntime.wrapInt(lib.prettyIndent);
+ case Id_prettyPrinting:
+ return ScriptRuntime.wrapBoolean(lib.prettyPrinting);
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments:
+ lib.ignoreComments = ScriptRuntime.toBoolean(value);
+ return;
+ case Id_ignoreProcessingInstructions:
+ lib.ignoreProcessingInstructions = ScriptRuntime.toBoolean(value);
+ return;
+ case Id_ignoreWhitespace:
+ lib.ignoreWhitespace = ScriptRuntime.toBoolean(value);
+ return;
+ case Id_prettyIndent:
+ lib.prettyIndent = ScriptRuntime.toInt32(value);
+ return;
+ case Id_prettyPrinting:
+ lib.prettyPrinting = ScriptRuntime.toBoolean(value);
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+// #string_id_map#
+ private static final int
+ Id_defaultSettings = 1,
+ Id_settings = 2,
+ Id_setSettings = 3,
+ MAX_FUNCTION_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2004-07-19 13:03:52 CEST
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==8) { X="settings";id=Id_settings; }
+ else if (s_length==11) { X="setSettings";id=Id_setSettings; }
+ else if (s_length==15) { X="defaultSettings";id=Id_defaultSettings; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_defaultSettings: arity=0; s="defaultSettings"; break;
+ case Id_settings: arity=0; s="settings"; break;
+ case Id_setSettings: arity=1; s="setSettings"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(XMLCTOR_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(XMLCTOR_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_defaultSettings: {
+ lib.defaultSettings();
+ Scriptable obj = cx.newObject(scope);
+ writeSetting(obj);
+ return obj;
+ }
+ case Id_settings: {
+ Scriptable obj = cx.newObject(scope);
+ writeSetting(obj);
+ return obj;
+ }
+ case Id_setSettings: {
+ if (args.length == 0
+ || args[0] == null
+ || args[0] == Undefined.instance)
+ {
+ lib.defaultSettings();
+ } else if (args[0] instanceof Scriptable) {
+ readSettings((Scriptable)args[0]);
+ }
+ return Undefined.instance;
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.java
new file mode 100644
index 0000000..90da7d4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLLibImpl.java
@@ -0,0 +1,754 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import java.io.Serializable;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
+
+public final class XMLLibImpl extends XMLLib implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private Scriptable globalScope;
+
+ XML xmlPrototype;
+ XMLList xmlListPrototype;
+ Namespace namespacePrototype;
+ QName qnamePrototype;
+
+
+ // Environment settings...
+ boolean ignoreComments;
+ boolean ignoreProcessingInstructions;
+ boolean ignoreWhitespace;
+ boolean prettyPrinting;
+ int prettyIndent;
+
+ Scriptable globalScope()
+ {
+ return globalScope;
+ }
+
+ private XMLLibImpl(Scriptable globalScope)
+ {
+ this.globalScope = globalScope;
+ defaultSettings();
+ }
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+ // To force LinkageError if XmlObject is not available
+ XmlObject.class.getName();
+
+ XMLLibImpl lib = new XMLLibImpl(scope);
+ XMLLib bound = lib.bindToScope(scope);
+ if (bound == lib) {
+ lib.exportToScope(sealed);
+ }
+ }
+
+ private void exportToScope(boolean sealed)
+ {
+ xmlPrototype = XML.createEmptyXML(this);
+ xmlListPrototype = new XMLList(this);
+ namespacePrototype = new Namespace(this, "", "");
+ qnamePrototype = new QName(this, "", "", "");
+
+ xmlPrototype.exportAsJSClass(sealed);
+ xmlListPrototype.exportAsJSClass(sealed);
+ namespacePrototype.exportAsJSClass(sealed);
+ qnamePrototype.exportAsJSClass(sealed);
+ }
+
+ void defaultSettings()
+ {
+ ignoreComments = true;
+ ignoreProcessingInstructions = true;
+ ignoreWhitespace = true;
+ prettyPrinting = true;
+ prettyIndent = 2;
+ }
+
+ XMLName toAttributeName(Context cx, Object nameValue)
+ {
+ String uri;
+ String localName;
+
+ if (nameValue instanceof String) {
+ uri = "";
+ localName = (String)nameValue;
+ } else if (nameValue instanceof XMLName) {
+ XMLName xmlName = (XMLName)nameValue;
+ if (!xmlName.isAttributeName()) {
+ xmlName.setAttributeName();
+ }
+ return xmlName;
+ } else if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ uri = qname.uri();
+ localName = qname.localName();
+ } else if (nameValue instanceof Boolean
+ || nameValue instanceof Number
+ || nameValue == Undefined.instance
+ || nameValue == null)
+ {
+ throw badXMLName(nameValue);
+ } else {
+ uri = "";
+ localName = ScriptRuntime.toString(nameValue);
+ }
+ XMLName xmlName = XMLName.formProperty(uri, localName);
+ xmlName.setAttributeName();
+ return xmlName;
+ }
+
+ private static RuntimeException badXMLName(Object value)
+ {
+ String msg;
+ if (value instanceof Number) {
+ msg = "Can not construct XML name from number: ";
+ } else if (value instanceof Boolean) {
+ msg = "Can not construct XML name from boolean: ";
+ } else if (value == Undefined.instance || value == null) {
+ msg = "Can not construct XML name from ";
+ } else {
+ throw new IllegalArgumentException(value.toString());
+ }
+ return ScriptRuntime.typeError(msg+ScriptRuntime.toString(value));
+ }
+
+ XMLName toXMLName(Context cx, Object nameValue)
+ {
+ XMLName result;
+
+ if (nameValue instanceof XMLName) {
+ result = (XMLName)nameValue;
+ } else if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ result = XMLName.formProperty(qname.uri(), qname.localName());
+ } else if (nameValue instanceof String) {
+ result = toXMLNameFromString(cx, (String)nameValue);
+ } else if (nameValue instanceof Boolean
+ || nameValue instanceof Number
+ || nameValue == Undefined.instance
+ || nameValue == null)
+ {
+ throw badXMLName(nameValue);
+ } else {
+ String name = ScriptRuntime.toString(nameValue);
+ result = toXMLNameFromString(cx, name);
+ }
+
+ return result;
+ }
+
+ /**
+ * If value represents Uint32 index, make it available through
+ * ScriptRuntime.lastUint32Result(cx) and return null.
+ * Otherwise return the same value as toXMLName(cx, value).
+ */
+ XMLName toXMLNameOrIndex(Context cx, Object value)
+ {
+ XMLName result;
+
+ if (value instanceof XMLName) {
+ result = (XMLName)value;
+ } else if (value instanceof String) {
+ String str = (String)value;
+ long test = ScriptRuntime.testUint32String(str);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ result = null;
+ } else {
+ result = toXMLNameFromString(cx, str);
+ }
+ } else if (value instanceof Number) {
+ double d = ((Number)value).doubleValue();
+ long l = (long)d;
+ if (l == d && 0 <= l && l <= 0xFFFFFFFFL) {
+ ScriptRuntime.storeUint32Result(cx, l);
+ result = null;
+ } else {
+ throw badXMLName(value);
+ }
+ } else if (value instanceof QName) {
+ QName qname = (QName)value;
+ String uri = qname.uri();
+ boolean number = false;
+ result = null;
+ if (uri != null && uri.length() == 0) {
+ // Only in this case qname.toString() can resemble uint32
+ long test = ScriptRuntime.testUint32String(uri);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ number = true;
+ }
+ }
+ if (!number) {
+ result = XMLName.formProperty(uri, qname.localName());
+ }
+ } else if (value instanceof Boolean
+ || value == Undefined.instance
+ || value == null)
+ {
+ throw badXMLName(value);
+ } else {
+ String str = ScriptRuntime.toString(value);
+ long test = ScriptRuntime.testUint32String(str);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ result = null;
+ } else {
+ result = toXMLNameFromString(cx, str);
+ }
+ }
+
+ return result;
+ }
+
+ XMLName toXMLNameFromString(Context cx, String name)
+ {
+ if (name == null)
+ throw new IllegalArgumentException();
+
+ int l = name.length();
+ if (l != 0) {
+ char firstChar = name.charAt(0);
+ if (firstChar == '*') {
+ if (l == 1) {
+ return XMLName.formStar();
+ }
+ } else if (firstChar == '@') {
+ XMLName xmlName = XMLName.formProperty("", name.substring(1));
+ xmlName.setAttributeName();
+ return xmlName;
+ }
+ }
+
+ String uri = getDefaultNamespaceURI(cx);
+
+ return XMLName.formProperty(uri, name);
+ }
+
+ Namespace constructNamespace(Context cx, Object uriValue)
+ {
+ String prefix;
+ String uri;
+
+ if (uriValue instanceof Namespace) {
+ Namespace ns = (Namespace)uriValue;
+ prefix = ns.prefix();
+ uri = ns.uri();
+ } else if (uriValue instanceof QName) {
+ QName qname = (QName)uriValue;
+ uri = qname.uri();
+ if (uri != null) {
+ prefix = qname.prefix();
+ } else {
+ uri = qname.toString();
+ prefix = null;
+ }
+ } else {
+ uri = ScriptRuntime.toString(uriValue);
+ prefix = (uri.length() == 0) ? "" : null;
+ }
+
+ return new Namespace(this, prefix, uri);
+ }
+
+ Namespace castToNamespace(Context cx, Object namescapeObj)
+ {
+ if (namescapeObj instanceof Namespace) {
+ return (Namespace)namescapeObj;
+ }
+ return constructNamespace(cx, namescapeObj);
+ }
+
+ Namespace constructNamespace(Context cx)
+ {
+ return new Namespace(this, "", "");
+ }
+
+ public Namespace constructNamespace(Context cx, Object prefixValue,
+ Object uriValue)
+ {
+ String prefix;
+ String uri;
+
+ if (uriValue instanceof QName) {
+ QName qname = (QName)uriValue;
+ uri = qname.uri();
+ if (uri == null) {
+ uri = qname.toString();
+ }
+ } else {
+ uri = ScriptRuntime.toString(uriValue);
+ }
+
+ if (uri.length() == 0) {
+ if (prefixValue == Undefined.instance) {
+ prefix = "";
+ } else {
+ prefix = ScriptRuntime.toString(prefixValue);
+ if (prefix.length() != 0) {
+ throw ScriptRuntime.typeError(
+ "Illegal prefix '"+prefix+"' for 'no namespace'.");
+ }
+ }
+ } else if (prefixValue == Undefined.instance) {
+ prefix = "";
+ } else if (!isXMLName(cx, prefixValue)) {
+ prefix = "";
+ } else {
+ prefix = ScriptRuntime.toString(prefixValue);
+ }
+
+ return new Namespace(this, prefix, uri);
+ }
+
+ String getDefaultNamespaceURI(Context cx)
+ {
+ String uri = "";
+ if (cx == null) {
+ cx = Context.getCurrentContext();
+ }
+ if (cx != null) {
+ Object ns = ScriptRuntime.searchDefaultNamespace(cx);
+ if (ns != null) {
+ if (ns instanceof Namespace) {
+ uri = ((Namespace)ns).uri();
+ } else {
+ // Should not happen but for now it could
+ // due to bad searchDefaultNamespace implementation.
+ }
+ }
+ }
+ return uri;
+ }
+
+ Namespace getDefaultNamespace(Context cx)
+ {
+ if (cx == null) {
+ cx = Context.getCurrentContext();
+ if (cx == null) {
+ return namespacePrototype;
+ }
+ }
+
+ Namespace result;
+ Object ns = ScriptRuntime.searchDefaultNamespace(cx);
+ if (ns == null) {
+ result = namespacePrototype;
+ } else {
+ if (ns instanceof Namespace) {
+ result = (Namespace)ns;
+ } else {
+ // Should not happen but for now it could
+ // due to bad searchDefaultNamespace implementation.
+ result = namespacePrototype;
+ }
+ }
+ return result;
+ }
+
+ QName castToQName(Context cx, Object qnameValue)
+ {
+ if (qnameValue instanceof QName) {
+ return (QName)qnameValue;
+ }
+ return constructQName(cx, qnameValue);
+ }
+
+ QName constructQName(Context cx, Object nameValue)
+ {
+ QName result;
+
+ if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ result = new QName(this, qname.uri(), qname.localName(),
+ qname.prefix());
+ } else {
+ String localName = ScriptRuntime.toString(nameValue);
+ result = constructQNameFromString(cx, localName);
+ }
+
+ return result;
+ }
+
+ /**
+ * Optimized version of constructQName for String type
+ */
+ QName constructQNameFromString(Context cx, String localName)
+ {
+ if (localName == null)
+ throw new IllegalArgumentException();
+
+ String uri;
+ String prefix;
+
+ if ("*".equals(localName)) {
+ uri = null;
+ prefix = null;
+ } else {
+ Namespace ns = getDefaultNamespace(cx);
+ uri = ns.uri();
+ prefix = ns.prefix();
+ }
+
+ return new QName(this, uri, localName, prefix);
+ }
+
+ QName constructQName(Context cx, Object namespaceValue, Object nameValue)
+ {
+ String uri;
+ String localName;
+ String prefix;
+
+ if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ localName = qname.localName();
+ } else {
+ localName = ScriptRuntime.toString(nameValue);
+ }
+
+ Namespace ns;
+ if (namespaceValue == Undefined.instance) {
+ if ("*".equals(localName)) {
+ ns = null;
+ } else {
+ ns = getDefaultNamespace(cx);
+ }
+ } else if (namespaceValue == null) {
+ ns = null;
+ } else if (namespaceValue instanceof Namespace) {
+ ns = (Namespace)namespaceValue;
+ } else {
+ ns = constructNamespace(cx, namespaceValue);
+ }
+
+ if (ns == null) {
+ uri = null;
+ prefix = null;
+ } else {
+ uri = ns.uri();
+ prefix = ns.prefix();
+ }
+
+ return new QName(this, uri, localName, prefix);
+ }
+
+ Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
+ {
+ XMLList listToAdd = new XMLList(this);
+
+ if (obj1 instanceof XMLList) {
+ XMLList list1 = (XMLList)obj1;
+ if (list1.length() == 1) {
+ listToAdd.addToList(list1.item(0));
+ } else {
+ // Might be xmlFragment + xmlFragment + xmlFragment + ...;
+ // then the result will be an XMLList which we want to be an
+ // rValue and allow it to be assigned to an lvalue.
+ listToAdd = new XMLList(this, obj1);
+ }
+ } else {
+ listToAdd.addToList(obj1);
+ }
+
+ if (obj2 instanceof XMLList) {
+ XMLList list2 = (XMLList)obj2;
+ for (int i = 0; i < list2.length(); i++) {
+ listToAdd.addToList(list2.item(i));
+ }
+ } else if (obj2 instanceof XML) {
+ listToAdd.addToList(obj2);
+ }
+
+ return listToAdd;
+ }
+
+ //
+ //
+ // Overriding XMLLib methods
+ //
+ //
+
+ /**
+ * See E4X 13.1.2.1.
+ */
+ public boolean isXMLName(Context cx, Object nameObj)
+ {
+ String name;
+ try {
+ name = ScriptRuntime.toString(nameObj);
+ } catch (EcmaError ee) {
+ if ("TypeError".equals(ee.getName())) {
+ return false;
+ }
+ throw ee;
+ }
+
+ // See http://w3.org/TR/xml-names11/#NT-NCName
+ int length = name.length();
+ if (length != 0) {
+ if (isNCNameStartChar(name.charAt(0))) {
+ for (int i = 1; i != length; ++i) {
+ if (!isNCNameChar(name.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isNCNameStartChar(int c)
+ {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return (0xC0 <= c && c <= 0xD6)
+ || (0xD8 <= c && c <= 0xF6)
+ || (0xF8 <= c && c <= 0x2FF)
+ || (0x370 <= c && c <= 0x37D)
+ || 0x37F <= c;
+ }
+ return (0x200C <= c && c <= 0x200D)
+ || (0x2070 <= c && c <= 0x218F)
+ || (0x2C00 <= c && c <= 0x2FEF)
+ || (0x3001 <= c && c <= 0xD7FF)
+ || (0xF900 <= c && c <= 0xFDCF)
+ || (0xFDF0 <= c && c <= 0xFFFD)
+ || (0x10000 <= c && c <= 0xEFFFF);
+ }
+
+ private static boolean isNCNameChar(int c)
+ {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use - < . < 0..9 < A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ } else if (c >= '0') {
+ return c <= '9';
+ } else {
+ return c == '-' || c == '.';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return isNCNameStartChar(c) || c == 0xB7
+ || (0x300 <= c && c <= 0x36F);
+ }
+ return isNCNameStartChar(c) || (0x203F <= c && c <= 0x2040);
+ }
+
+ XMLName toQualifiedName(Context cx, Object namespaceValue,
+ Object nameValue)
+ {
+ // This is duplication of constructQName(cx, namespaceValue, nameValue)
+ // but for XMLName
+
+ String uri;
+ String localName;
+
+ if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ localName = qname.localName();
+ } else {
+ localName = ScriptRuntime.toString(nameValue);
+ }
+
+ Namespace ns;
+ if (namespaceValue == Undefined.instance) {
+ if ("*".equals(localName)) {
+ ns = null;
+ } else {
+ ns = getDefaultNamespace(cx);
+ }
+ } else if (namespaceValue == null) {
+ ns = null;
+ } else if (namespaceValue instanceof Namespace) {
+ ns = (Namespace)namespaceValue;
+ } else {
+ ns = constructNamespace(cx, namespaceValue);
+ }
+
+ if (ns == null) {
+ uri = null;
+ } else {
+ uri = ns.uri();
+ }
+
+ return XMLName.formProperty(uri, localName);
+ }
+
+ public Ref nameRef(Context cx, Object name,
+ Scriptable scope, int memberTypeFlags)
+ {
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) {
+ // should only be called foir cases like @name or @[expr]
+ throw Kit.codeBug();
+ }
+ XMLName xmlName = toAttributeName(cx, name);
+ return xmlPrimaryReference(cx, xmlName, scope);
+ }
+
+ public Ref nameRef(Context cx, Object namespace, Object name,
+ Scriptable scope, int memberTypeFlags)
+ {
+ XMLName xmlName = toQualifiedName(cx, namespace, name);
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
+ if (!xmlName.isAttributeName()) {
+ xmlName.setAttributeName();
+ }
+ }
+ return xmlPrimaryReference(cx, xmlName, scope);
+ }
+
+ private Ref xmlPrimaryReference(Context cx, XMLName xmlName,
+ Scriptable scope)
+ {
+ XMLObjectImpl xmlObj;
+ XMLObjectImpl firstXmlObject = null;
+ for (;;) {
+ // XML object can only present on scope chain as a wrapper
+ // of XMLWithScope
+ if (scope instanceof XMLWithScope) {
+ xmlObj = (XMLObjectImpl)scope.getPrototype();
+ if (xmlObj.hasXMLProperty(xmlName)) {
+ break;
+ }
+ if (firstXmlObject == null) {
+ firstXmlObject = xmlObj;
+ }
+ }
+ scope = scope.getParentScope();
+ if (scope == null) {
+ xmlObj = firstXmlObject;
+ break;
+ }
+ }
+
+ // xmlObj == null corresponds to undefined as the target of
+ // the reference
+ if (xmlObj != null) {
+ xmlName.initXMLObject(xmlObj);
+ }
+ return xmlName;
+ }
+
+ /**
+ * Escapes the reserved characters in a value of an attribute
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public String escapeAttributeValue(Object value)
+ {
+ String text = ScriptRuntime.toString(value);
+
+ if (text.length() == 0) return "";
+
+ XmlObject xo = XmlObject.Factory.newInstance();
+
+ XmlCursor cursor = xo.newCursor();
+ cursor.toNextToken();
+ cursor.beginElement("a");
+ cursor.insertAttributeWithValue("a", text);
+ cursor.dispose();
+
+ String elementText = xo.toString();
+ int begin = elementText.indexOf('"');
+ int end = elementText.lastIndexOf('"');
+ return elementText.substring(begin + 1, end);
+ }
+
+ /**
+ * Escapes the reserved characters in a value of a text node
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public String escapeTextValue(Object value)
+ {
+ if (value instanceof XMLObjectImpl) {
+ return ((XMLObjectImpl)value).toXMLString(0);
+ }
+
+ String text = ScriptRuntime.toString(value);
+
+ if (text.length() == 0) return text;
+
+ XmlObject xo = XmlObject.Factory.newInstance();
+
+ XmlCursor cursor = xo.newCursor();
+ cursor.toNextToken();
+ cursor.beginElement("a");
+ cursor.insertChars(text);
+ cursor.dispose();
+
+ String elementText = xo.toString();
+ int begin = elementText.indexOf('>') + 1;
+ int end = elementText.lastIndexOf('<');
+ return (begin < end) ? elementText.substring(begin, end) : "";
+ }
+
+ public Object toDefaultXmlNamespace(Context cx, Object uriValue)
+ {
+ return constructNamespace(cx, uriValue);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.java
new file mode 100644
index 0000000..b66ec96
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLList.java
@@ -0,0 +1,1617 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import java.util.Vector;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+import org.apache.xmlbeans.XmlCursor;
+
+class XMLList extends XMLObjectImpl implements Function
+{
+ static final long serialVersionUID = -4543618751670781135L;
+
+ static class AnnotationList
+ {
+ private Vector v;
+
+
+ AnnotationList ()
+ {
+ v = new Vector();
+ }
+
+
+ void add (XML.XScriptAnnotation n)
+ {
+ v.add(n);
+ }
+
+
+ XML.XScriptAnnotation item(int index)
+ {
+ return (XML.XScriptAnnotation)(v.get(index));
+ }
+
+
+ void remove (int index)
+ {
+ v.remove(index);
+ }
+
+
+ int length()
+ {
+ return v.size();
+ }
+ };
+
+
+ // Fields
+ private AnnotationList _annos;
+
+ private XMLObjectImpl targetObject = null;
+ private javax.xml.namespace.QName targetProperty = null;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Constructors
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ XMLList(XMLLibImpl lib)
+ {
+ super(lib, lib.xmlListPrototype);
+ _annos = new AnnotationList();
+ }
+
+ /**
+ *
+ * @param inputObject
+ */
+ XMLList(XMLLibImpl lib, Object inputObject)
+ {
+ super(lib, lib.xmlListPrototype);
+ String frag;
+
+ if (inputObject == null || inputObject instanceof Undefined)
+ {
+ frag = "";
+ }
+ else if (inputObject instanceof XML)
+ {
+ XML xml = (XML) inputObject;
+
+ _annos = new AnnotationList();
+ _annos.add(xml.getAnnotation());
+ }
+ else if (inputObject instanceof XMLList)
+ {
+ XMLList xmll = (XMLList) inputObject;
+
+ _annos = new AnnotationList();
+
+ for (int i = 0; i < xmll._annos.length(); i++)
+ {
+ _annos.add(xmll._annos.item(i));
+ }
+ }
+ else
+ {
+ frag = ScriptRuntime.toString(inputObject).trim();
+
+ if (!frag.startsWith("<>"))
+ {
+ frag = "<>" + frag + "</>";
+ }
+
+ frag = "<fragment>" + frag.substring(2);
+ if (!frag.endsWith("</>"))
+ {
+ throw ScriptRuntime.typeError("XML with anonymous tag missing end anonymous tag");
+ }
+
+ frag = frag.substring(0, frag.length() - 3) + "</fragment>";
+
+ XML orgXML = XML.createFromJS(lib, frag);
+
+ // Now orphan the children and add them to our XMLList.
+ XMLList children = orgXML.children();
+
+ _annos = new AnnotationList();
+
+ for (int i = 0; i < children._annos.length(); i++)
+ {
+ // Copy here is so that they'll be orphaned (parent() will be undefined)
+ _annos.add(((XML) children.item(i).copy()).getAnnotation());
+ }
+ }
+ }
+
+ //
+ //
+ // TargetObject/Property accessors
+ //
+ //
+
+ /**
+ *
+ * @param object
+ * @param property
+ */
+ void setTargets(XMLObjectImpl object, javax.xml.namespace.QName property)
+ {
+ targetObject = object;
+ targetProperty = property;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Private functions
+ //
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ XML getXmlFromAnnotation(int index)
+ {
+ XML retVal;
+
+ if (index >= 0 && index < length())
+ {
+ XML.XScriptAnnotation anno = _annos.item(index);
+ retVal = XML.getFromAnnotation(lib, anno);
+ }
+ else
+ {
+ retVal = null;
+ }
+
+ return retVal;
+ }
+
+ /**
+ *
+ * @param index
+ */
+ private void internalRemoveFromList (int index)
+ {
+ _annos.remove(index);
+ }
+
+ /**
+ *
+ * @param index
+ * @param xml
+ */
+ void replace(int index, XML xml)
+ {
+ if (index < length())
+ {
+ AnnotationList newAnnoList = new AnnotationList();
+
+ // Copy upto item to replace.
+ for (int i = 0; i < index; i++)
+ {
+ newAnnoList.add(_annos.item(i));
+ }
+
+ newAnnoList.add(xml.getAnnotation());
+
+ // Skip over old item we're going to replace we've already add new item on above line.
+ for (int i = index + 1; i < length(); i++)
+ {
+ newAnnoList.add(_annos.item(i));
+ }
+
+ _annos = newAnnoList;
+ }
+ }
+
+ /**
+ *
+ * @param index
+ * @param xml
+ */
+ private void insert(int index, XML xml)
+ {
+ if (index < length())
+ {
+ AnnotationList newAnnoList = new AnnotationList();
+
+ // Copy upto item to insert.
+ for (int i = 0; i < index; i++)
+ {
+ newAnnoList.add(_annos.item(i));
+ }
+
+ newAnnoList.add(xml.getAnnotation());
+
+ for (int i = index; i < length(); i++)
+ {
+ newAnnoList.add(_annos.item(i));
+ }
+
+ _annos = newAnnoList;
+ }
+ }
+
+ //
+ //
+ // methods overriding ScriptableObject
+ //
+ //
+
+ public String getClassName ()
+ {
+ return "XMLList";
+ }
+
+ //
+ //
+ // methods overriding IdScriptableObject
+ //
+ //
+
+ /**
+ *
+ * @param index
+ * @param start
+ * @return
+ */
+ public Object get(int index, Scriptable start)
+ {
+ //Log("get index: " + index);
+
+ if (index >= 0 && index < length())
+ {
+ return getXmlFromAnnotation(index);
+ }
+ else
+ {
+ return Scriptable.NOT_FOUND;
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @param start
+ * @return
+ */
+ boolean hasXMLProperty(XMLName xmlName)
+ {
+ boolean result = false;
+
+ // Has now should return true if the property would have results > 0 or
+ // if it's a method name
+ String name = xmlName.localName();
+ if ((getPropertyList(xmlName).length() > 0) ||
+ (getMethod(name) != NOT_FOUND))
+ {
+ result = true;
+ }
+
+ return result;
+ }
+
+
+ /**
+ *
+ * @param index
+ * @param start
+ * @return
+ */
+ public boolean has(int index, Scriptable start)
+ {
+ return 0 <= index && index < length();
+ }
+
+ /**
+ *
+ * @param name
+ * @param value
+ */
+ void putXMLProperty(XMLName xmlName, Object value)
+ {
+ //Log("put property: " + name);
+
+ // Special-case checks for undefined and null
+ if (value == null)
+ {
+ value = "null";
+ }
+ else if (value instanceof Undefined)
+ {
+ value = "undefined";
+ }
+
+ if (length() > 1)
+ {
+ throw ScriptRuntime.typeError("Assignment to lists with more that one item is not supported");
+ }
+ else if (length() == 0)
+ {
+ // Secret sauce for super-expandos.
+ // We set an element here, and then add ourselves to our target.
+ if (targetObject != null &&
+ targetProperty != null &&
+ !targetProperty.getLocalPart().equals("*"))
+ {
+ // Add an empty element with our targetProperty name and then set it.
+ XML xmlValue = XML.createTextElement(lib, targetProperty, "");
+ addToList(xmlValue);
+
+ if(xmlName.isAttributeName())
+ {
+ setAttribute(xmlName, value);
+ }
+ else
+ {
+ XML xml = item(0);
+ xml.putXMLProperty(xmlName, value);
+
+ // Update the list with the new item at location 0.
+ replace(0, item(0));
+ }
+
+ // Now add us to our parent
+ XMLName name2 = XMLName.formProperty(targetProperty.getNamespaceURI(), targetProperty.getLocalPart());
+ targetObject.putXMLProperty(name2, this);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("Assignment to empty XMLList without targets not supported");
+ }
+ }
+ else if(xmlName.isAttributeName())
+ {
+ setAttribute(xmlName, value);
+ }
+ else
+ {
+ XML xml = item(0);
+ xml.putXMLProperty(xmlName, value);
+
+ // Update the list with the new item at location 0.
+ replace(0, item(0));
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ Object getXMLProperty(XMLName name)
+ {
+ return getPropertyList(name);
+ }
+
+ /**
+ *
+ * @param index
+ * @param value
+ */
+ public void put(int index, Scriptable start, Object value)
+ {
+ Object parent = Undefined.instance;
+ // Convert text into XML if needed.
+ XMLObject xmlValue;
+
+ // Special-case checks for undefined and null
+ if (value == null)
+ {
+ value = "null";
+ }
+ else if (value instanceof Undefined)
+ {
+ value = "undefined";
+ }
+
+ if (value instanceof XMLObject)
+ {
+ xmlValue = (XMLObject) value;
+ }
+ else
+ {
+ if (targetProperty == null)
+ {
+ xmlValue = XML.createFromJS(lib, value.toString());
+ }
+ else
+ {
+ xmlValue = XML.createTextElement(lib, targetProperty, value.toString());
+ }
+ }
+
+ // Find the parent
+ if (index < length())
+ {
+ parent = item(index).parent();
+ }
+ else
+ {
+ // Appending
+ parent = parent();
+ }
+
+ if (parent instanceof XML)
+ {
+ // found parent, alter doc
+ XML xmlParent = (XML) parent;
+
+ if (index < length())
+ {
+ // We're replacing the the node.
+ XML xmlNode = getXmlFromAnnotation(index);
+
+ if (xmlValue instanceof XML)
+ {
+ xmlNode.replaceAll((XML) xmlValue);
+ replace(index, xmlNode);
+ }
+ else if (xmlValue instanceof XMLList)
+ {
+ // Replace the first one, and add the rest on the list.
+ XMLList list = (XMLList) xmlValue;
+
+ if (list.length() > 0)
+ {
+ int lastIndexAdded = xmlNode.childIndex();
+ xmlNode.replaceAll(list.item(0));
+ replace(index, list.item(0));
+
+ for (int i = 1; i < list.length(); i++)
+ {
+ xmlParent.insertChildAfter(xmlParent.getXmlChild(lastIndexAdded), list.item(i));
+ lastIndexAdded++;
+ insert(index + i, list.item(i));
+ }
+ }
+ }
+ }
+ else
+ {
+ // Appending
+ xmlParent.appendChild(xmlValue);
+ addToList(xmlParent.getXmlChild(index));
+ }
+ }
+ else
+ {
+ // Don't all have same parent, no underlying doc to alter
+ if (index < length())
+ {
+ XML xmlNode = XML.getFromAnnotation(lib, _annos.item(index));
+
+ if (xmlValue instanceof XML)
+ {
+ xmlNode.replaceAll((XML) xmlValue);
+ replace(index, xmlNode);
+ }
+ else if (xmlValue instanceof XMLList)
+ {
+ // Replace the first one, and add the rest on the list.
+ XMLList list = (XMLList) xmlValue;
+
+ if (list.length() > 0)
+ {
+ xmlNode.replaceAll(list.item(0));
+ replace(index, list.item(0));
+
+ for (int i = 1; i < list.length(); i++)
+ {
+ insert(index + i, list.item(i));
+ }
+ }
+ }
+ }
+ else
+ {
+ addToList(xmlValue);
+ }
+ }
+ }
+
+
+ /**
+ *
+ * @param name
+ */
+ void deleteXMLProperty(XMLName name)
+ {
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+
+ if (xml.tokenType() == XmlCursor.TokenType.START)
+ {
+ xml.deleteXMLProperty(name);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param index
+ */
+ public void delete(int index)
+ {
+ if (index >= 0 && index < length())
+ {
+ XML xml = getXmlFromAnnotation(index);
+
+ xml.remove();
+
+ internalRemoveFromList(index);
+ }
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public Object[] getIds()
+ {
+ Object enumObjs[];
+
+ if (prototypeFlag)
+ {
+ enumObjs = new Object[0];
+ }
+ else
+ {
+ enumObjs = new Object[length()];
+
+ for (int i = 0; i < enumObjs.length; i++)
+ {
+ enumObjs[i] = new Integer(i);
+ }
+ }
+
+ return enumObjs;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Object[] getIdsForDebug()
+ {
+ return getIds();
+ }
+
+
+ // XMLList will remove will delete all items in the list (a set delete) this differs from the XMLList delete operator.
+ void remove ()
+ {
+ int nLen = length();
+ for (int i = nLen - 1; i >= 0; i--)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ if (xml != null)
+ {
+ xml.remove();
+ internalRemoveFromList(i);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ XML item (int index)
+ {
+ return _annos != null
+ ? getXmlFromAnnotation(index) : XML.createEmptyXML(lib);
+ }
+
+
+ /**
+ *
+ * @param name
+ * @param value
+ */
+ private void setAttribute (XMLName xmlName, Object value)
+ {
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ xml.setAttribute(xmlName, value);
+ }
+ }
+
+
+ /**
+ *
+ * @param toAdd
+ */
+ void addToList(Object toAdd)
+ {
+ if (toAdd instanceof Undefined)
+ {
+ // Missing argument do nothing...
+ return;
+ }
+
+ if (toAdd instanceof XMLList)
+ {
+ XMLList xmlSrc = (XMLList)toAdd;
+ for (int i = 0; i < xmlSrc.length(); i++)
+ {
+ _annos.add((xmlSrc.item(i)).getAnnotation());
+ }
+ }
+ else if (toAdd instanceof XML)
+ {
+ _annos.add(((XML)(toAdd)).getAnnotation());
+ }
+ else if (toAdd instanceof XML.XScriptAnnotation)
+ {
+ _annos.add((XML.XScriptAnnotation)toAdd);
+ }
+ }
+
+ //
+ //
+ // Methods from section 12.4.4 in the spec
+ //
+ //
+
+ /**
+ *
+ * @param toAdd
+ */
+ XML addNamespace(Namespace ns)
+ {
+ if(length() == 1)
+ {
+ return getXmlFromAnnotation(0).addNamespace(ns);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The addNamespace method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ XML appendChild(Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).appendChild(xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The appendChild method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param attr
+ * @return
+ */
+ XMLList attribute(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.attribute(xmlName));
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList attributes()
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.attributes());
+ }
+
+ return result;
+ }
+
+ XMLList child(long index)
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ result.addToList(getXmlFromAnnotation(i).child(index));
+ }
+
+ return result;
+ }
+
+ XMLList child(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ result.addToList(getXmlFromAnnotation(i).child(xmlName));
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ int childIndex()
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).childIndex();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The childIndex method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList children()
+ {
+ Vector v = new Vector();
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+
+ if (xml != null)
+ {
+ Object o = xml.children();
+ if (o instanceof XMLList)
+ {
+ XMLList childList = (XMLList)o;
+
+ int cChildren = childList.length();
+ for (int j = 0; j < cChildren; j++)
+ {
+ v.addElement(childList.item(j));
+ }
+ }
+ }
+ }
+
+ XMLList allChildren = new XMLList(lib);
+ int sz = v.size();
+
+ for (int i = 0; i < sz; i++)
+ {
+ allChildren.addToList(v.get(i));
+ }
+
+ return allChildren;
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList comments()
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+
+ result.addToList(xml.comments());
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ boolean contains(Object xml)
+ {
+ boolean result = false;
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML member = getXmlFromAnnotation(i);
+
+ if (member.equivalentXml(xml))
+ {
+ result = true;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object copy()
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.copy());
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ XMLList descendants(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.descendants(xmlName));
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object[] inScopeNamespaces()
+ {
+ if(length() == 1)
+ {
+ return getXmlFromAnnotation(0).inScopeNamespaces();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The inScopeNamespaces method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param child
+ * @param xml
+ */
+ XML insertChildAfter(Object child, Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).insertChildAfter(child, xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The insertChildAfter method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param child
+ * @param xml
+ */
+ XML insertChildBefore(Object child, Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).insertChildAfter(child, xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The insertChildBefore method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasOwnProperty(XMLName xmlName)
+ {
+ boolean hasProperty = false;
+
+ if (prototypeFlag)
+ {
+ String property = xmlName.localName();
+ hasProperty = (0 != findPrototypeId(property));
+ }
+ else
+ {
+ hasProperty = (getPropertyList(xmlName).length() > 0);
+ }
+
+ return hasProperty;
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasComplexContent()
+ {
+ boolean complexContent;
+ int length = length();
+
+ if (length == 0)
+ {
+ complexContent = false;
+ }
+ else if (length == 1)
+ {
+ complexContent = getXmlFromAnnotation(0).hasComplexContent();
+ }
+ else
+ {
+ complexContent = false;
+
+ for (int i = 0; i < length; i++)
+ {
+ XML nextElement = getXmlFromAnnotation(i);
+ if (nextElement.tokenType() == XmlCursor.TokenType.START)
+ {
+ complexContent = true;
+ break;
+ }
+ }
+ }
+
+ return complexContent;
+ }
+
+ /**
+ *
+ * @return
+ */
+ boolean hasSimpleContent()
+ {
+ boolean simpleContent;
+ int length = length();
+
+ if (length == 0)
+ {
+ simpleContent = true;
+ }
+ else if (length == 1)
+ {
+ simpleContent = getXmlFromAnnotation(0).hasSimpleContent();
+ }
+ else
+ {
+ simpleContent = true;
+
+ for (int i = 0; i < length; i++)
+ {
+ XML nextElement = getXmlFromAnnotation(i);
+ if (nextElement.tokenType() == XmlCursor.TokenType.START)
+ {
+ simpleContent = false;
+ break;
+ }
+ }
+ }
+
+ return simpleContent;
+ }
+
+ /**
+ *
+ * @return
+ */
+ int length()
+ {
+ int result = 0;
+
+ if (_annos != null)
+ {
+ result = _annos.length();
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ String localName()
+ {
+ if (length() == 1)
+ {
+ return name().localName();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The localName method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ QName name()
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).name();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The name method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param prefix
+ * @return
+ */
+ Object namespace(String prefix)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).namespace(prefix);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The namespace method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object[] namespaceDeclarations()
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).namespaceDeclarations();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The namespaceDeclarations method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object nodeKind()
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).nodeKind();
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The nodeKind method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ */
+ void normalize()
+ {
+ for (int i = 0; i < length(); i++)
+ {
+ getXmlFromAnnotation(i).normalize();
+ }
+ }
+
+ /**
+ * If list is empty, return undefined, if elements have different parents return undefined,
+ * If they all have the same parent, return that parent.
+ *
+ * @return
+ */
+ Object parent()
+ {
+ Object sameParent = Undefined.instance;
+
+ if ((length() == 0) && (targetObject != null) && (targetObject instanceof XML))
+ {
+ sameParent = targetObject;
+ }
+ else
+ {
+ for (int i = 0; i < length(); i++)
+ {
+ Object currParent = getXmlFromAnnotation(i).parent();
+
+ if (i == 0)
+ {
+ // Set the first for the rest to compare to.
+ sameParent = currParent;
+ }
+ else if (sameParent != currParent)
+ {
+ sameParent = Undefined.instance;
+ break;
+ }
+ }
+ }
+
+ // If everything in the list is the sameParent then return that as the parent.
+ return sameParent;
+ }
+
+ /**
+ *
+ * @param xml
+ * @return
+ */
+ XML prependChild(Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).prependChild(xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The prependChild method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object processingInstructions(XMLName xmlName)
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ XML xml = getXmlFromAnnotation(i);
+
+ result.addToList(xml.processingInstructions(xmlName));
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ boolean propertyIsEnumerable(Object name)
+ {
+ long index;
+ if (name instanceof Integer) {
+ index = ((Integer)name).intValue();
+ } else if (name instanceof Number) {
+ double x = ((Number)name).doubleValue();
+ index = (long)x;
+ if (index != x) {
+ return false;
+ }
+ if (index == 0 && 1.0 / x < 0) {
+ // Negative 0
+ return false;
+ }
+ } else {
+ String s = ScriptRuntime.toString(name);
+ index = ScriptRuntime.testUint32String(s);
+ }
+ return (0 <= index && index < length());
+ }
+
+ /**
+ *
+ * @param ns
+ */
+ XML removeNamespace(Namespace ns)
+ {
+ if(length() == 1)
+ {
+ return getXmlFromAnnotation(0).removeNamespace(ns);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The removeNamespace method works only on lists containing one item");
+ }
+ }
+
+ XML replace(long index, Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).replace(index, xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The replace method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param propertyName
+ * @param xml
+ * @return
+ */
+ XML replace(XMLName xmlName, Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).replace(xmlName, xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The replace method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param xml
+ */
+ XML setChildren(Object xml)
+ {
+ if (length() == 1)
+ {
+ return getXmlFromAnnotation(0).setChildren(xml);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The setChildren method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param name
+ */
+ void setLocalName(String localName)
+ {
+ if (length() == 1)
+ {
+ getXmlFromAnnotation(0).setLocalName(localName);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The setLocalName method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param name
+ */
+ void setName(QName qname)
+ {
+ if (length() == 1)
+ {
+ getXmlFromAnnotation(0).setName(qname);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The setName method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * @param ns
+ */
+ void setNamespace(Namespace ns)
+ {
+ if (length() == 1)
+ {
+ getXmlFromAnnotation(0).setNamespace(ns);
+ }
+ else
+ {
+ throw ScriptRuntime.typeError("The setNamespace method works only on lists containing one item");
+ }
+ }
+
+ /**
+ *
+ * * @return
+ */
+ XMLList text()
+ {
+ XMLList result = new XMLList(lib);
+
+ for (int i = 0; i < length(); i++)
+ {
+ result.addToList(getXmlFromAnnotation(i).text());
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String toString()
+ {
+ if (hasSimpleContent())
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for(int i = 0; i < length(); i++)
+ {
+ XML next = getXmlFromAnnotation(i);
+ sb.append(next.toString());
+ }
+
+ return sb.toString();
+ }
+ else
+ {
+ return toXMLString(0);
+ }
+ }
+
+ String toSource(int indent)
+ {
+ // XXX indent is ignored
+ return "<>"+toXMLString(0)+"</>";
+ }
+
+ /**
+ *
+ * @return
+ */
+ String toXMLString(int indent)
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for(int i = 0; i < length(); i++)
+ {
+ if (i > 0)
+ {
+ sb.append('\n');
+ }
+
+ sb.append(getXmlFromAnnotation(i).toXMLString(indent));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ *
+ * @return
+ */
+ Object valueOf()
+ {
+ return this;
+ }
+
+ //
+ // Other public Functions from XMLObject
+ //
+
+ /**
+ *
+ * @param target
+ * @return
+ */
+ boolean equivalentXml(Object target)
+ {
+ boolean result = false;
+
+ // Zero length list should equate to undefined
+ if (target instanceof Undefined && length() == 0)
+ {
+ result = true;
+ }
+ else if (length() == 1)
+ {
+ result = getXmlFromAnnotation(0).equivalentXml(target);
+ }
+ else if (target instanceof XMLList)
+ {
+ XMLList otherList = (XMLList) target;
+
+ if (otherList.length() == length())
+ {
+ result = true;
+
+ for (int i = 0; i < length(); i++)
+ {
+ if (!getXmlFromAnnotation(i).equivalentXml(otherList.getXmlFromAnnotation(i)))
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ *
+ * @param name
+ * @param start
+ * @return
+ */
+ private XMLList getPropertyList(XMLName name)
+ {
+ XMLList propertyList = new XMLList(lib);
+ javax.xml.namespace.QName qname = null;
+
+ if (!name.isDescendants() && !name.isAttributeName())
+ {
+ // Only set the targetProperty if this is a regular child get
+ // and not a descendant or attribute get
+ qname = new javax.xml.namespace.QName(name.uri(), name.localName());
+ }
+
+ propertyList.setTargets(this, qname);
+
+ for (int i = 0; i < length(); i++)
+ {
+ propertyList.addToList(
+ getXmlFromAnnotation(i).getPropertyList(name));
+ }
+
+ return propertyList;
+ }
+
+ private Object applyOrCall(boolean isApply,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ String methodName = isApply ? "apply" : "call";
+ if(!(thisObj instanceof XMLList) ||
+ ((XMLList)thisObj).targetProperty == null)
+ throw ScriptRuntime.typeError1("msg.isnt.function",
+ methodName);
+
+ return ScriptRuntime.applyOrCall(isApply, cx, scope, thisObj, args);
+ }
+
+ protected Object jsConstructor(Context cx, boolean inNewExpr,
+ Object[] args)
+ {
+ if (args.length == 0) {
+ return new XMLList(lib);
+ } else {
+ Object arg0 = args[0];
+ if (!inNewExpr && arg0 instanceof XMLList) {
+ // XMLList(XMLList) returns the same object.
+ return arg0;
+ }
+ return new XMLList(lib, arg0);
+ }
+ }
+
+ org.apache.xmlbeans.XmlObject getXmlObject()
+ {
+ if (length() == 1) {
+ return getXmlFromAnnotation(0).getXmlObject();
+ } else {
+ throw ScriptRuntime.typeError("getXmlObject method works only on lists containing one item");
+ }
+ }
+
+ /**
+ * See ECMA 357, 11_2_2_1, Semantics, 3_e.
+ */
+ public Scriptable getExtraMethodSource(Context cx)
+ {
+ if (length() == 1) {
+ return getXmlFromAnnotation(0);
+ }
+ return null;
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ // This XMLList is being called as a Function.
+ // Let's find the real Function object.
+ if(targetProperty == null)
+ throw ScriptRuntime.notFunctionError(this);
+
+ String methodName = targetProperty.getLocalPart();
+
+ boolean isApply = methodName.equals("apply");
+ if(isApply || methodName.equals("call"))
+ return applyOrCall(isApply, cx, scope, thisObj, args);
+
+ Callable method = ScriptRuntime.getElemFunctionAndThis(
+ this, methodName, cx);
+ // Call lastStoredScriptable to clear stored thisObj
+ // but ignore the result as the method should use the supplied
+ // thisObj, not one from redirected call
+ ScriptRuntime.lastStoredScriptable(cx);
+ return method.call(cx, scope, thisObj, args);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ throw ScriptRuntime.typeError1("msg.not.ctor", "XMLList");
+ }
+}
+
+
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.java
new file mode 100644
index 0000000..8ff972e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLName.java
@@ -0,0 +1,171 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Kit;
+import org.mozilla.javascript.Ref;
+import org.mozilla.javascript.ScriptRuntime;
+import org.mozilla.javascript.Undefined;
+
+class XMLName extends Ref
+{
+ static final long serialVersionUID = 3832176310755686977L;
+
+ private String uri;
+ private String localName;
+ private boolean isAttributeName;
+ private boolean isDescendants;
+ private XMLObjectImpl xmlObject;
+
+ private XMLName(String uri, String localName)
+ {
+ this.uri = uri;
+ this.localName = localName;
+ }
+
+ static XMLName formStar()
+ {
+ return new XMLName(null, "*");
+ }
+
+ static XMLName formProperty(String uri, String localName)
+ {
+ return new XMLName(uri, localName);
+ }
+
+ void initXMLObject(XMLObjectImpl xmlObject)
+ {
+ if (xmlObject == null) throw new IllegalArgumentException();
+ if (this.xmlObject != null) throw new IllegalStateException();
+ this.xmlObject = xmlObject;
+ }
+
+ String uri()
+ {
+ return uri;
+ }
+
+ String localName()
+ {
+ return localName;
+ }
+
+ boolean isAttributeName()
+ {
+ return isAttributeName;
+ }
+
+ void setAttributeName()
+ {
+ if (isAttributeName) throw new IllegalStateException();
+ isAttributeName = true;
+ }
+
+ boolean isDescendants()
+ {
+ return isDescendants;
+ }
+
+ void setIsDescendants()
+ {
+ if (isDescendants) throw new IllegalStateException();
+ isDescendants = true;
+ }
+
+ public boolean has(Context cx)
+ {
+ if (xmlObject == null) {
+ return false;
+ }
+ return xmlObject.hasXMLProperty(this);
+ }
+
+ public Object get(Context cx)
+ {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefReadError(Undefined.instance,
+ toString());
+ }
+ return xmlObject.getXMLProperty(this);
+ }
+
+ public Object set(Context cx, Object value)
+ {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefWriteError(Undefined.instance,
+ toString(),
+ value);
+ }
+ // Assignment to descendants causes parse error on bad reference
+ // and this should not be called
+ if (isDescendants) throw Kit.codeBug();
+ xmlObject.putXMLProperty(this, value);
+ return value;
+ }
+
+ public boolean delete(Context cx)
+ {
+ if (xmlObject == null) {
+ return true;
+ }
+ xmlObject.deleteXMLProperty(this);
+ return !xmlObject.hasXMLProperty(this);
+ }
+
+ public String toString()
+ {
+ //return qname.localName();
+ StringBuffer buff = new StringBuffer();
+ if (isDescendants) buff.append("..");
+ if (isAttributeName) buff.append('@');
+ if (uri == null) {
+ buff.append('*');
+ if(localName().equals("*")) {
+ return buff.toString();
+ }
+ } else {
+ buff.append('"').append(uri()).append('"');
+ }
+ buff.append(':').append(localName());
+ return buff.toString();
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.java
new file mode 100644
index 0000000..a6d47d5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLObjectImpl.java
@@ -0,0 +1,724 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+/**
+ * This abstract class describes what all XML objects (XML, XMLList) should have in common.
+ *
+ * @see XML
+ */
+abstract class XMLObjectImpl extends XMLObject
+{
+ private static final Object XMLOBJECT_TAG = new Object();
+
+ protected final XMLLibImpl lib;
+ protected boolean prototypeFlag;
+
+ protected XMLObjectImpl(XMLLibImpl lib, XMLObject prototype)
+ {
+ super(lib.globalScope(), prototype);
+ this.lib = lib;
+ }
+
+ /**
+ * ecmaHas(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract boolean hasXMLProperty(XMLName name);
+
+ /**
+ * ecmaGet(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract Object getXMLProperty(XMLName name);
+
+ /**
+ * ecmaPut(cx, id, value) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract void putXMLProperty(XMLName name, Object value);
+
+ /**
+ * ecmaDelete(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract void deleteXMLProperty(XMLName name);
+
+ /**
+ * Test XML equality with target the target.
+ */
+ abstract boolean equivalentXml(Object target);
+
+ // Methods from section 12.4.4 in the spec
+ abstract XML addNamespace(Namespace ns);
+ abstract XML appendChild(Object xml);
+ abstract XMLList attribute(XMLName xmlName);
+ abstract XMLList attributes();
+ abstract XMLList child(long index);
+ abstract XMLList child(XMLName xmlName);
+ abstract int childIndex();
+ abstract XMLList children();
+ abstract XMLList comments();
+ abstract boolean contains(Object xml);
+ abstract Object copy();
+ abstract XMLList descendants(XMLName xmlName);
+ abstract Object[] inScopeNamespaces();
+ abstract XML insertChildAfter(Object child, Object xml);
+ abstract XML insertChildBefore(Object child, Object xml);
+ abstract boolean hasOwnProperty(XMLName xmlName);
+ abstract boolean hasComplexContent();
+ abstract boolean hasSimpleContent();
+ abstract int length();
+ abstract String localName();
+ abstract QName name();
+ abstract Object namespace(String prefix);
+ abstract Object[] namespaceDeclarations();
+ abstract Object nodeKind();
+ abstract void normalize();
+ abstract Object parent();
+ abstract XML prependChild(Object xml);
+ abstract Object processingInstructions(XMLName xmlName);
+ abstract boolean propertyIsEnumerable(Object member);
+ abstract XML removeNamespace(Namespace ns);
+ abstract XML replace(long index, Object xml);
+ abstract XML replace(XMLName name, Object xml);
+ abstract XML setChildren(Object xml);
+ abstract void setLocalName(String name);
+ abstract void setName(QName xmlName);
+ abstract void setNamespace(Namespace ns);
+ abstract XMLList text();
+ public abstract String toString();
+ abstract String toSource(int indent);
+ abstract String toXMLString(int indent);
+ abstract Object valueOf();
+
+ /**
+ * Extension to access native implementation from scripts
+ */
+ abstract org.apache.xmlbeans.XmlObject getXmlObject();
+
+ protected abstract Object jsConstructor(Context cx, boolean inNewExpr,
+ Object[] args);
+
+
+ final Object getMethod(String id)
+ {
+ return super.get(id, this);
+ }
+
+ //
+ //
+ // Methods overriding ScriptableObject
+ //
+ //
+
+ public final Object getDefaultValue(Class hint)
+ {
+ return toString();
+ }
+
+ public void delete(String name)
+ {
+ throw new IllegalArgumentException("String: [" + name + "]");
+ }
+
+ /**
+ * XMLObject always compare with any value and equivalentValues
+ * never returns {@link Scriptable#NOT_FOUND} for them but rather
+ * calls equivalentXml(value) and wrap the result as Boolean.
+ */
+ protected final Object equivalentValues(Object value)
+ {
+ boolean result = equivalentXml(value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ //
+ //
+ // Methods overriding XMLObject
+ //
+ //
+
+ public final XMLLib lib()
+ {
+ return lib;
+ }
+
+ /**
+ * Implementation of ECMAScript [[Has]]
+ */
+ public final boolean ecmaHas(Context cx, Object id)
+ {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ return has((int)index, this);
+ }
+ return hasXMLProperty(xmlName);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Get]]
+ */
+ public final Object ecmaGet(Context cx, Object id)
+ {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ Object result = get((int)index, this);
+ if (result == Scriptable.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+ return result;
+ }
+ return getXMLProperty(xmlName);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Put]]
+ */
+ public final void ecmaPut(Context cx, Object id, Object value)
+ {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ put((int)index, this, value);
+ return;
+ }
+ putXMLProperty(xmlName, value);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Delete]].
+ */
+ public final boolean ecmaDelete(Context cx, Object id)
+ {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this
+ delete((int)index);
+ return true;
+ }
+ deleteXMLProperty(xmlName);
+ return true;
+ }
+
+ public Ref memberRef(Context cx, Object elem, int memberTypeFlags)
+ {
+ XMLName xmlName;
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
+ xmlName = lib.toAttributeName(cx, elem);
+ } else {
+ if ((memberTypeFlags & Node.DESCENDANTS_FLAG) == 0) {
+ // Code generation would use ecma(Get|Has|Delete|Set) for
+ // normal name idenrifiers so one ATTRIBUTE_FLAG
+ // or DESCENDANTS_FLAG has to be set
+ throw Kit.codeBug();
+ }
+ xmlName = lib.toXMLName(cx, elem);
+ }
+ if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
+ xmlName.setIsDescendants();
+ }
+ xmlName.initXMLObject(this);
+ return xmlName;
+ }
+
+ /**
+ * Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
+ */
+ public Ref memberRef(Context cx, Object namespace, Object elem,
+ int memberTypeFlags)
+ {
+ XMLName xmlName = lib.toQualifiedName(cx, namespace, elem);
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
+ if (!xmlName.isAttributeName()) {
+ xmlName.setAttributeName();
+ }
+ }
+ if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
+ xmlName.setIsDescendants();
+ }
+ xmlName.initXMLObject(this);
+ return xmlName;
+ }
+
+ public NativeWith enterWith(Scriptable scope)
+ {
+ return new XMLWithScope(lib, scope, this);
+ }
+
+ public NativeWith enterDotQuery(Scriptable scope)
+ {
+ XMLWithScope xws = new XMLWithScope(lib, scope, this);
+ xws.initAsDotQuery();
+ return xws;
+ }
+
+ public final Object addValues(Context cx, boolean thisIsLeft,
+ Object value)
+ {
+ if (value instanceof XMLObject) {
+ XMLObject v1, v2;
+ if (thisIsLeft) {
+ v1 = this;
+ v2 = (XMLObject)value;
+ } else {
+ v1 = (XMLObject)value;
+ v2 = this;
+ }
+ return lib.addXMLObjects(cx, v1, v2);
+ }
+ if (value == Undefined.instance) {
+ // both "xml + undefined" and "undefined + xml" gives String(xml)
+ return ScriptRuntime.toString(this);
+ }
+
+ return super.addValues(cx, thisIsLeft, value);
+ }
+
+ //
+ //
+ // IdScriptableObject machinery
+ //
+ //
+
+ final void exportAsJSClass(boolean sealed)
+ {
+ prototypeFlag = true;
+ exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
+ }
+
+// #string_id_map#
+ private final static int
+ Id_constructor = 1,
+
+ Id_addNamespace = 2,
+ Id_appendChild = 3,
+ Id_attribute = 4,
+ Id_attributes = 5,
+ Id_child = 6,
+ Id_childIndex = 7,
+ Id_children = 8,
+ Id_comments = 9,
+ Id_contains = 10,
+ Id_copy = 11,
+ Id_descendants = 12,
+ Id_inScopeNamespaces = 13,
+ Id_insertChildAfter = 14,
+ Id_insertChildBefore = 15,
+ Id_hasOwnProperty = 16,
+ Id_hasComplexContent = 17,
+ Id_hasSimpleContent = 18,
+ Id_length = 19,
+ Id_localName = 20,
+ Id_name = 21,
+ Id_namespace = 22,
+ Id_namespaceDeclarations = 23,
+ Id_nodeKind = 24,
+ Id_normalize = 25,
+ Id_parent = 26,
+ Id_prependChild = 27,
+ Id_processingInstructions = 28,
+ Id_propertyIsEnumerable = 29,
+ Id_removeNamespace = 30,
+ Id_replace = 31,
+ Id_setChildren = 32,
+ Id_setLocalName = 33,
+ Id_setName = 34,
+ Id_setNamespace = 35,
+ Id_text = 36,
+ Id_toString = 37,
+ Id_toSource = 38,
+ Id_toXMLString = 39,
+ Id_valueOf = 40,
+
+ Id_getXmlObject = 41,
+
+ MAX_PROTOTYPE_ID = 41;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2004-11-10 15:38:11 CET
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 4: c=s.charAt(0);
+ if (c=='c') { X="copy";id=Id_copy; }
+ else if (c=='n') { X="name";id=Id_name; }
+ else if (c=='t') { X="text";id=Id_text; }
+ break L;
+ case 5: X="child";id=Id_child; break L;
+ case 6: c=s.charAt(0);
+ if (c=='l') { X="length";id=Id_length; }
+ else if (c=='p') { X="parent";id=Id_parent; }
+ break L;
+ case 7: c=s.charAt(0);
+ if (c=='r') { X="replace";id=Id_replace; }
+ else if (c=='s') { X="setName";id=Id_setName; }
+ else if (c=='v') { X="valueOf";id=Id_valueOf; }
+ break L;
+ case 8: switch (s.charAt(4)) {
+ case 'K': X="nodeKind";id=Id_nodeKind; break L;
+ case 'a': X="contains";id=Id_contains; break L;
+ case 'd': X="children";id=Id_children; break L;
+ case 'e': X="comments";id=Id_comments; break L;
+ case 'r': X="toString";id=Id_toString; break L;
+ case 'u': X="toSource";id=Id_toSource; break L;
+ } break L;
+ case 9: switch (s.charAt(2)) {
+ case 'c': X="localName";id=Id_localName; break L;
+ case 'm': X="namespace";id=Id_namespace; break L;
+ case 'r': X="normalize";id=Id_normalize; break L;
+ case 't': X="attribute";id=Id_attribute; break L;
+ } break L;
+ case 10: c=s.charAt(0);
+ if (c=='a') { X="attributes";id=Id_attributes; }
+ else if (c=='c') { X="childIndex";id=Id_childIndex; }
+ break L;
+ case 11: switch (s.charAt(0)) {
+ case 'a': X="appendChild";id=Id_appendChild; break L;
+ case 'c': X="constructor";id=Id_constructor; break L;
+ case 'd': X="descendants";id=Id_descendants; break L;
+ case 's': X="setChildren";id=Id_setChildren; break L;
+ case 't': X="toXMLString";id=Id_toXMLString; break L;
+ } break L;
+ case 12: switch (s.charAt(0)) {
+ case 'a': X="addNamespace";id=Id_addNamespace; break L;
+ case 'g': X="getXmlObject";id=Id_getXmlObject; break L;
+ case 'p': X="prependChild";id=Id_prependChild; break L;
+ case 's': c=s.charAt(3);
+ if (c=='L') { X="setLocalName";id=Id_setLocalName; }
+ else if (c=='N') { X="setNamespace";id=Id_setNamespace; }
+ break L;
+ } break L;
+ case 14: X="hasOwnProperty";id=Id_hasOwnProperty; break L;
+ case 15: X="removeNamespace";id=Id_removeNamespace; break L;
+ case 16: c=s.charAt(0);
+ if (c=='h') { X="hasSimpleContent";id=Id_hasSimpleContent; }
+ else if (c=='i') { X="insertChildAfter";id=Id_insertChildAfter; }
+ break L;
+ case 17: c=s.charAt(3);
+ if (c=='C') { X="hasComplexContent";id=Id_hasComplexContent; }
+ else if (c=='c') { X="inScopeNamespaces";id=Id_inScopeNamespaces; }
+ else if (c=='e') { X="insertChildBefore";id=Id_insertChildBefore; }
+ break L;
+ case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
+ case 21: X="namespaceDeclarations";id=Id_namespaceDeclarations; break L;
+ case 22: X="processingInstructions";id=Id_processingInstructions; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: {
+ IdFunctionObject ctor;
+ if (this instanceof XML) {
+ ctor = new XMLCtor((XML)this, XMLOBJECT_TAG, id, 1);
+ } else {
+ ctor = new IdFunctionObject(this, XMLOBJECT_TAG, id, 1);
+ }
+ initPrototypeConstructor(ctor);
+ return;
+ }
+
+ case Id_addNamespace: arity=1; s="addNamespace"; break;
+ case Id_appendChild: arity=1; s="appendChild"; break;
+ case Id_attribute: arity=1; s="attribute"; break;
+ case Id_attributes: arity=0; s="attributes"; break;
+ case Id_child: arity=1; s="child"; break;
+ case Id_childIndex: arity=0; s="childIndex"; break;
+ case Id_children: arity=0; s="children"; break;
+ case Id_comments: arity=0; s="comments"; break;
+ case Id_contains: arity=1; s="contains"; break;
+ case Id_copy: arity=0; s="copy"; break;
+ case Id_descendants: arity=1; s="descendants"; break;
+ case Id_hasComplexContent: arity=0; s="hasComplexContent"; break;
+ case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
+ case Id_hasSimpleContent: arity=0; s="hasSimpleContent"; break;
+ case Id_inScopeNamespaces: arity=0; s="inScopeNamespaces"; break;
+ case Id_insertChildAfter: arity=2; s="insertChildAfter"; break;
+ case Id_insertChildBefore: arity=2; s="insertChildBefore"; break;
+ case Id_length: arity=0; s="length"; break;
+ case Id_localName: arity=0; s="localName"; break;
+ case Id_name: arity=0; s="name"; break;
+ case Id_namespace: arity=1; s="namespace"; break;
+ case Id_namespaceDeclarations:
+ arity=0; s="namespaceDeclarations"; break;
+ case Id_nodeKind: arity=0; s="nodeKind"; break;
+ case Id_normalize: arity=0; s="normalize"; break;
+ case Id_parent: arity=0; s="parent"; break;
+ case Id_prependChild: arity=1; s="prependChild"; break;
+ case Id_processingInstructions:
+ arity=1; s="processingInstructions"; break;
+ case Id_propertyIsEnumerable:
+ arity=1; s="propertyIsEnumerable"; break;
+ case Id_removeNamespace: arity=1; s="removeNamespace"; break;
+ case Id_replace: arity=2; s="replace"; break;
+ case Id_setChildren: arity=1; s="setChildren"; break;
+ case Id_setLocalName: arity=1; s="setLocalName"; break;
+ case Id_setName: arity=1; s="setName"; break;
+ case Id_setNamespace: arity=1; s="setNamespace"; break;
+ case Id_text: arity=0; s="text"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=1; s="toSource"; break;
+ case Id_toXMLString: arity=1; s="toXMLString"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+
+ case Id_getXmlObject: arity=0; s="getXmlObject"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(XMLOBJECT_TAG, id, s, arity);
+ }
+
+ /**
+ *
+ * @param f
+ * @param cx
+ * @param scope
+ * @param thisObj
+ * @param args
+ * @return
+ */
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(XMLOBJECT_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ if (id == Id_constructor) {
+ return jsConstructor(cx, thisObj == null, args);
+ }
+
+ // All (XML|XMLList).prototype methods require thisObj to be XML
+ if (!(thisObj instanceof XMLObjectImpl))
+ throw incompatibleCallError(f);
+ XMLObjectImpl realThis = (XMLObjectImpl)thisObj;
+
+ switch (id) {
+ case Id_addNamespace: {
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ return realThis.addNamespace(ns);
+ }
+ case Id_appendChild:
+ return realThis.appendChild(arg(args, 0));
+ case Id_attribute: {
+ XMLName xmlName = lib.toAttributeName(cx, arg(args, 0));
+ return realThis.attribute(xmlName);
+ }
+ case Id_attributes:
+ return realThis.attributes();
+ case Id_child: {
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ return realThis.child(index);
+ } else {
+ return realThis.child(xmlName);
+ }
+ }
+ case Id_childIndex:
+ return ScriptRuntime.wrapInt(realThis.childIndex());
+ case Id_children:
+ return realThis.children();
+ case Id_comments:
+ return realThis.comments();
+ case Id_contains:
+ return ScriptRuntime.wrapBoolean(
+ realThis.contains(arg(args, 0)));
+ case Id_copy:
+ return realThis.copy();
+ case Id_descendants: {
+ XMLName xmlName = (args.length == 0)
+ ? XMLName.formStar()
+ : lib.toXMLName(cx, args[0]);
+ return realThis.descendants(xmlName);
+ }
+ case Id_inScopeNamespaces: {
+ Object[] array = realThis.inScopeNamespaces();
+ return cx.newArray(scope, array);
+ }
+ case Id_insertChildAfter:
+ return realThis.insertChildAfter(arg(args, 0), arg(args, 1));
+ case Id_insertChildBefore:
+ return realThis.insertChildBefore(arg(args, 0), arg(args, 1));
+ case Id_hasOwnProperty: {
+ XMLName xmlName = lib.toXMLName(cx, arg(args, 0));
+ return ScriptRuntime.wrapBoolean(
+ realThis.hasOwnProperty(xmlName));
+ }
+ case Id_hasComplexContent:
+ return ScriptRuntime.wrapBoolean(realThis.hasComplexContent());
+ case Id_hasSimpleContent:
+ return ScriptRuntime.wrapBoolean(realThis.hasSimpleContent());
+ case Id_length:
+ return ScriptRuntime.wrapInt(realThis.length());
+ case Id_localName:
+ return realThis.localName();
+ case Id_name:
+ return realThis.name();
+ case Id_namespace: {
+ String prefix = (args.length > 0)
+ ? ScriptRuntime.toString(args[0]) : null;
+ return realThis.namespace(prefix);
+ }
+ case Id_namespaceDeclarations: {
+ Object[] array = realThis.namespaceDeclarations();
+ return cx.newArray(scope, array);
+ }
+ case Id_nodeKind:
+ return realThis.nodeKind();
+ case Id_normalize:
+ realThis.normalize();
+ return Undefined.instance;
+ case Id_parent:
+ return realThis.parent();
+ case Id_prependChild:
+ return realThis.prependChild(arg(args, 0));
+ case Id_processingInstructions: {
+ XMLName xmlName = (args.length > 0)
+ ? lib.toXMLName(cx, args[0])
+ : XMLName.formStar();
+ return realThis.processingInstructions(xmlName);
+ }
+ case Id_propertyIsEnumerable: {
+ return ScriptRuntime.wrapBoolean(
+ realThis.propertyIsEnumerable(arg(args, 0)));
+ }
+ case Id_removeNamespace: {
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ return realThis.removeNamespace(ns);
+ }
+ case Id_replace: {
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
+ Object arg1 = arg(args, 1);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ return realThis.replace(index, arg1);
+ } else {
+ return realThis.replace(xmlName, arg1);
+ }
+ }
+ case Id_setChildren:
+ return realThis.setChildren(arg(args, 0));
+ case Id_setLocalName: {
+ String localName;
+ Object arg = arg(args, 0);
+ if (arg instanceof QName) {
+ localName = ((QName)arg).localName();
+ } else {
+ localName = ScriptRuntime.toString(arg);
+ }
+ realThis.setLocalName(localName);
+ return Undefined.instance;
+ }
+ case Id_setName: {
+ Object arg = (args.length != 0) ? args[0] : Undefined.instance;
+ QName qname;
+ if (arg instanceof QName) {
+ qname = (QName)arg;
+ if (qname.uri() == null) {
+ qname = lib.constructQNameFromString(cx, qname.localName());
+ } else {
+ // E4X 13.4.4.35 requires to always construct QName
+ qname = lib.constructQName(cx, qname);
+ }
+ } else {
+ qname = lib.constructQName(cx, arg);
+ }
+ realThis.setName(qname);
+ return Undefined.instance;
+ }
+ case Id_setNamespace: {
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ realThis.setNamespace(ns);
+ return Undefined.instance;
+ }
+ case Id_text:
+ return realThis.text();
+ case Id_toString:
+ return realThis.toString();
+ case Id_toSource: {
+ int indent = ScriptRuntime.toInt32(args, 0);
+ return realThis.toSource(indent);
+ }
+ case Id_toXMLString: {
+ int indent = ScriptRuntime.toInt32(args, 0);
+ return realThis.toXMLString(indent);
+ }
+ case Id_valueOf:
+ return realThis.valueOf();
+
+ case Id_getXmlObject: {
+ org.apache.xmlbeans.XmlObject xmlObject = realThis.getXmlObject();
+ return Context.javaToJS(xmlObject, scope);
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static Object arg(Object[] args, int i)
+ {
+ return (i < args.length) ? args[i] : Undefined.instance;
+ }
+
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.java b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.java
new file mode 100644
index 0000000..67a778d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/deprecatedsrc/org/mozilla/javascript/xml/impl/xmlbeans/XMLWithScope.java
@@ -0,0 +1,125 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml.impl.xmlbeans;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+final class XMLWithScope extends NativeWith
+{
+ private static final long serialVersionUID = -696429282095170887L;
+
+ private XMLLibImpl lib;
+ private int _currIndex;
+ private XMLList _xmlList;
+ private XMLObject _dqPrototype;
+
+ XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype)
+ {
+ super(parent, prototype);
+ this.lib = lib;
+ }
+
+ void initAsDotQuery()
+ {
+ XMLObject prototype = (XMLObject)getPrototype();
+ // XMLWithScope also handles the .(xxx) DotQuery for XML
+ // basically DotQuery is a for/in/with statement and in
+ // the following 3 statements we setup to signal it's
+ // DotQuery,
+ // the index and the object being looped over. The
+ // xws.setPrototype is the scope of the object which is
+ // is a element of the lhs (XMLList).
+ _currIndex = 0;
+ _dqPrototype = prototype;
+ if (prototype instanceof XMLList) {
+ XMLList xl = (XMLList)prototype;
+ if (xl.length() > 0) {
+ setPrototype((Scriptable)(xl.get(0, null)));
+ }
+ }
+ // Always return the outer-most type of XML lValue of
+ // XML to left of dotQuery.
+ _xmlList = new XMLList(lib);
+ }
+
+ protected Object updateDotQuery(boolean value)
+ {
+ // Return null to continue looping
+
+ XMLObject seed = _dqPrototype;
+ XMLList xmlL = _xmlList;
+
+ if (seed instanceof XMLList) {
+ // We're a list so keep testing each element of the list if the
+ // result on the top of stack is true then that element is added
+ // to our result list. If false, we try the next element.
+ XMLList orgXmlL = (XMLList)seed;
+
+ int idx = _currIndex;
+
+ if (value) {
+ xmlL.addToList(orgXmlL.get(idx, null));
+ }
+
+ // More elements to test?
+ if (++idx < orgXmlL.length()) {
+ // Yes, set our new index, get the next element and
+ // reset the expression to run with this object as
+ // the WITH selector.
+ _currIndex = idx;
+ setPrototype((Scriptable)(orgXmlL.get(idx, null)));
+
+ // continue looping
+ return null;
+ }
+ } else {
+ // If we're not a XMLList then there's no looping
+ // just return DQPrototype if the result is true.
+ if (value) {
+ xmlL.addToList(seed);
+ }
+ }
+
+ return xmlL;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/examples/Control.java b/infrastructure/rhino1_7R1/examples/Control.java
new file mode 100644
index 0000000..d671181
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/Control.java
@@ -0,0 +1,100 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * Example of controlling the JavaScript execution engine.
+ *
+ * We evaluate a script and then manipulate the result.
+ *
+ */
+public class Control {
+
+ /**
+ * Main entry point.
+ *
+ * Process arguments as would a normal Java program. Also
+ * create a new Context and associate it with the current thread.
+ * Then set up the execution environment and begin to
+ * execute scripts.
+ */
+ public static void main(String[] args)
+ {
+ Context cx = Context.enter();
+ try {
+ // Set version to JavaScript1.2 so that we get object-literal style
+ // printing instead of "[object Object]"
+ cx.setLanguageVersion(Context.VERSION_1_2);
+
+ // Initialize the standard objects (Object, Function, etc.)
+ // This must be done before scripts can be executed.
+ Scriptable scope = cx.initStandardObjects();
+
+ // Now we can evaluate a script. Let's create a new object
+ // using the object literal notation.
+ Object result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}",
+ "MySource", 1, null);
+
+ Scriptable obj = (Scriptable) scope.get("obj", scope);
+
+ // Should print "obj == result" (Since the result of an assignment
+ // expression is the value that was assigned)
+ System.out.println("obj " + (obj == result ? "==" : "!=") +
+ " result");
+
+ // Should print "obj.a == 1"
+ System.out.println("obj.a == " + obj.get("a", obj));
+
+ Scriptable b = (Scriptable) obj.get("b", obj);
+
+ // Should print "obj.b[0] == x"
+ System.out.println("obj.b[0] == " + b.get(0, b));
+
+ // Should print "obj.b[1] == y"
+ System.out.println("obj.b[1] == " + b.get(1, b));
+
+ // Should print {a:1, b:["x", "y"]}
+ Function fn = (Function) ScriptableObject.getProperty(obj, "toString");
+ System.out.println(fn.call(cx, scope, obj, new Object[0]));
+ } finally {
+ Context.exit();
+ }
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/Counter.java b/infrastructure/rhino1_7R1/examples/Counter.java
new file mode 100644
index 0000000..14c179a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/Counter.java
@@ -0,0 +1,59 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+public class Counter extends ScriptableObject {
+ // The zero-argument constructor used by Rhino runtime to create instances
+ public Counter() { }
+
+ // Method jsConstructor defines the JavaScript constructor
+ public void jsConstructor(int a) { count = a; }
+
+ // The class name is defined by the getClassName method
+ public String getClassName() { return "Counter"; }
+
+ // The method jsGet_count defines the count property.
+ public int jsGet_count() { return count++; }
+
+ // Methods can be defined using the jsFunction_ prefix. Here we define
+ // resetCount for JavaScript.
+ public void jsFunction_resetCount() { count = 0; }
+
+ private int count;
+}
diff --git a/infrastructure/rhino1_7R1/examples/CounterTest.java b/infrastructure/rhino1_7R1/examples/CounterTest.java
new file mode 100644
index 0000000..63dc74b
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/CounterTest.java
@@ -0,0 +1,82 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * An example illustrating how to create a JavaScript object and retrieve
+ * properties and call methods.
+ * <p>
+ * Output should be:
+ * <pre>
+ * count = 0
+ * count = 1
+ * resetCount
+ * count = 0
+ * </pre>
+ */
+public class CounterTest {
+
+ public static void main(String[] args) throws Exception
+ {
+ Context cx = Context.enter();
+ try {
+ Scriptable scope = cx.initStandardObjects();
+ ScriptableObject.defineClass(scope, Counter.class);
+
+ Scriptable testCounter = cx.newObject(scope, "Counter");
+
+ Object count = ScriptableObject.getProperty(testCounter, "count");
+ System.out.println("count = " + count);
+
+ count = ScriptableObject.getProperty(testCounter, "count");
+ System.out.println("count = " + count);
+
+ ScriptableObject.callMethod(testCounter,
+ "resetCount",
+ new Object[0]);
+ System.out.println("resetCount");
+
+ count = ScriptableObject.getProperty(testCounter, "count");
+ System.out.println("count = " + count);
+ } finally {
+ Context.exit();
+ }
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/examples/DynamicScopes.java b/infrastructure/rhino1_7R1/examples/DynamicScopes.java
new file mode 100644
index 0000000..10d53ac
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/DynamicScopes.java
@@ -0,0 +1,204 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * Example of controlling the JavaScript with multiple scopes and threads.
+ */
+public class DynamicScopes {
+
+ static boolean useDynamicScope;
+
+ static class MyFactory extends ContextFactory
+ {
+ protected boolean hasFeature(Context cx, int featureIndex)
+ {
+ if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) {
+ return useDynamicScope;
+ }
+ return super.hasFeature(cx, featureIndex);
+ }
+ }
+
+ static {
+ ContextFactory.initGlobal(new MyFactory());
+ }
+
+
+ /**
+ * Main entry point.
+ *
+ * Set up the shared scope and then spawn new threads that execute
+ * relative to that shared scope. Try to run functions with and
+ * without dynamic scope to see the effect.
+ *
+ * The expected output is
+ * <pre>
+ * sharedScope
+ * nested:sharedScope
+ * sharedScope
+ * nested:sharedScope
+ * sharedScope
+ * nested:sharedScope
+ * thread0
+ * nested:thread0
+ * thread1
+ * nested:thread1
+ * thread2
+ * nested:thread2
+ * </pre>
+ * The final three lines may be permuted in any order depending on
+ * thread scheduling.
+ */
+ public static void main(String[] args)
+ {
+ Context cx = Context.enter();
+ try {
+ // Precompile source only once
+ String source = ""
+ +"var x = 'sharedScope';\n"
+ +"function f() { return x; }\n"
+ // Dynamic scope works with nested function too
+ +"function initClosure(prefix) {\n"
+ +" return function test() { return prefix+x; }\n"
+ +"}\n"
+ +"var closure = initClosure('nested:');\n"
+ +"";
+ Script script = cx.compileString(source, "sharedScript", 1, null);
+
+ useDynamicScope = false;
+ runScripts(cx, script);
+ useDynamicScope = true;
+ runScripts(cx, script);
+ } finally {
+ Context.exit();
+ }
+ }
+
+ static void runScripts(Context cx, Script script)
+ {
+ // Initialize the standard objects (Object, Function, etc.)
+ // This must be done before scripts can be executed. The call
+ // returns a new scope that we will share.
+ ScriptableObject sharedScope = cx.initStandardObjects(null, true);
+
+ // Now we can execute the precompiled script against the scope
+ // to define x variable and f function in the shared scope.
+ script.exec(cx, sharedScope);
+
+ // Now we spawn some threads that execute a script that calls the
+ // function 'f'. The scope chain looks like this:
+ // <pre>
+ // ------------------ ------------------
+ // | per-thread scope | -prototype-> | shared scope |
+ // ------------------ ------------------
+ // ^
+ // |
+ // parentScope
+ // |
+ // ------------------
+ // | f's activation |
+ // ------------------
+ // </pre>
+ // Both the shared scope and the per-thread scope have variables 'x'
+ // defined in them. If 'f' is compiled with dynamic scope enabled,
+ // the 'x' from the per-thread scope will be used. Otherwise, the 'x'
+ // from the shared scope will be used. The 'x' defined in 'g' (which
+ // calls 'f') should not be seen by 'f'.
+ final int threadCount = 3;
+ Thread[] t = new Thread[threadCount];
+ for (int i=0; i < threadCount; i++) {
+ String source2 = ""
+ +"function g() { var x = 'local'; return f(); }\n"
+ +"java.lang.System.out.println(g());\n"
+ +"function g2() { var x = 'local'; return closure(); }\n"
+ +"java.lang.System.out.println(g2());\n"
+ +"";
+ t[i] = new Thread(new PerThread(sharedScope, source2,
+ "thread" + i));
+ }
+ for (int i=0; i < threadCount; i++)
+ t[i].start();
+ // Don't return in this thread until all the spawned threads have
+ // completed.
+ for (int i=0; i < threadCount; i++) {
+ try {
+ t[i].join();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ static class PerThread implements Runnable {
+
+ PerThread(Scriptable sharedScope, String source, String x) {
+ this.sharedScope = sharedScope;
+ this.source = source;
+ this.x = x;
+ }
+
+ public void run() {
+ // We need a new Context for this thread.
+ Context cx = Context.enter();
+ try {
+ // We can share the scope.
+ Scriptable threadScope = cx.newObject(sharedScope);
+ threadScope.setPrototype(sharedScope);
+
+ // We want "threadScope" to be a new top-level
+ // scope, so set its parent scope to null. This
+ // means that any variables created by assignments
+ // will be properties of "threadScope".
+ threadScope.setParentScope(null);
+
+ // Create a JavaScript property of the thread scope named
+ // 'x' and save a value for it.
+ threadScope.put("x", threadScope, x);
+ cx.evaluateString(threadScope, source, "threadScript", 1, null);
+ } finally {
+ Context.exit();
+ }
+ }
+ private Scriptable sharedScope;
+ private String source;
+ private String x;
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/E4X/e4x_example.js b/infrastructure/rhino1_7R1/examples/E4X/e4x_example.js
new file mode 100644
index 0000000..7417404
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/E4X/e4x_example.js
@@ -0,0 +1,223 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * John Schneider
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+print("----------------------------------------");
+
+// Use the XML constructor to parse an string into an XML object
+var John = "<employee><name>John</name><age>25</age></employee>";
+var Sue ="<employee><name>Sue</name><age>32</age></employee>";
+var tagName = "employees";
+var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
+print("The employees XML object constructed from a string is:\n" + employees);
+
+print("----------------------------------------");
+
+// Use an XML literal to create an XML object
+var order = <order>
+ <customer>
+ <firstname>John</firstname>
+ <lastname>Doe</lastname>
+ </customer>
+ <item>
+ <description>Big Screen Television</description>
+ <price>1299.99</price>
+ <quantity>1</quantity>
+ </item>
+</order>
+
+// Construct the full customer name
+var name = order.customer.firstname + " " + order.customer.lastname;
+
+// Calculate the total price
+var total = order.item.price * order.item.quantity;
+
+print("The order XML object constructed using a literal is:\n" + order);
+print("The total price of " + name + "'s order is " + total);
+
+print("----------------------------------------");
+
+// construct a new XML object using expando and super-expando properties
+var order = <order/>;
+order.customer.name = "Fred Jones";
+order.customer.address.street = "123 Long Lang";
+order.customer.address.city = "Underwood";
+order.customer.address.state = "CA";
+order.item[0] = "";
+order.item[0].description = "Small Rodents";
+order.item[0].quantity = 10;
+order.item[0].price = 6.95;
+
+print("The order custructed using expandos and super-expandos is:\n" + order);
+
+// append a new item to the order
+order.item += <item><description>Catapult</description><price>139.95</price></item>;
+
+print("----------------------------------------");
+
+print("The order after appending a new item is:\n" + order);
+
+print("----------------------------------------");
+
+// dynamically construct an XML element using embedded expressions
+var tagname = "name";
+var attributename = "id";
+var attributevalue = 5;
+var content = "Fred";
+
+var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
+
+print("The dynamically computed element value is:\n" + x.toXMLString());
+
+print("----------------------------------------");
+
+// Create a SOAP message
+var message = <soap:Envelope
+ xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
+ soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+ <soap:Body>
+ <m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
+ <symbol>DIS</symbol>
+ </m:GetLastTradePrice>
+ </soap:Body>
+</soap:Envelope>
+
+// declare the SOAP and stocks namespaces
+var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
+var stock = new Namespace ("http://mycompany.com/stocks");
+
+// extract the soap encoding style and body from the soap message
+var encodingStyle = message.@soap::encodingStyle;
+
+print("The encoding style of the soap message is specified by:\n" + encodingStyle);
+
+// change the stock symbol
+message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
+
+var body = message.soap::Body;
+
+print("The body of the soap message is:\n" + body);
+
+print("----------------------------------------");
+
+// create an manipulate an XML object using the default xml namespace
+
+default xml namespace = "http://default.namespace.com";
+var x = <x/>;
+x.a = "one";
+x.b = "two";
+x.c = <c xmlns="http://some.other.namespace.com">three</c>;
+
+print("XML object constructed using the default xml namespace:\n" + x);
+
+default xml namespace="";
+
+print("----------------------------------------");
+
+var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
+ <customer>
+ <firstname>John</firstname>
+ <lastname>Doe</lastname>
+ </customer>
+ <item id="3456">
+ <description>Big Screen Television</description>
+ <price>1299.99</price>
+ <quantity>1</quantity>
+ </item>
+ <item id = "56789">
+ <description>DVD Player</description>
+ <price>399.99</price>
+ <quantity>1</quantity>
+ </item>
+</order>;
+
+
+// get the customer element from the orderprint("The customer is:\n" + order.customer);
+
+// get the id attribute from the order
+print("The order id is:" + order.@id);
+
+// get all the child elements from the order element
+print("The children of the order are:\n" + order.*);
+
+// get the list of all item descriptions
+print("The order descriptions are:\n" + order.item.description);
+
+
+// get second item by numeric index
+print("The second item is:\n" + order.item[1]);
+
+// get the list of all child elements in all item elements
+print("The children of the items are:\n" + order.item.*);
+
+// get the second child element from the order by index
+print("The second child of the order is:\n" + order.*[1]);
+
+// calculate the total price of the order
+var totalprice = 0;
+for each (i in order.item) {
+ totalprice += i.price * i.quantity;
+}
+print("The total price of the order is: " + totalprice);
+
+print("----------------------------------------");
+
+var e = <employees>
+ <employee id="1"><name>Joe</name><age>20</age></employee>
+ <employee id="2"><name>Sue</name><age>30</age></employee>
+</employees>;
+
+// get all the names in e
+print("All the employee names are:\n" + e..name);
+
+// employees with name Joe
+print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
+
+// employees with id's 1 & 2
+print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
+
+// name of employee with id 1
+print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
+
+print("----------------------------------------");
+
+
+
+
+
+
+
diff --git a/infrastructure/rhino1_7R1/examples/File.java b/infrastructure/rhino1_7R1/examples/File.java
new file mode 100644
index 0000000..62bd980
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/File.java
@@ -0,0 +1,348 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+import java.io.*;
+import java.util.Vector;
+
+/**
+ * Define a simple JavaScript File object.
+ *
+ * This isn't intended to be any sort of definitive attempt at a
+ * standard File object for JavaScript, but instead is an example
+ * of a more involved definition of a host object.
+ *
+ * Example of use of the File object:
+ * <pre>
+ * js> defineClass("File")
+ * js> file = new File("myfile.txt");
+ * [object File]
+ * js> file.writeLine("one"); <i>only now is file actually opened</i>
+ * js> file.writeLine("two");
+ * js> file.writeLine("thr", "ee");
+ * js> file.close(); <i>must close file before we can reopen for reading</i>
+ * js> var a = file.readLines(); <i>creates and fills an array with the contents of the file</i>
+ * js> a;
+ * one,two,three
+ * js>
+ * </pre>
+ *
+ *
+ * File errors or end-of-file signaled by thrown Java exceptions will
+ * be wrapped as JavaScript exceptions when called from JavaScript,
+ * and may be caught within JavaScript.
+ *
+ * @author Norris Boyd
+ */
+public class File extends ScriptableObject {
+
+ /**
+ * The zero-parameter constructor.
+ *
+ * When Context.defineClass is called with this class, it will
+ * construct File.prototype using this constructor.
+ */
+ public File() {
+ }
+
+ /**
+ * The Java method defining the JavaScript File constructor.
+ *
+ * If the constructor has one or more arguments, and the
+ * first argument is not undefined, the argument is converted
+ * to a string as used as the filename.<p>
+ *
+ * Otherwise System.in or System.out is assumed as appropriate
+ * to the use.
+ */
+ public static Scriptable jsConstructor(Context cx, Object[] args,
+ Function ctorObj,
+ boolean inNewExpr)
+ {
+ File result = new File();
+ if (args.length == 0 || args[0] == Context.getUndefinedValue()) {
+ result.name = "";
+ result.file = null;
+ } else {
+ result.name = Context.toString(args[0]);
+ result.file = new java.io.File(result.name);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the name of this JavaScript class, "File".
+ */
+ public String getClassName() {
+ return "File";
+ }
+
+ /**
+ * Get the name of the file.
+ *
+ * Used to define the "name" property.
+ */
+ public String jsGet_name() {
+ return name;
+ }
+
+ /**
+ * Read the remaining lines in the file and return them in an array.
+ *
+ * Implements a JavaScript function.<p>
+ *
+ * This is a good example of creating a new array and setting
+ * elements in that array.
+ *
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object
+ */
+ public Object jsFunction_readLines()
+ throws IOException
+ {
+ Vector v = new Vector();
+ String s;
+ while ((s = jsFunction_readLine()) != null) {
+ v.addElement(s);
+ }
+ Object[] lines = new Object[v.size()];
+ v.copyInto(lines);
+
+ Scriptable scope = ScriptableObject.getTopLevelScope(this);
+ Context cx = Context.getCurrentContext();
+ return cx.newObject(scope, "Array", lines);
+ }
+
+ /**
+ * Read a line.
+ *
+ * Implements a JavaScript function.
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object, or EOFException if the object
+ * reached the end of the file
+ */
+ public String jsFunction_readLine() throws IOException {
+ return getReader().readLine();
+ }
+
+ /**
+ * Read a character.
+ *
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object, or EOFException if the object
+ * reached the end of the file
+ */
+ public String jsFunction_readChar() throws IOException {
+ int i = getReader().read();
+ if (i == -1)
+ return null;
+ char[] charArray = { (char) i };
+ return new String(charArray);
+ }
+
+ /**
+ * Write strings.
+ *
+ * Implements a JavaScript function. <p>
+ *
+ * This function takes a variable number of arguments, converts
+ * each argument to a string, and writes that string to the file.
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object
+ */
+ public static void jsFunction_write(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IOException
+ {
+ write0(thisObj, args, false);
+ }
+
+ /**
+ * Write strings and a newline.
+ *
+ * Implements a JavaScript function.
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object
+ *
+ */
+ public static void jsFunction_writeLine(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IOException
+ {
+ write0(thisObj, args, true);
+ }
+
+ public int jsGet_lineNumber()
+ throws FileNotFoundException
+ {
+ return getReader().getLineNumber();
+ }
+
+ /**
+ * Close the file. It may be reopened.
+ *
+ * Implements a JavaScript function.
+ * @exception IOException if an error occurred while accessing the file
+ * associated with this object
+ */
+ public void jsFunction_close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ reader = null;
+ } else if (writer != null) {
+ writer.close();
+ writer = null;
+ }
+ }
+
+ /**
+ * Finalizer.
+ *
+ * Close the file when this object is collected.
+ */
+ protected void finalize() {
+ try {
+ jsFunction_close();
+ }
+ catch (IOException e) {
+ }
+ }
+
+ /**
+ * Get the Java reader.
+ */
+ public Object jsFunction_getReader() {
+ if (reader == null)
+ return null;
+ // Here we use toObject() to "wrap" the BufferedReader object
+ // in a Scriptable object so that it can be manipulated by
+ // JavaScript.
+ Scriptable parent = ScriptableObject.getTopLevelScope(this);
+ return Context.javaToJS(reader, parent);
+ }
+
+ /**
+ * Get the Java writer.
+ *
+ * @see File#jsFunction_getReader
+ *
+ */
+ public Object jsFunction_getWriter() {
+ if (writer == null)
+ return null;
+ Scriptable parent = ScriptableObject.getTopLevelScope(this);
+ return Context.javaToJS(writer, parent);
+ }
+
+ /**
+ * Get the reader, checking that we're not already writing this file.
+ */
+ private LineNumberReader getReader() throws FileNotFoundException {
+ if (writer != null) {
+ throw Context.reportRuntimeError("already writing file \""
+ + name
+ + "\"");
+ }
+ if (reader == null)
+ reader = new LineNumberReader(file == null
+ ? new InputStreamReader(System.in)
+ : new FileReader(file));
+ return reader;
+ }
+
+ /**
+ * Perform the guts of write and writeLine.
+ *
+ * Since the two functions differ only in whether they write a
+ * newline character, move the code into a common subroutine.
+ *
+ */
+ private static void write0(Scriptable thisObj, Object[] args, boolean eol)
+ throws IOException
+ {
+ File thisFile = checkInstance(thisObj);
+ if (thisFile.reader != null) {
+ throw Context.reportRuntimeError("already writing file \""
+ + thisFile.name
+ + "\"");
+ }
+ if (thisFile.writer == null)
+ thisFile.writer = new BufferedWriter(
+ thisFile.file == null ? new OutputStreamWriter(System.out)
+ : new FileWriter(thisFile.file));
+ for (int i=0; i < args.length; i++) {
+ String s = Context.toString(args[i]);
+ thisFile.writer.write(s, 0, s.length());
+ }
+ if (eol)
+ thisFile.writer.newLine();
+ }
+
+ /**
+ * Perform the instanceof check and return the downcasted File object.
+ *
+ * This is necessary since methods may reside in the File.prototype
+ * object and scripts can dynamically alter prototype chains. For example:
+ * <pre>
+ * js> defineClass("File");
+ * js> o = {};
+ * [object Object]
+ * js> o.__proto__ = File.prototype;
+ * [object File]
+ * js> o.write("hi");
+ * js: called on incompatible object
+ * </pre>
+ * The runtime will take care of such checks when non-static Java methods
+ * are defined as JavaScript functions.
+ */
+ private static File checkInstance(Scriptable obj) {
+ if (obj == null || !(obj instanceof File)) {
+ throw Context.reportRuntimeError("called on incompatible object");
+ }
+ return (File) obj;
+ }
+
+ /**
+ * Some private data for this class.
+ */
+ private String name;
+ private java.io.File file; // may be null, meaning to use System.out or .in
+ private LineNumberReader reader;
+ private BufferedWriter writer;
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/Foo.java b/infrastructure/rhino1_7R1/examples/Foo.java
new file mode 100644
index 0000000..bca1b79
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/Foo.java
@@ -0,0 +1,169 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * An example host object class.
+ *
+ * Here's a shell session showing the Foo object in action:
+ * <pre>
+ * js> defineClass("Foo")
+ * js> foo = new Foo(); <i>A constructor call, see <a href="#Foo">Foo</a> below.</i>
+ * [object Foo] <i>The "Foo" here comes from <a href"#getClassName">getClassName</a>.</i>
+ * js> foo.counter; <i>The counter property is defined by the <code>defineProperty</code></i>
+ * 0 <i>call below and implemented by the <a href="#getCounter">getCounter</a></i>
+ * js> foo.counter; <i>method below.</i>
+ * 1
+ * js> foo.counter;
+ * 2
+ * js> foo.resetCounter(); <i>Results in a call to <a href="#resetCounter">resetCounter</a>.</i>
+ * js> foo.counter; <i>Now the counter has been reset.</i>
+ * 0
+ * js> foo.counter;
+ * 1
+ * js> bar = new Foo(37); <i>Create a new instance.</i>
+ * [object Foo]
+ * js> bar.counter; <i>This instance's counter is distinct from</i>
+ * 37 <i>the other instance's counter.</i>
+ * js> foo.varargs(3, "hi"); <i>Calls <a href="#varargs">varargs</a>.</i>
+ * this = [object Foo]; args = [3, hi]
+ * js> foo[7] = 34; <i>Since we extended ScriptableObject, we get</i>
+ * 34 <i>all the behavior of a JavaScript object</i>
+ * js> foo.a = 23; <i>for free.</i>
+ * 23
+ * js> foo.a + foo[7];
+ * 57
+ * js>
+ * </pre>
+ *
+ * @see org.mozilla.javascript.Context
+ * @see org.mozilla.javascript.Scriptable
+ * @see org.mozilla.javascript.ScriptableObject
+ *
+ * @author Norris Boyd
+ */
+
+public class Foo extends ScriptableObject {
+
+ /**
+ * The zero-parameter constructor.
+ *
+ * When Context.defineClass is called with this class, it will
+ * construct Foo.prototype using this constructor.
+ */
+ public Foo() {
+ }
+
+ /**
+ * The Java method defining the JavaScript Foo constructor.
+ *
+ * Takes an initial value for the counter property.
+ * Note that in the example Shell session above, we didn't
+ * supply a argument to the Foo constructor. This means that
+ * the Undefined value is used as the value of the argument,
+ * and when the argument is converted to an integer, Undefined
+ * becomes 0.
+ */
+ public Foo(int counterStart) {
+ counter = counterStart;
+ }
+
+ /**
+ * Returns the name of this JavaScript class, "Foo".
+ */
+ public String getClassName() {
+ return "Foo";
+ }
+
+ /**
+ * The Java method defining the JavaScript resetCounter function.
+ *
+ * Resets the counter to 0.
+ */
+ public void jsFunction_resetCounter() {
+ counter = 0;
+ }
+
+ /**
+ * The Java method implementing the getter for the counter property.
+ * <p>
+ * If "setCounter" had been defined in this class, the runtime would
+ * call the setter when the property is assigned to.
+ */
+ public int jsGet_counter() {
+ return counter++;
+ }
+
+ /**
+ * An example of a variable-arguments method.
+ *
+ * All variable arguments methods must have the same number and
+ * types of parameters, and must be static. <p>
+ * @param cx the Context of the current thread
+ * @param thisObj the JavaScript 'this' value.
+ * @param args the array of arguments for this call
+ * @param funObj the function object of the invoked JavaScript function
+ * This value is useful to compute a scope using
+ * Context.getTopLevelScope().
+ * @return computes the string values and types of 'this' and
+ * of each of the supplied arguments and returns them in a string.
+ *
+ * @see org.mozilla.javascript.ScriptableObject#getTopLevelScope
+ */
+ public static Object jsFunction_varargs(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("this = ");
+ buf.append(Context.toString(thisObj));
+ buf.append("; args = [");
+ for (int i=0; i < args.length; i++) {
+ buf.append(Context.toString(args[i]));
+ if (i+1 != args.length)
+ buf.append(", ");
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ /**
+ * A piece of private data for this class.
+ */
+ private int counter;
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/Matrix.java b/infrastructure/rhino1_7R1/examples/Matrix.java
new file mode 100644
index 0000000..87e4b8a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/Matrix.java
@@ -0,0 +1,279 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+import java.util.Vector;
+
+/**
+ * Matrix: An example host object class that implements the Scriptable interface.
+ *
+ * Built-in JavaScript arrays don't handle multiple dimensions gracefully: the
+ * script writer must create every array in an array of arrays. The Matrix class
+ * takes care of that by automatically allocating arrays for every index that
+ * is accessed. What's more, the Matrix constructor takes a integer argument
+ * that specifies the dimension of the Matrix. If m is a Matrix with dimension 3,
+ * then m[0] will be a Matrix with dimension 1, and m[0][0] will be an Array.
+ *
+ * Here's a shell session showing the Matrix object in action:
+ * <pre>
+ * js> defineClass("Matrix")
+ * js> m = new Matrix(2); <i>A constructor call, see <a href="#Matrix">Matrix</a> below.</i>
+ * [object Matrix] <i>The "Matrix" here comes from <a href"#getClassName">getClassName</a>.</i>
+ * js> version(120); <i>switch to JavaScript1.2 to see arrays better</i>
+ * 0
+ * js> m[0][0] = 3;
+ * 3
+ * js> m[0]; <i>an array was created automatically!</i>
+ * [3]
+ * js> m[1]; <i>array is created even if we don't set a value</i>
+ * []
+ * js> m.dim; <i>we can access the "dim" property</i>
+ * 2
+ * js> m.dim = 3;
+ * 3
+ * js> m.dim; <i>but not modify it</i>
+ * 2
+ * </pre>
+ *
+ * @see org.mozilla.javascript.Context
+ * @see org.mozilla.javascript.Scriptable
+ *
+ * @author Norris Boyd
+ */
+public class Matrix implements Scriptable {
+
+ /**
+ * The zero-parameter constructor.
+ *
+ * When ScriptableObject.defineClass is called with this class, it will
+ * construct Matrix.prototype using this constructor.
+ */
+ public Matrix() {
+ }
+
+ /**
+ * The Java constructor, also used to define the JavaScript constructor.
+ */
+ public Matrix(int dimension) {
+ if (dimension <= 0) {
+ throw Context.reportRuntimeError(
+ "Dimension of Matrix must be greater than zero");
+ }
+ dim = dimension;
+ v = new Vector();
+ }
+
+ /**
+ * Returns the name of this JavaScript class, "Matrix".
+ */
+ public String getClassName() {
+ return "Matrix";
+ }
+
+ /**
+ * Defines the "dim" property by returning true if name is
+ * equal to "dim".
+ * <p>
+ * Defines no other properties, i.e., returns false for
+ * all other names.
+ *
+ * @param name the name of the property
+ * @param start the object where lookup began
+ */
+ public boolean has(String name, Scriptable start) {
+ return name.equals("dim");
+ }
+
+ /**
+ * Defines all numeric properties by returning true.
+ *
+ * @param index the index of the property
+ * @param start the object where lookup began
+ */
+ public boolean has(int index, Scriptable start) {
+ return true;
+ }
+
+ /**
+ * Get the named property.
+ * <p>
+ * Handles the "dim" property and returns NOT_FOUND for all
+ * other names.
+ * @param name the property name
+ * @param start the object where the lookup began
+ */
+ public Object get(String name, Scriptable start) {
+ if (name.equals("dim"))
+ return new Integer(dim);
+
+ return NOT_FOUND;
+ }
+
+ /**
+ * Get the indexed property.
+ * <p>
+ * Look up the element in the associated vector and return
+ * it if it exists. If it doesn't exist, create it.<p>
+ * @param index the index of the integral property
+ * @param start the object where the lookup began
+ */
+ public Object get(int index, Scriptable start) {
+ if (index >= v.size())
+ v.setSize(index+1);
+ Object result = v.elementAt(index);
+ if (result != null)
+ return result;
+ if (dim > 2) {
+ Matrix m = new Matrix(dim-1);
+ m.setParentScope(getParentScope());
+ m.setPrototype(getPrototype());
+ result = m;
+ } else {
+ Context cx = Context.getCurrentContext();
+ Scriptable scope = ScriptableObject.getTopLevelScope(start);
+ result = cx.newArray(scope, 0);
+ }
+ v.setElementAt(result, index);
+ return result;
+ }
+
+ /**
+ * Set a named property.
+ *
+ * We do nothing here, so all properties are effectively read-only.
+ */
+ public void put(String name, Scriptable start, Object value) {
+ }
+
+ /**
+ * Set an indexed property.
+ *
+ * We do nothing here, so all properties are effectively read-only.
+ */
+ public void put(int index, Scriptable start, Object value) {
+ }
+
+ /**
+ * Remove a named property.
+ *
+ * This method shouldn't even be called since we define all properties
+ * as PERMANENT.
+ */
+ public void delete(String id) {
+ }
+
+ /**
+ * Remove an indexed property.
+ *
+ * This method shouldn't even be called since we define all properties
+ * as PERMANENT.
+ */
+ public void delete(int index) {
+ }
+
+ /**
+ * Get prototype.
+ */
+ public Scriptable getPrototype() {
+ return prototype;
+ }
+
+ /**
+ * Set prototype.
+ */
+ public void setPrototype(Scriptable prototype) {
+ this.prototype = prototype;
+ }
+
+ /**
+ * Get parent.
+ */
+ public Scriptable getParentScope() {
+ return parent;
+ }
+
+ /**
+ * Set parent.
+ */
+ public void setParentScope(Scriptable parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Get properties.
+ *
+ * We return an empty array since we define all properties to be DONTENUM.
+ */
+ public Object[] getIds() {
+ return new Object[0];
+ }
+
+ /**
+ * Default value.
+ *
+ * Use the convenience method from Context that takes care of calling
+ * toString, etc.
+ */
+ public Object getDefaultValue(Class typeHint) {
+ return "[object Matrix]";
+ }
+
+ /**
+ * instanceof operator.
+ *
+ * We mimick the normal JavaScript instanceof semantics, returning
+ * true if <code>this</code> appears in <code>value</code>'s prototype
+ * chain.
+ */
+ public boolean hasInstance(Scriptable value) {
+ Scriptable proto = value.getPrototype();
+ while (proto != null) {
+ if (proto.equals(this))
+ return true;
+ proto = proto.getPrototype();
+ }
+
+ return false;
+ }
+
+ /**
+ * Some private data for this class.
+ */
+ private int dim;
+ private Vector v;
+ private Scriptable prototype, parent;
+}
diff --git a/infrastructure/rhino1_7R1/examples/NervousText.html b/infrastructure/rhino1_7R1/examples/NervousText.html
new file mode 100644
index 0000000..0e3c7dd
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/NervousText.html
@@ -0,0 +1,53 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<html>
+<body>
+This is the NervousText applet in javascript:
+<applet archive="js.jar" code=NervousText width=200 height=50 >
+</applet>
+
+<hr>
+The test assumes that applet code is generated with:
+<pre>
+java -classpath js.jar org.mozilla.javascript.tools.jsc.Main \
+ -extends java.applet.Applet \
+ -implements java.lang.Runnable \
+ NervousText.js
+</pre>
+and the resulting 2 classes, NervousText.class extending java.applet.Applet and implementing java.lang.Runnable and NervousText1.class which represents compiled JavaScript code, are placed in the same directory as NervousText.html.
+<p>
+The test also assumes that js.jar from Rhino distribution is available in the same directory.
+</body>
+</html>
diff --git a/infrastructure/rhino1_7R1/examples/NervousText.js b/infrastructure/rhino1_7R1/examples/NervousText.js
new file mode 100644
index 0000000..a2f82fe
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/NervousText.js
@@ -0,0 +1,109 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// The Java "NervousText" example ported to JavaScript.
+// Compile using java org.mozilla.javascript.tools.jsc.Main -extends java.applet.Applet -implements java.lang.Runnable NervousText.js
+/*
+Adapted from Java code by
+ Daniel Wyszynski
+ Center for Applied Large-Scale Computing (CALC)
+ 04-12-95
+
+ Test of text animation.
+
+ kwalrath: Changed string; added thread suspension. 5-9-95
+*/
+var Font = java.awt.Font;
+var Thread = java.lang.Thread;
+var separated;
+var s = null;
+var killme = null;
+var i;
+var x_coord = 0, y_coord = 0;
+var num;
+var speed=35;
+var counter =0;
+var threadSuspended = false; //added by kwalrath
+
+function init() {
+ this.resize(150,50);
+ this.setFont(new Font("TimesRoman",Font.BOLD,36));
+ s = this.getParameter("text");
+ if (s == null) {
+ s = "Rhino";
+ }
+ separated = s.split('');
+}
+
+function start() {
+ if(killme == null)
+ {
+ killme = new java.lang.Thread(java.lang.Runnable(this));
+ killme.start();
+ }
+}
+
+function stop() {
+ killme = null;
+}
+
+function run() {
+ while (killme != null) {
+ try {Thread.sleep(100);} catch (e){}
+ this.repaint();
+ }
+ killme = null;
+}
+
+function paint(g) {
+ for(i=0;i<separated.length;i++)
+ {
+ x_coord = Math.random()*10+15*i;
+ y_coord = Math.random()*10+36;
+ g.drawChars(separated, i,1,x_coord,y_coord);
+ }
+}
+
+/* Added by kwalrath. */
+function mouseDown(evt, x, y) {
+ if (threadSuspended) {
+ killme.resume();
+ }
+ else {
+ killme.suspend();
+ }
+ threadSuspended = !threadSuspended;
+ return true;
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/PrimitiveWrapFactory.java b/infrastructure/rhino1_7R1/examples/PrimitiveWrapFactory.java
new file mode 100644
index 0000000..4157a11
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/PrimitiveWrapFactory.java
@@ -0,0 +1,72 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * An example WrapFactory that can be used to avoid wrapping of Java types
+ * that can be converted to ECMA primitive values.
+ * So java.lang.String is mapped to ECMA string, all java.lang.Numbers are
+ * mapped to ECMA numbers, and java.lang.Booleans are mapped to ECMA booleans
+ * instead of being wrapped as objects. Additionally java.lang.Character is
+ * converted to ECMA string with length 1.
+ * Other types have the default behavior.
+ * <p>
+ * Note that calling "new java.lang.String('foo')" in JavaScript with this
+ * wrap factory enabled will still produce a wrapped Java object since the
+ * WrapFactory.wrapNewObject method is not overridden.
+ * <p>
+ * The PrimitiveWrapFactory is enabled on a Context by calling setWrapFactory
+ * on that context.
+ */
+public class PrimitiveWrapFactory extends WrapFactory {
+
+ public Object wrap(Context cx, Scriptable scope, Object obj,
+ Class staticType)
+ {
+ if (obj instanceof String || obj instanceof Number ||
+ obj instanceof Boolean)
+ {
+ return obj;
+ } else if (obj instanceof Character) {
+ char[] a = { ((Character)obj).charValue() };
+ return new String(a);
+ }
+ return super.wrap(cx, scope, obj, staticType);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/examples/RunScript.java b/infrastructure/rhino1_7R1/examples/RunScript.java
new file mode 100644
index 0000000..758ac64
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/RunScript.java
@@ -0,0 +1,78 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * RunScript: simplest example of controlling execution of Rhino.
+ *
+ * Collects its arguments from the command line, executes the
+ * script, and prints the result.
+ *
+ * @author Norris Boyd
+ */
+public class RunScript {
+ public static void main(String args[])
+ {
+ // Creates and enters a Context. The Context stores information
+ // about the execution environment of a script.
+ Context cx = Context.enter();
+ try {
+ // Initialize the standard objects (Object, Function, etc.)
+ // This must be done before scripts can be executed. Returns
+ // a scope object that we use in later calls.
+ Scriptable scope = cx.initStandardObjects();
+
+ // Collect the arguments into a single string.
+ String s = "";
+ for (int i=0; i < args.length; i++) {
+ s += args[i];
+ }
+
+ // Now evaluate the string we've colected.
+ Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
+
+ // Convert the result to a string and print it.
+ System.err.println(Context.toString(result));
+
+ } finally {
+ // Exit from the context.
+ Context.exit();
+ }
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/RunScript2.java b/infrastructure/rhino1_7R1/examples/RunScript2.java
new file mode 100644
index 0000000..cb02896
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/RunScript2.java
@@ -0,0 +1,69 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * RunScript2: Like RunScript, but reflects the System.out into JavaScript.
+ *
+ * @author Norris Boyd
+ */
+public class RunScript2 {
+ public static void main(String args[])
+ {
+ Context cx = Context.enter();
+ try {
+ Scriptable scope = cx.initStandardObjects();
+
+ // Add a global variable "out" that is a JavaScript reflection
+ // of System.out
+ Object jsOut = Context.javaToJS(System.out, scope);
+ ScriptableObject.putProperty(scope, "out", jsOut);
+
+ String s = "";
+ for (int i=0; i < args.length; i++) {
+ s += args[i];
+ }
+ Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
+ System.err.println(Context.toString(result));
+ } finally {
+ Context.exit();
+ }
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/RunScript3.java b/infrastructure/rhino1_7R1/examples/RunScript3.java
new file mode 100644
index 0000000..7baeba8
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/RunScript3.java
@@ -0,0 +1,88 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * RunScript3: Example of using JavaScript objects
+ *
+ * Collects its arguments from the command line, executes the
+ * script, and then ...
+ *
+ * @author Norris Boyd
+ */
+public class RunScript3 {
+ public static void main(String args[])
+ {
+ Context cx = Context.enter();
+ try {
+ Scriptable scope = cx.initStandardObjects();
+
+ // Collect the arguments into a single string.
+ String s = "";
+ for (int i=0; i < args.length; i++) {
+ s += args[i];
+ }
+
+ // Now evaluate the string we've colected. We'll ignore the result.
+ cx.evaluateString(scope, s, "<cmd>", 1, null);
+
+ // Print the value of variable "x"
+ Object x = scope.get("x", scope);
+ if (x == Scriptable.NOT_FOUND) {
+ System.out.println("x is not defined.");
+ } else {
+ System.out.println("x = " + Context.toString(x));
+ }
+
+ // Call function "f('my arg')" and print its result.
+ Object fObj = scope.get("f", scope);
+ if (!(fObj instanceof Function)) {
+ System.out.println("f is undefined or not a function.");
+ } else {
+ Object functionArgs[] = { "my arg" };
+ Function f = (Function)fObj;
+ Object result = f.call(cx, scope, scope, functionArgs);
+ String report = "f('my args') = " + Context.toString(result);
+ System.out.println(report);
+ }
+ } finally {
+ Context.exit();
+ }
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/RunScript4.java b/infrastructure/rhino1_7R1/examples/RunScript4.java
new file mode 100644
index 0000000..bd3d6f4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/RunScript4.java
@@ -0,0 +1,78 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+
+/**
+ * RunScript4: Execute scripts in an environment that includes the
+ * example Counter class.
+ *
+ * @author Norris Boyd
+ */
+public class RunScript4 {
+ public static void main(String args[])
+ throws Exception
+ {
+ Context cx = Context.enter();
+ try {
+ Scriptable scope = cx.initStandardObjects();
+
+ // Use the Counter class to define a Counter constructor
+ // and prototype in JavaScript.
+ ScriptableObject.defineClass(scope, Counter.class);
+
+ // Create an instance of Counter and assign it to
+ // the top-level variable "myCounter". This is
+ // equivalent to the JavaScript code
+ // myCounter = new Counter(7);
+ Object[] arg = { new Integer(7) };
+ Scriptable myCounter = cx.newObject(scope, "Counter", arg);
+ scope.put("myCounter", scope, myCounter);
+
+ String s = "";
+ for (int i=0; i < args.length; i++) {
+ s += args[i];
+ }
+ Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
+ System.err.println(Context.toString(result));
+ } finally {
+ Context.exit();
+ }
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/Shell.java b/infrastructure/rhino1_7R1/examples/Shell.java
new file mode 100644
index 0000000..6316c6f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/Shell.java
@@ -0,0 +1,345 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+import org.mozilla.javascript.*;
+import java.io.*;
+
+/**
+ * The shell program.
+ *
+ * Can execute scripts interactively or in batch mode at the command line.
+ * An example of controlling the JavaScript engine.
+ *
+ * @author Norris Boyd
+ */
+public class Shell extends ScriptableObject
+{
+ public String getClassName()
+ {
+ return "global";
+ }
+
+ /**
+ * Main entry point.
+ *
+ * Process arguments as would a normal Java program. Also
+ * create a new Context and associate it with the current thread.
+ * Then set up the execution environment and begin to
+ * execute scripts.
+ */
+ public static void main(String args[]) {
+ // Associate a new Context with this thread
+ Context cx = Context.enter();
+ try {
+ // Initialize the standard objects (Object, Function, etc.)
+ // This must be done before scripts can be executed.
+ Shell shell = new Shell();
+ cx.initStandardObjects(shell);
+
+ // Define some global functions particular to the shell. Note
+ // that these functions are not part of ECMA.
+ String[] names = { "print", "quit", "version", "load", "help" };
+ shell.defineFunctionProperties(names, Shell.class,
+ ScriptableObject.DONTENUM);
+
+ args = processOptions(cx, args);
+
+ // Set up "arguments" in the global scope to contain the command
+ // line arguments after the name of the script to execute
+ Object[] array;
+ if (args.length == 0) {
+ array = new Object[0];
+ } else {
+ int length = args.length - 1;
+ array = new Object[length];
+ System.arraycopy(args, 1, array, 0, length);
+ }
+ Scriptable argsObj = cx.newArray(shell, array);
+ shell.defineProperty("arguments", argsObj,
+ ScriptableObject.DONTENUM);
+
+ shell.processSource(cx, args.length == 0 ? null : args[0]);
+ } finally {
+ Context.exit();
+ }
+ }
+
+ /**
+ * Parse arguments.
+ */
+ public static String[] processOptions(Context cx, String args[]) {
+ for (int i=0; i < args.length; i++) {
+ String arg = args[i];
+ if (!arg.startsWith("-")) {
+ String[] result = new String[args.length - i];
+ for (int j=i; j < args.length; j++)
+ result[j-i] = args[j];
+ return result;
+ }
+ if (arg.equals("-version")) {
+ if (++i == args.length)
+ usage(arg);
+ double d = Context.toNumber(args[i]);
+ if (d != d)
+ usage(arg);
+ cx.setLanguageVersion((int) d);
+ continue;
+ }
+ usage(arg);
+ }
+ return new String[0];
+ }
+
+ /**
+ * Print a usage message.
+ */
+ private static void usage(String s) {
+ p("Didn't understand \"" + s + "\".");
+ p("Valid arguments are:");
+ p("-version 100|110|120|130|140|150|160|170");
+ System.exit(1);
+ }
+
+ /**
+ * Print a help message.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public void help() {
+ p("");
+ p("Command Description");
+ p("======= ===========");
+ p("help() Display usage and help messages. ");
+ p("defineClass(className) Define an extension using the Java class");
+ p(" named with the string argument. ");
+ p(" Uses ScriptableObject.defineClass(). ");
+ p("load(['foo.js', ...]) Load JavaScript source files named by ");
+ p(" string arguments. ");
+ p("loadClass(className) Load a class named by a string argument.");
+ p(" The class must be a script compiled to a");
+ p(" class file. ");
+ p("print([expr ...]) Evaluate and print expressions. ");
+ p("quit() Quit the shell. ");
+ p("version([number]) Get or set the JavaScript version number.");
+ p("");
+ }
+
+ /**
+ * Print the string values of its arguments.
+ *
+ * This method is defined as a JavaScript function.
+ * Note that its arguments are of the "varargs" form, which
+ * allows it to handle an arbitrary number of arguments
+ * supplied to the JavaScript function.
+ *
+ */
+ public static void print(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ for (int i=0; i < args.length; i++) {
+ if (i > 0)
+ System.out.print(" ");
+
+ // Convert the arbitrary JavaScript value into a string form.
+ String s = Context.toString(args[i]);
+
+ System.out.print(s);
+ }
+ System.out.println();
+ }
+
+ /**
+ * Quit the shell.
+ *
+ * This only affects the interactive mode.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public void quit()
+ {
+ quitting = true;
+ }
+
+ /**
+ * Get and set the language version.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public static double version(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ double result = cx.getLanguageVersion();
+ if (args.length > 0) {
+ double d = Context.toNumber(args[0]);
+ cx.setLanguageVersion((int) d);
+ }
+ return result;
+ }
+
+ /**
+ * Load and execute a set of JavaScript source files.
+ *
+ * This method is defined as a JavaScript function.
+ *
+ */
+ public static void load(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ Shell shell = (Shell)getTopLevelScope(thisObj);
+ for (int i = 0; i < args.length; i++) {
+ shell.processSource(cx, Context.toString(args[i]));
+ }
+ }
+
+
+ /**
+ * Evaluate JavaScript source.
+ *
+ * @param cx the current context
+ * @param filename the name of the file to compile, or null
+ * for interactive mode.
+ */
+ private void processSource(Context cx, String filename)
+ {
+ if (filename == null) {
+ BufferedReader in = new BufferedReader
+ (new InputStreamReader(System.in));
+ String sourceName = "<stdin>";
+ int lineno = 1;
+ boolean hitEOF = false;
+ do {
+ int startline = lineno;
+ System.err.print("js> ");
+ System.err.flush();
+ try {
+ String source = "";
+ // Collect lines of source to compile.
+ while(true) {
+ String newline;
+ newline = in.readLine();
+ if (newline == null) {
+ hitEOF = true;
+ break;
+ }
+ source = source + newline + "\n";
+ lineno++;
+ // Continue collecting as long as more lines
+ // are needed to complete the current
+ // statement. stringIsCompilableUnit is also
+ // true if the source statement will result in
+ // any error other than one that might be
+ // resolved by appending more source.
+ if (cx.stringIsCompilableUnit(source))
+ break;
+ }
+ Object result = cx.evaluateString(this, source,
+ sourceName, startline,
+ null);
+ if (result != Context.getUndefinedValue()) {
+ System.err.println(Context.toString(result));
+ }
+ }
+ catch (WrappedException we) {
+ // Some form of exception was caught by JavaScript and
+ // propagated up.
+ System.err.println(we.getWrappedException().toString());
+ we.printStackTrace();
+ }
+ catch (EvaluatorException ee) {
+ // Some form of JavaScript error.
+ System.err.println("js: " + ee.getMessage());
+ }
+ catch (JavaScriptException jse) {
+ // Some form of JavaScript error.
+ System.err.println("js: " + jse.getMessage());
+ }
+ catch (IOException ioe) {
+ System.err.println(ioe.toString());
+ }
+ if (quitting) {
+ // The user executed the quit() function.
+ break;
+ }
+ } while (!hitEOF);
+ System.err.println();
+ } else {
+ FileReader in = null;
+ try {
+ in = new FileReader(filename);
+ }
+ catch (FileNotFoundException ex) {
+ Context.reportError("Couldn't open file \"" + filename + "\".");
+ return;
+ }
+
+ try {
+ // Here we evalute the entire contents of the file as
+ // a script. Text is printed only if the print() function
+ // is called.
+ cx.evaluateReader(this, in, filename, 1, null);
+ }
+ catch (WrappedException we) {
+ System.err.println(we.getWrappedException().toString());
+ we.printStackTrace();
+ }
+ catch (EvaluatorException ee) {
+ System.err.println("js: " + ee.getMessage());
+ }
+ catch (JavaScriptException jse) {
+ System.err.println("js: " + jse.getMessage());
+ }
+ catch (IOException ioe) {
+ System.err.println(ioe.toString());
+ }
+ finally {
+ try {
+ in.close();
+ }
+ catch (IOException ioe) {
+ System.err.println(ioe.toString());
+ }
+ }
+ }
+ }
+
+ private static void p(String s) {
+ System.out.println(s);
+ }
+
+ private boolean quitting;
+}
+
diff --git a/infrastructure/rhino1_7R1/examples/SwingApplication.js b/infrastructure/rhino1_7R1/examples/SwingApplication.js
new file mode 100644
index 0000000..a527aad
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/SwingApplication.js
@@ -0,0 +1,111 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * SwingApplication.js - a translation into JavaScript of
+ * SwingApplication.java, a java.sun.com Swing example.
+ *
+ * @author Roger E Critchlow, Jr.
+ */
+
+var swingNames = JavaImporter();
+
+swingNames.importPackage(Packages.javax.swing);
+swingNames.importPackage(Packages.java.awt);
+swingNames.importPackage(Packages.java.awt.event);
+
+function createComponents()
+{
+ with (swingNames) {
+ var labelPrefix = "Number of button clicks: ";
+ var numClicks = 0;
+ var label = new JLabel(labelPrefix + numClicks);
+ var button = new JButton("I'm a Swing button!");
+ button.mnemonic = KeyEvent.VK_I;
+ // Since Rhino 1.5R5 JS functions can be passed to Java method if
+ // corresponding argument type is Java interface with single method
+ // or all its methods have the same number of arguments and the
+ // corresponding arguments has the same type. See also comments for
+ // frame.addWindowListener bellow
+ button.addActionListener(function() {
+ numClicks += 1;
+ label.setText(labelPrefix + numClicks);
+ });
+ label.setLabelFor(button);
+
+ /*
+ * An easy way to put space between a top-level container
+ * and its contents is to put the contents in a JPanel
+ * that has an "empty" border.
+ */
+ var pane = new JPanel();
+ pane.border = BorderFactory.createEmptyBorder(30, //top
+ 30, //left
+ 10, //bottom
+ 30); //right
+ pane.setLayout(new GridLayout(0, 1));
+ pane.add(button);
+ pane.add(label);
+
+ return pane;
+ }
+}
+
+with (swingNames) {
+ try {
+ UIManager.
+ setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+ } catch (e) { }
+
+ //Create the top-level container and add contents to it.
+ var frame = new swingNames.JFrame("SwingApplication");
+ frame.getContentPane().add(createComponents(), BorderLayout.CENTER);
+
+ // Pass JS function as implementation of WindowListener. It is allowed since
+ // all methods in WindowListener have the same signature. To distinguish
+ // between methods Rhino passes to JS function the name of corresponding
+ // method as the last argument
+ frame.addWindowListener(function(event, methodName) {
+ if (methodName == "windowClosing") {
+ java.lang.System.exit(0);
+ }
+ });
+
+ //Finish setting up the frame, and show it.
+ frame.pack();
+ frame.setVisible(true);
+}
+
+
+
diff --git a/infrastructure/rhino1_7R1/examples/checkParam.js b/infrastructure/rhino1_7R1/examples/checkParam.js
new file mode 100644
index 0000000..51910d5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/checkParam.js
@@ -0,0 +1,137 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * checkParam.js
+ *
+ * The files given as arguments on the command line are assumed to be
+ * Java source code files. This program checks to see that the @param
+ * tags in the documentation comments match with the parameters for
+ * the associated Java methods.
+ * <p>
+ * Any errors found are reported.
+ *
+ */
+defineClass("File")
+
+// Return true if "str" ends with "suffix".
+function stringEndsWith(str, suffix) {
+ return str.substring(str.length - suffix.length) == suffix;
+}
+
+/**
+ * Perform processing once the end of a documentation comment is seen.
+ *
+ * Look for a parameter list following the end of the comment and
+ * collect the parameters and compare to the @param entries.
+ * Report any discrepancies.
+ * @param f the current file
+ * @param a an array of parameters from @param comments
+ * @param line the string containing the comment end (in case the
+ * parameters are on the same line)
+ */
+function processCommentEnd(f, a, line) {
+ while (line != null && !line.match(/\(/))
+ line = f.readLine();
+ while (line != null && !line.match(/\)/))
+ line += f.readLine();
+ if (line === null)
+ return;
+ var m = line.match(/\(([^\)]+)\)/);
+ var args = m ? m[1].split(",") : [];
+ if (a.length != args.length) {
+ print('"' + f.name +
+ '"; line ' + f.lineNumber +
+ ' mismatch: had a different number' +
+ ' of @param entries and parameters.');
+ } else {
+ for (var i=0; i < a.length; i++) {
+ if (!stringEndsWith(args[i], a[i])) {
+ print('"' + f.name +
+ '"; line ' + f.lineNumber +
+ ' mismatch: had "' + a[i] +
+ '" and "' + args[i] + '".');
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * Process the given file, looking for mismatched @param lists and
+ * parameter lists.
+ * @param f the file to process
+ */
+function processFile(f) {
+ var line;
+ var m;
+ var i = 0;
+ var a = [];
+ outer:
+ while ((line = f.readLine()) != null) {
+ if (line.match(/@param/)) {
+ while (m = line.match(/@param[ ]+([^ ]+)/)) {
+ a[i++] = m[1];
+ line = f.readLine();
+ if (line == null)
+ break outer;
+ }
+ }
+ if (i != 0 && line.match(/\*\//)) {
+ processCommentEnd(f, a, line);
+ i = 0;
+ a = [];
+ }
+ }
+ if (i != 0) {
+ print('"' + f.name +
+ '"; line ' + f.lineNumber +
+ ' missing parameters at end of file.');
+ }
+}
+
+// main script: process each file in arguments list
+
+for (var i=0; i < arguments.length; i++) {
+ var filename = String(arguments[i]);
+ print("Checking " + filename + "...");
+ var f = new File(filename);
+ processFile(f);
+}
+print("done.");
+
diff --git a/infrastructure/rhino1_7R1/examples/enum.js b/infrastructure/rhino1_7R1/examples/enum.js
new file mode 100644
index 0000000..02034bc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/enum.js
@@ -0,0 +1,69 @@
+/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+Implementing the interface java.util.Enumeration passing the object
+with JavaScript implementation directly to the constructor.
+This is a shorthand for JavaAdapter constructor:
+
+elements = new JavaAdapter(java.util.Enumeration, {
+ index: 0,
+ elements: array,
+ hasMoreElements: function ...
+ nextElement: function ...
+ });
+ */
+
+// an array to enumerate.
+var array = [0, 1, 2];
+
+// create an array enumeration.
+var elements = new java.util.Enumeration({
+ index: 0,
+ elements: array,
+ hasMoreElements: function() {
+ return (this.index < this.elements.length);
+ },
+ nextElement: function() {
+ return this.elements[this.index++];
+ }
+ });
+
+// now print out the array by enumerating through the Enumeration
+while (elements.hasMoreElements())
+ print(elements.nextElement());
diff --git a/infrastructure/rhino1_7R1/examples/jsdoc.js b/infrastructure/rhino1_7R1/examples/jsdoc.js
new file mode 100644
index 0000000..3d44e48
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/jsdoc.js
@@ -0,0 +1,556 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roland Pennings
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Process a JavaScript source file and process special comments
+ * to produce an HTML file of documentation, similar to javadoc.
+ * @author Norris Boyd
+ * @see rhinotip.jar
+ * @lastmodified xx
+ * @version 1.2 Roland Pennings: Allow multiple files for a function.
+ * @version 1.3 Roland Pennings: Removes ../.. from the input directory name
+ */
+defineClass("File")
+
+var functionDocArray = [];
+var inputDirName = "";
+var indexFileArray = [];
+var indexFile = "";
+var indexFileName = "index_files";
+var indexFunctionArray = [];
+var indexFunction = "";
+var indexFunctionName = "index_functions";
+var FileList = [];
+var DirList = [];
+var outputdir = null;
+var debug = 0;
+
+
+
+/**
+ * Process JavaScript source file <code>f</code>, writing jsdoc to
+ * file <code>out</code>.
+ * @param f input file
+ * @param fname name of the input file (without the path)
+ * @param inputdir directory of the input file
+ * @param out output file
+ */
+function processFile(f, fname, inputdir, out) {
+ var s;
+ var firstLine = true;
+ indexFileArray[fname] = "";
+
+ // write the header of the output file
+ out.writeLine('<HTML><HEADER><TITLE>' + fname + '</TITLE><BODY>');
+ if (inputdir != null) {
+ outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> ';
+ outstr += '<a href=\"' + indexFunction + '\">Index Functions</a></pre><hr>';
+ out.writeLine(outstr);
+ }
+
+ // process the input file
+ var comment = "";
+ while ((s = f.readLine()) != null) {
+ var m = s.match(/\/\*\*(.*)/);
+ if (m != null) {
+ // Found a comment start.
+ s = "*" + m[1];
+ do {
+ m = s.match(/(.*)\*\//);
+ if (m != null) {
+ // Found end of comment.
+ comment += m[1];
+ break;
+ }
+ // Strip leading whitespace and "*".
+ comment += s.replace(/^\s*\*/, "");
+ s = f.readLine();
+ } while (s != null);
+
+ if (debug)
+ print("Found comment " + comment);
+
+ if (firstLine) {
+ // We have a comment for the whole file.
+ out.writeLine('<H1>File ' + fname + '</H1>');
+ out.writeLine(processComment(comment,firstLine,fname));
+ out.writeLine('<HR>');
+ firstLine = false;
+ comment = "";
+ continue;
+ }
+ }
+ // match the beginning of the function
+ // NB we also match functions without a comment!
+ // if we have two comments one after another only the last one will be taken
+ m = s.match(/^\s*function\s+((\w+)|(\w+)(\s+))\(([^)]*)\)/);
+ if (m != null)
+ {
+ // Found a function start
+ var htmlText = processFunction(m[1], m[5], comment); // sjm changed from 2nd to 5th arg
+
+ // Save the text in a global variable, so we
+ // can write out a table of contents first.
+ functionDocArray[functionDocArray.length] = {name:m[1], text:htmlText};
+
+ // Store the function also in the indexFunctionArray
+ // so we can have a separate file with the function table of contents
+ if (indexFunctionArray[m[1]]) {
+ // print("ERROR: function: " + m[1] + " is defined more than once!");
+ // Allow multiple files for a function
+ with (indexFunctionArray[m[1]]) {
+ filename = filename + "|" + fname;
+ // print("filename = " + filename);
+ }
+ }
+ else {
+ indexFunctionArray[m[1]] = {filename:fname};
+ }
+ //reset comment
+ comment = "";
+ }
+ // match a method being bound to a prototype
+ m = s.match(/^\s*(\w*)\.prototype\.(\w*)\s*=\s*function\s*\(([^)]*)\)/);
+ if (m != null)
+ {
+ // Found a method being bound to a prototype.
+ var htmlText = processPrototypeMethod(m[1], m[2], m[3], comment);
+
+ // Save the text in a global variable, so we
+ // can write out a table of contents first.
+ functionDocArray[functionDocArray.length] = {name:m[1]+".prototype."+m[2], text:htmlText};
+
+ // Store the function also in the indexFunctionArray
+ // so we can have a separate file with the function table of contents
+ if (indexFunctionArray[m[1]]) {
+ // print("ERROR: function: " + m[1] + " is defined more than once!");
+ // Allow multiple files for a function
+ with (indexFunctionArray[m[1]]) {
+ filename = filename + "|" + fname;
+ // print("filename = " + filename);
+ }
+ }
+ else {
+ indexFunctionArray[m[1]] = {filename:fname};
+ }
+ //reset comment
+ comment = "";
+ }
+
+
+ firstLine = false;
+ }
+
+ // Write table of contents.
+ for (var i=0; i < functionDocArray.length; i++) {
+ with (functionDocArray[i]) {
+ out.writeLine('function <A HREF=#' + name +
+ '>' + name + '</A><BR>');
+ }
+ }
+ out.writeLine('<HR>');
+
+ // Now write the saved function documentation.
+ for (i=0; i < functionDocArray.length; i++) {
+ with (functionDocArray[i]) {
+ out.writeLine('<A NAME=' + name + '>');
+ out.writeLine(text);
+ }
+ }
+ out.writeLine('</BODY></HTML>');
+
+ // Now clean up the doc array
+ functionDocArray = [];
+}
+
+/**
+ * Process function and associated comment.
+ * @param name the name of the function
+ * @param args the args of the function as a single string
+ * @param comment the text of the comment
+ * @return a string for the HTML text of the documentation
+ */
+function processFunction(name, args, comment) {
+ if (debug)
+ print("Processing " + name + " " + args + " " + comment);
+ return "<H2>Function " + name + "</H2>" +
+ "<PRE>" +
+ "function " + name + "(" + args + ")" +
+ "</PRE>" +
+ processComment(comment,0,name) +
+ "<P><BR><BR>";
+}
+
+/**
+ * Process a method being bound to a prototype.
+ * @param proto the name of the prototype
+ * @param name the name of the function
+ * @param args the args of the function as a single string
+ * @param comment the text of the comment
+ * @return a string for the HTML text of the documentation
+ */
+function processPrototypeMethod(proto, name, args, comment) {
+ if (debug)
+ print("Processing " + proto + ".prototype." + name + " " + args + " " + comment);
+ return "<H2> Method " + proto + ".prototype." + name + "</H2>" +
+ "<PRE>" +
+ proto + ".prototype." + name + " = function(" + args + ")" +
+ "</PRE>" +
+ processComment(comment,0,name) +
+ "<P><BR><BR>";
+}
+
+
+/**
+ * Process comment.
+ * @param comment the text of the comment
+ * @param firstLine shows if comment is at the beginning of the file
+ * @param fname name of the file (without path)
+ * @return a string for the HTML text of the documentation
+ */
+function processComment(comment,firstLine,fname) {
+ var tags = {};
+ // Use the "lambda" form of regular expression replace,
+ // where the replacement object is a function rather
+ // than a string. The function is called with the
+ // matched text and any parenthetical matches as
+ // arguments, and the result of the function used as the
+ // replacement text.
+ // Here we use the function to build up the "tags" object,
+ // which has a property for each "@" tag that is the name
+ // of the tag, and whose value is an array of the
+ // text following that tag.
+ comment = comment.replace(/@(\w+)\s+([^@]*)/g,
+ function (s, name, text) {
+ var a = tags[name] || [];
+ a.push(text);
+ tags[name] = a;
+ return "";
+ });
+
+ // if we have a comment at the beginning of a file
+ // store the comment for the index file
+ if (firstLine) {
+ indexFileArray[fname] = comment;
+ }
+
+ var out = comment + '<P>';
+ if (tags["param"]) {
+ // Create a table of parameters and their descriptions.
+ var array = tags["param"];
+ var params = "";
+ for (var i=0; i < array.length; i++) {
+ var m = array[i].match(/(\w+)\s+(.*)/);
+ params += '<TR><TD><I>'+m[1]+'</I></TD>' +
+ '<TD>'+m[2]+'</TD></TR>';
+ }
+ out += '<TABLE WIDTH="90%" BORDER=1>';
+ out += '<TR BGCOLOR=0xdddddddd>';
+ out += '<TD><B>Parameter</B></TD>';
+ out += '<TD><B>Description</B></TD></TR>';
+ out += params;
+ out += '</TABLE><P>';
+ }
+ if (tags["return"]) {
+ out += "<DT><B>Returns:</B><DD>";
+ out += tags["return"][0] + "</DL><P>";
+ }
+ if (tags["author"]) {
+ // List the authors together, separated by commas.
+ out += '<DT><B>Author:</B><DD>';
+ var array = tags["author"];
+ for (var i=0; i < array.length; i++) {
+ out += array[i];
+ if (i+1 < array.length)
+ out += ", ";
+ }
+ out += '</DL><P>';
+ }
+ if (tags["version"]) {
+ // Show the version.
+ out += '<DT><B>Version:</B><DD>';
+ var array = tags["version"];
+ for (var i=0; i < array.length; i++) {
+ out += array[i];
+ if (i+1 < array.length)
+ out += "<BR><DD>";
+ }
+ out += '</DL><P>';
+ }
+ if (tags["see"]) {
+ // List the see modules together, separated by <BR>.
+ out += '<DT><B>Dependencies:</B><DD>';
+ var array = tags["see"];
+ for (var i=0; i < array.length; i++) {
+ out += array[i];
+ if (i+1 < array.length)
+ out += "<BR><DD>";
+ }
+ out += '</DL><P>';
+ }
+ if (tags["lastmodified"]) {
+ // Shows a last modified description with client-side js.
+ out += '<DT><B>Last modified:</B><DD>';
+ out += '<script><!--\n';
+ out += 'document.writeln(document.lastModified);\n';
+ out += '// ---></script>\n';
+ out += '</DL><P>';
+ }
+
+ // additional tags can be added here (i.e., "if (tags["see"])...")
+ return out;
+}
+
+/**
+ * Create an html output file
+ * @param outputdir directory to put the file
+ * @param htmlfile name of the file
+*/
+function CreateOutputFile(outputdir,htmlfile)
+{
+ if (outputdir==null)
+ {
+ var outname = htmlfile;
+ }
+ else
+ {
+ var separator = Packages.java.io.File.separator;
+ var outname = outputdir + separator + htmlfile.substring(htmlfile.lastIndexOf(separator),htmlfile.length);
+ }
+ print("output file: " + outname);
+ return new File(outname);
+}
+
+/**
+ * Process a javascript file. Puts the generated HTML file in the outdir
+ * @param filename name of the javascript file
+ * @inputdir input directory of the file (default null)
+ */
+function processJSFile(filename,inputdir)
+{
+ if (debug) print("filename = " + filename + " inputdir = " + inputdir);
+
+ if (!filename.match(/\.js$/)) {
+ print("Expected filename to end in '.js'; had instead " +
+ filename + ". I don't treat the file.");
+ } else {
+ if (inputdir==null)
+ {
+ var inname = filename;
+ }
+ else
+ {
+ var separator = Packages.java.io.File.separator;
+ var inname = inputdir + separator + filename;
+ }
+ print("Processing file " + inname);
+
+ var f = new File(inname);
+
+ // create the output file
+ var htmlfile = filename.replace(/\.js$/, ".html");
+
+ var out = CreateOutputFile(outputdir,htmlfile);
+
+ processFile(f, filename, inputdir, out);
+ out.close();
+ }
+}
+
+/**
+ * Generate index files containing links to the processed javascript files
+ * and the generated functions
+ */
+function GenerateIndex(dirname)
+{
+ // construct the files index file
+ var out = CreateOutputFile(outputdir,indexFile);
+
+ // write the beginning of the file
+ out.writeLine('<HTML><HEADER><TITLE>File Index - directory: ' + dirname + '</TITLE><BODY>');
+ out.writeLine('<H1>File Index - directory: ' + dirname + '</H1>\n');
+ out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
+ out.writeLine('<TR BGCOLOR=0xdddddddd>');
+ out.writeLine('<TD><B>File</B></TD>');
+ out.writeLine('<TD><B>Description</B></TD></TR>');
+
+ var separator = Packages.java.io.File.separator;
+
+ // sort the index file array
+ var SortedFileArray = [];
+ for (var fname in indexFileArray)
+ SortedFileArray.push(fname);
+ SortedFileArray.sort();
+
+ for (var i=0; i < SortedFileArray.length; i++) {
+ var fname = SortedFileArray[i];
+ var htmlfile = fname.replace(/\.js$/, ".html");
+ out.writeLine('<TR><TD><A HREF=\"' + htmlfile + '\">' + fname + '</A></TD></TD><TD>');
+ if (indexFileArray[fname])
+ out.writeLine(indexFileArray[fname]);
+ else
+ out.writeLine('No comments');
+ out.writeLine('</TD></TR>\n');
+ }
+ out.writeLine('</TABLE></BODY></HTML>');
+ out.close();
+
+ // construct the functions index file
+ var out = CreateOutputFile(outputdir,indexFunction);
+
+ // write the beginning of the file
+ out.writeLine('<HTML><HEADER><TITLE>Function Index - directory: ' + dirname + '</TITLE><BODY>');
+ out.writeLine('<H1>Function Index - directory: ' + dirname + '</H1>\n');
+ out.writeLine('<TABLE WIDTH="90%" BORDER=1>');
+ out.writeLine('<TR BGCOLOR=0xdddddddd>');
+ out.writeLine('<TD><B>Function</B></TD>');
+ out.writeLine('<TD><B>Files</B></TD></TR>');
+
+ // sort the function array
+ var SortedFunctionArray = [];
+ for (var functionname in indexFunctionArray)
+ SortedFunctionArray.push(functionname);
+ SortedFunctionArray.sort();
+
+ for (var j=0; j < SortedFunctionArray.length; j++) {
+ var funcname = SortedFunctionArray[j];
+ with (indexFunctionArray[funcname]) {
+ var outstr = '<TR><TD>' + funcname + '</TD><TD>';
+ var filelst = filename.split("|");
+ for (var i in filelst) {
+ var htmlfile = filelst[i].replace(/\.js$/, ".html");
+ outstr += '<A HREF=\"' + htmlfile + '#' + funcname + '\">' + filelst[i] + '</A>&nbsp;';
+ }
+ outstr += '</TD></TR>';
+ out.writeLine(outstr);
+ }
+ }
+ out.writeLine('</TABLE></BODY></HTML>');
+ out.close();
+}
+
+
+/**
+ * prints the options for JSDoc
+*/
+function PrintOptions()
+{
+ print("You can use the following options:\n");
+ print("-d: specify an output directory for the generated html files\n");
+ print("-i: processes all files in an input directory (you can specify several directories)\n");
+ quit();
+}
+
+
+// Main Script
+// first read the arguments
+if (! arguments)
+ PrintOptions();
+
+for (var i=0; i < arguments.length; i++) {
+ if (debug) print("argument: + \'" + arguments[i] + "\'");
+ if (arguments[i].match(/^\-/)) {
+ if (String(arguments[i])=="-d"){
+ // output directory for the generated html files
+
+ outputdir = String(arguments[i+1]);
+ if (debug) print("outputdir: + \'" + outputdir + "\'");
+
+ i++;
+ }
+ else if (String(arguments[i])=="-i"){
+ // process all files in an input directory
+
+ DirList.push(String(arguments[i+1]));
+if (debug) print("inputdir: + \'" + arguments[i+1] + "\'");
+ i++;
+ }
+ else {
+ print("Unknown option: " + arguments[i] + "\n");
+ PrintOptions();
+ }
+ }
+ else
+ {
+ // we have a single file
+ if (debug) print("file: + \'" + arguments[i] + "\'");
+
+ FileList.push(String(arguments[i]));
+ }
+}
+
+// first handle the single files
+for (var i in FileList)
+ processJSFile(FileList[i],null);
+
+// then handle the input directories
+for (var j in DirList) {
+ var inputdir = String(DirList[j]);
+
+ print("Process input directory: " + inputdir);
+
+ // clean up index arrays
+ var indexFileArray = [];
+ var indexFunctionArray = [];
+
+ // for the directory name get rid of ../../ or ..\..\
+ inputDirName = inputdir.replace(/\.\.\/|\.\.\\/g,"");
+
+ indexFile = indexFileName + "_" + inputDirName + ".html";
+ indexFunction = indexFunctionName + "_" + inputDirName + ".html";
+
+print("indexFile = " + indexFile);
+print("indexFunction = " + indexFunction);
+
+ // read the files in the directory
+ var DirFile = new java.io.File(inputdir);
+ var lst = DirFile.list();
+ var separator = Packages.java.io.File.separator;
+
+ for (var i=0; i < lst.length; i++)
+ {
+ processJSFile(String(lst[i]),inputdir);
+ }
+
+ // generate the index files for the input directory
+ GenerateIndex(inputDirName);
+}
+
+
+
diff --git a/infrastructure/rhino1_7R1/examples/liveConnect.js b/infrastructure/rhino1_7R1/examples/liveConnect.js
new file mode 100644
index 0000000..7befc08
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/liveConnect.js
@@ -0,0 +1,57 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
+ */
+
+// Create a new StringBuffer. Note that the class name must be fully qualified
+// by its package. Packages other than "java" must start with "Packages", i.e.,
+// "Packages.javax.servlet...".
+var sb = new java.lang.StringBuffer();
+
+// Now add some stuff to the buffer.
+sb.append("hi, mom");
+sb.append(3); // this will add "3.0" to the buffer since all JS numbers
+ // are doubles by default
+sb.append(true);
+
+// Now print it out. (The toString() method of sb is automatically called
+// to convert the buffer to a string.)
+// Should print "hi, mom3.0true".
+print(sb);
diff --git a/infrastructure/rhino1_7R1/examples/unique.js b/infrastructure/rhino1_7R1/examples/unique.js
new file mode 100644
index 0000000..a4274bb
--- /dev/null
+++ b/infrastructure/rhino1_7R1/examples/unique.js
@@ -0,0 +1,56 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// unique.js: read the contents of a file and print out the unique lines
+
+defineClass("File")
+
+// "arguments[0]" refers to the first argument at the command line to the
+// script, if present. If not present, "arguments[0]" will be undefined,
+// which will cause f to read from System.in.
+var f = new File(arguments[0]);
+var o = {}
+var line;
+while ((line = f.readLine()) != null) {
+ // Use JavaScript objects' inherent nature as an associative
+ // array to provide uniqueness
+ o[line] = true;
+}
+for (i in o) {
+ print(i);
+}
diff --git a/infrastructure/rhino1_7R1/javadoc/allclasses-frame.html b/infrastructure/rhino1_7R1/javadoc/allclasses-frame.html
new file mode 100644
index 0000000..073b251
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/allclasses-frame.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+All Classes (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Callable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript" target="classFrame">ClassCache</A>
+<BR>
+<A HREF="org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer" target="classFrame">ClassCompiler</A>
+<BR>
+<A HREF="org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ClassShutter</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript" target="classFrame">CompilerEnvirons</A>
+<BR>
+<A HREF="org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript" target="classFrame">Context</A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ContextAction</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript" target="classFrame">ContextFactory</A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ContextFactory.Listener</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug" target="classFrame"><I>DebuggableScript</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript" target="classFrame">EcmaError</A>
+<BR>
+<A HREF="org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ErrorReporter</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript" target="classFrame">EvaluatorException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Function</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript" target="classFrame">FunctionObject</A>
+<BR>
+<A HREF="org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript" target="classFrame"><I>GeneratedClassLoader</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript" target="classFrame">ImporterTopLevel</A>
+<BR>
+<A HREF="org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript" target="classFrame">JavaScriptException</A>
+<BR>
+<A HREF="org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>RefCallable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript" target="classFrame">RhinoException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Script</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Scriptable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize" target="classFrame">ScriptableInputStream</A>
+<BR>
+<A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript" target="classFrame">ScriptableObject</A>
+<BR>
+<A HREF="org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize" target="classFrame">ScriptableOutputStream</A>
+<BR>
+<A HREF="org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript" target="classFrame">SecurityController</A>
+<BR>
+<A HREF="org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript" target="classFrame">Synchronizer</A>
+<BR>
+<A HREF="org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript" target="classFrame">WrapFactory</A>
+<BR>
+<A HREF="org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript" target="classFrame">WrappedException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Wrapper</I></A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/allclasses-noframe.html b/infrastructure/rhino1_7R1/javadoc/allclasses-noframe.html
new file mode 100644
index 0000000..48536b4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/allclasses-noframe.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+All Classes (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><I>Callable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<BR>
+<A HREF="org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<BR>
+<A HREF="org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><I>ClassShutter</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<BR>
+<A HREF="org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><I>ContextAction</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<BR>
+<A HREF="org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><I>ContextFactory.Listener</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug"><I>DebuggableScript</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<BR>
+<A HREF="org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><I>ErrorReporter</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><I>Function</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<BR>
+<A HREF="org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><I>GeneratedClassLoader</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<BR>
+<A HREF="org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<BR>
+<A HREF="org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><I>RefCallable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><I>Script</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><I>Scriptable</I></A>
+<BR>
+<A HREF="org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableInputStream</A>
+<BR>
+<A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<BR>
+<A HREF="org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<BR>
+<A HREF="org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<BR>
+<A HREF="org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A>
+<BR>
+<A HREF="org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<BR>
+<A HREF="org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A>
+<BR>
+<A HREF="org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><I>Wrapper</I></A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/constant-values.html b/infrastructure/rhino1_7R1/javadoc/constant-values.html
new file mode 100644
index 0000000..b29b7ba
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/constant-values.html
@@ -0,0 +1,424 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Constant Field Values (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Constant Field Values (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?constant-values.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="constant-values.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+Constant Field Values</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+<B>Contents</B><UL>
+<LI><A HREF="#org.mozilla">org.mozilla.*</A>
+</UL>
+
+<A NAME="org.mozilla"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left"><FONT SIZE="+2">
+org.mozilla.*</FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.errorReporterProperty"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#errorReporterProperty">errorReporterProperty</A></CODE></TD>
+<TD ALIGN="right"><CODE>"error reporter"</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_DYNAMIC_SCOPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE">FEATURE_DYNAMIC_SCOPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>7</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_E4X"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_E4X">FEATURE_E4X</A></CODE></TD>
+<TD ALIGN="right"><CODE>6</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_ENHANCED_JAVA_ACCESS"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_ENHANCED_JAVA_ACCESS">FEATURE_ENHANCED_JAVA_ACCESS</A></CODE></TD>
+<TD ALIGN="right"><CODE>13</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_LOCATION_INFORMATION_IN_ERROR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_LOCATION_INFORMATION_IN_ERROR">FEATURE_LOCATION_INFORMATION_IN_ERROR</A></CODE></TD>
+<TD ALIGN="right"><CODE>10</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME">FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_NON_ECMA_GET_YEAR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_NON_ECMA_GET_YEAR">FEATURE_NON_ECMA_GET_YEAR</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_PARENT_PROTO_PROPERTIES"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPERTIES">FEATURE_PARENT_PROTO_PROPERTIES</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_PARENT_PROTO_PROPRTIES"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPRTIES">FEATURE_PARENT_PROTO_PROPRTIES</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER">FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</A></CODE></TD>
+<TD ALIGN="right"><CODE>3</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_STRICT_EVAL"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_STRICT_EVAL">FEATURE_STRICT_EVAL</A></CODE></TD>
+<TD ALIGN="right"><CODE>9</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_STRICT_MODE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_STRICT_MODE">FEATURE_STRICT_MODE</A></CODE></TD>
+<TD ALIGN="right"><CODE>11</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_STRICT_VARS"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_STRICT_VARS">FEATURE_STRICT_VARS</A></CODE></TD>
+<TD ALIGN="right"><CODE>8</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_TO_STRING_AS_SOURCE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_TO_STRING_AS_SOURCE">FEATURE_TO_STRING_AS_SOURCE</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.FEATURE_WARNING_AS_ERROR"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#FEATURE_WARNING_AS_ERROR">FEATURE_WARNING_AS_ERROR</A></CODE></TD>
+<TD ALIGN="right"><CODE>12</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.languageVersionProperty"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;java.lang.String</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#languageVersionProperty">languageVersionProperty</A></CODE></TD>
+<TD ALIGN="right"><CODE>"language version"</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_0"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_0">VERSION_1_0</A></CODE></TD>
+<TD ALIGN="right"><CODE>100</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_1"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_1">VERSION_1_1</A></CODE></TD>
+<TD ALIGN="right"><CODE>110</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_2"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_2">VERSION_1_2</A></CODE></TD>
+<TD ALIGN="right"><CODE>120</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_3"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_3">VERSION_1_3</A></CODE></TD>
+<TD ALIGN="right"><CODE>130</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_4"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_4">VERSION_1_4</A></CODE></TD>
+<TD ALIGN="right"><CODE>140</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_5"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_5">VERSION_1_5</A></CODE></TD>
+<TD ALIGN="right"><CODE>150</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_6"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_6">VERSION_1_6</A></CODE></TD>
+<TD ALIGN="right"><CODE>160</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_1_7"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_1_7">VERSION_1_7</A></CODE></TD>
+<TD ALIGN="right"><CODE>170</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_DEFAULT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_DEFAULT">VERSION_DEFAULT</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.Context.VERSION_UNKNOWN"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/Context.html#VERSION_UNKNOWN">VERSION_UNKNOWN</A></CODE></TD>
+<TD ALIGN="right"><CODE>-1</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.mozilla.javascript.<A HREF="org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_BOOLEAN_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_BOOLEAN_TYPE">JAVA_BOOLEAN_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>3</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_DOUBLE_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_DOUBLE_TYPE">JAVA_DOUBLE_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_INT_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_INT_TYPE">JAVA_INT_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_OBJECT_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_OBJECT_TYPE">JAVA_OBJECT_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>6</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_SCRIPTABLE_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_SCRIPTABLE_TYPE">JAVA_SCRIPTABLE_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>5</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_STRING_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_STRING_TYPE">JAVA_STRING_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.FunctionObject.JAVA_UNSUPPORTED_TYPE"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/FunctionObject.html#JAVA_UNSUPPORTED_TYPE">JAVA_UNSUPPORTED_TYPE</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="3">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.CONST"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#CONST">CONST</A></CODE></TD>
+<TD ALIGN="right"><CODE>13</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.DONTENUM"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#DONTENUM">DONTENUM</A></CODE></TD>
+<TD ALIGN="right"><CODE>2</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.EMPTY"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#EMPTY">EMPTY</A></CODE></TD>
+<TD ALIGN="right"><CODE>0</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.PERMANENT"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#PERMANENT">PERMANENT</A></CODE></TD>
+<TD ALIGN="right"><CODE>4</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.READONLY"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#READONLY">READONLY</A></CODE></TD>
+<TD ALIGN="right"><CODE>1</CODE></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<A NAME="org.mozilla.javascript.ScriptableObject.UNINITIALIZED_CONST"><!-- --></A><TD ALIGN="right"><FONT SIZE="-1">
+<CODE>public&nbsp;static&nbsp;final&nbsp;int</CODE></FONT></TD>
+<TD ALIGN="left"><CODE><A HREF="org/mozilla/javascript/ScriptableObject.html#UNINITIALIZED_CONST">UNINITIALIZED_CONST</A></CODE></TD>
+<TD ALIGN="right"><CODE>8</CODE></TD>
+</TR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?constant-values.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="constant-values.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/deprecated-list.html b/infrastructure/rhino1_7R1/javadoc/deprecated-list.html
new file mode 100644
index 0000000..923cc54
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/deprecated-list.html
@@ -0,0 +1,386 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Deprecated List (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Deprecated List (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?deprecated-list.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="deprecated-list.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Deprecated API</B></H2>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+<B>Contents</B><UL>
+<LI><A HREF="#field">Deprecated Fields</A>
+<LI><A HREF="#method">Deprecated Methods</A>
+<LI><A HREF="#constructor">Deprecated Constructors</A>
+</UL>
+
+<A NAME="field"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Deprecated Fields</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPRTIES">org.mozilla.javascript.Context.FEATURE_PARENT_PROTO_PROPRTIES</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>In previous releases, this name was given to
+ FEATURE_PARENT_PROTO_PROPERTIES.</I>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="method"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Deprecated Methods</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#addContextListener(org.mozilla.javascript.ContextListener)">org.mozilla.javascript.Context.addContextListener(ContextListener)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)">org.mozilla.javascript.Context.call(ContextAction)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <A HREF="org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as
+ this method relies on usage of a static singleton "global"
+ ContextFactory.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#compileReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)">org.mozilla.javascript.Context.compileReader(Scriptable, Reader, String, int, Object)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)">org.mozilla.javascript.FunctionObject.convertArg(Context, Scriptable, Object, Class)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)"><CODE>FunctionObject.getTypeTag(Class)</CODE></A>
+ and <A HREF="org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><CODE>FunctionObject.convertArg(Context, Scriptable, Object, int)</CODE></A>
+ for type convertion.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#enter()">org.mozilla.javascript.Context.enter()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <A HREF="org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as this method relies
+ on usage of a static singleton "global" ContextFactory.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ContextFactory.html#enter()">org.mozilla.javascript.ContextFactory.enter()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <A HREF="org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A> instead</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#enter(org.mozilla.javascript.Context)">org.mozilla.javascript.Context.enter(Context)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <A HREF="org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><CODE>ContextFactory.enterContext(Context)</CODE></A> instead as
+ this method relies on usage of a static singleton "global" ContextFactory.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/SecurityController.html#execWithDomain(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Script, java.lang.Object)">org.mozilla.javascript.SecurityController.execWithDomain(Context, Scriptable, Script, Object)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>The application should not override this method and instead
+ override
+ <A HREF="org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>SecurityController.callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)</CODE></A>.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ContextFactory.html#exit()">org.mozilla.javascript.ContextFactory.exit()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A> instead.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ScriptableObject.html#getAttributes(int, org.mozilla.javascript.Scriptable)">org.mozilla.javascript.ScriptableObject.getAttributes(int, Scriptable)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/ScriptableObject.html#getAttributes(int)"><CODE>ScriptableObject.getAttributes(int index)</CODE></A>. The engine always
+ ignored the start argument.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)">org.mozilla.javascript.ScriptableObject.getAttributes(String, Scriptable)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>ScriptableObject.getAttributes(String name)</CODE></A>. The engine always
+ ignored the start argument.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#getColumnNumber()">org.mozilla.javascript.EcmaError.getColumnNumber()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EvaluatorException.html#getColumnNumber()">org.mozilla.javascript.EvaluatorException.getColumnNumber()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#getErrorObject()">org.mozilla.javascript.EcmaError.getErrorObject()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Always returns <b>null</b>.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#getLineNumber()">org.mozilla.javascript.EcmaError.getLineNumber()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EvaluatorException.html#getLineNumber()">org.mozilla.javascript.EvaluatorException.getLineNumber()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/JavaScriptException.html#getLineNumber()">org.mozilla.javascript.JavaScriptException.getLineNumber()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#getLineSource()">org.mozilla.javascript.EcmaError.getLineSource()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EvaluatorException.html#getLineSource()">org.mozilla.javascript.EvaluatorException.getLineSource()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#getSourceName()">org.mozilla.javascript.EcmaError.getSourceName()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EvaluatorException.html#getSourceName()">org.mozilla.javascript.EvaluatorException.getSourceName()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/JavaScriptException.html#getSourceName()">org.mozilla.javascript.JavaScriptException.getSourceName()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#hasCompileFunctionsWithDynamicScope()">org.mozilla.javascript.Context.hasCompileFunctionsWithDynamicScope()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ImporterTopLevel.html#importPackage(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[], org.mozilla.javascript.Function)">org.mozilla.javascript.ImporterTopLevel.importPackage(Context, Scriptable, Object[], Function)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Kept only for compatibility.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ClassCache.html#isInvokerOptimizationEnabled()">org.mozilla.javascript.ClassCache.isInvokerOptimizationEnabled()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>The method always returns false.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#removeContextListener(org.mozilla.javascript.ContextListener)">org.mozilla.javascript.Context.removeContextListener(ContextListener)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ScriptableObject.html#setAttributes(int, org.mozilla.javascript.Scriptable, int)">org.mozilla.javascript.ScriptableObject.setAttributes(int, Scriptable, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)"><CODE>ScriptableObject.setAttributes(int index, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)">org.mozilla.javascript.ScriptableObject.setAttributes(String, Scriptable, int)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>ScriptableObject.setAttributes(String name, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#setCachingEnabled(boolean)">org.mozilla.javascript.Context.setCachingEnabled(boolean)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#setCompileFunctionsWithDynamicScope(boolean)">org.mozilla.javascript.Context.setCompileFunctionsWithDynamicScope(boolean)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/ClassCache.html#setInvokerOptimizationEnabled(boolean)">org.mozilla.javascript.ClassCache.setInvokerOptimizationEnabled(boolean)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>The method does nothing.
+ Invoker optimization is no longer used by Rhino.
+ On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
+ like increased memory usage or longer initialization time overweight
+ small speed increase that can be gained using generated proxy class
+ to replace reflection.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable, java.lang.Class)">org.mozilla.javascript.Context.toObject(Object, Scriptable, Class)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#toType(java.lang.Object, java.lang.Class)">org.mozilla.javascript.Context.toType(Object, Class)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I></I>&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/WrappedException.html#unwrap()">org.mozilla.javascript.WrappedException.unwrap()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/WrappedException.html#getWrappedException()"><CODE>WrappedException.getWrappedException()</CODE></A> instead.</I>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<A NAME="constructor"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Deprecated Constructors</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/Context.html#Context()">org.mozilla.javascript.Context()</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>use <A HREF="org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/EcmaError.html#EcmaError(org.mozilla.javascript.Scriptable, java.lang.String, int, int, java.lang.String)">org.mozilla.javascript.EcmaError(Scriptable, String, int, int, String)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>EcmaError error instances should not be constructed
+ explicitly since they are generated by the engine.</I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="org/mozilla/javascript/JavaScriptException.html#JavaScriptException(java.lang.Object)">org.mozilla.javascript.JavaScriptException(Object)</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>Use <A HREF="org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)"><CODE>WrappedException.WrappedException(Throwable)</CODE></A> to report
+ exceptions in Java code.</I>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?deprecated-list.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="deprecated-list.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/help-doc.html b/infrastructure/rhino1_7R1/javadoc/help-doc.html
new file mode 100644
index 0000000..7a2e353
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/help-doc.html
@@ -0,0 +1,217 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+API Help (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="API Help (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+How This API Document Is Organized</H1>
+</CENTER>
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
+Overview</H3>
+<BLOCKQUOTE>
+
+<P>
+The <A HREF="overview-summary.html">Overview</A> page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.</BLOCKQUOTE>
+<H3>
+Package</H3>
+<BLOCKQUOTE>
+
+<P>
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
+<LI>Interfaces (italic)<LI>Classes<LI>Enums<LI>Exceptions<LI>Errors<LI>Annotation Types</UL>
+</BLOCKQUOTE>
+<H3>
+Class/Interface</H3>
+<BLOCKQUOTE>
+
+<P>
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
+<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
+<P>
+<LI>Nested Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
+<P>
+<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
+</BLOCKQUOTE>
+<H3>
+Annotation Type</H3>
+<BLOCKQUOTE>
+
+<P>
+Each annotation type has its own separate page with the following sections:<UL>
+<LI>Annotation Type declaration<LI>Annotation Type description<LI>Required Element Summary<LI>Optional Element Summary<LI>Element Detail</UL>
+</BLOCKQUOTE>
+</BLOCKQUOTE>
+<H3>
+Enum</H3>
+<BLOCKQUOTE>
+
+<P>
+Each enum has its own separate page with the following sections:<UL>
+<LI>Enum declaration<LI>Enum description<LI>Enum Constant Summary<LI>Enum Constant Detail</UL>
+</BLOCKQUOTE>
+<H3>
+Tree (Class Hierarchy)</H3>
+<BLOCKQUOTE>
+There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
+<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
+</BLOCKQUOTE>
+<H3>
+Deprecated API</H3>
+<BLOCKQUOTE>
+The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
+<H3>
+Index</H3>
+<BLOCKQUOTE>
+The <A HREF="index-all.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
+<H3>
+Prev/Next</H3>
+These links take you to the next or previous class, interface, package, or related page.<H3>
+Frames/No Frames</H3>
+These links show and hide the HTML frames. All pages are available with or without frames.
+<P>
+<H3>
+Serialized Form</H3>
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+<P>
+<H3>
+Constant Field Values</H3>
+The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.
+<P>
+<FONT SIZE="-1">
+<EM>
+This help file applies to API documentation generated using the standard doclet.</EM>
+</FONT>
+<BR>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?help-doc.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="help-doc.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/index-all.html b/infrastructure/rhino1_7R1/javadoc/index-all.html
new file mode 100644
index 0000000..15ba433
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/index-all.html
@@ -0,0 +1,1566 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Index (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="./stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Index (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="./index.html?index-all.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-all.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="./allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="./allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<A HREF="#_A_">A</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_J_">J</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A> <HR>
+<A NAME="_A_"><!-- --></A><H2>
+<B>A</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#addActivationName(java.lang.String)"><B>addActivationName(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Add a name to the list of names forcing the creation of real
+ activation objects for functions.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#addAsConstructor(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)"><B>addAsConstructor(Scriptable, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Define this function as a JavaScript constructor.
+<DT><A HREF="./org/mozilla/javascript/Context.html#addContextListener(org.mozilla.javascript.ContextListener)"><B>addContextListener(ContextListener)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#addExcludedName(java.lang.String)"><B>addExcludedName(String)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>Adds a qualified name to the list of object to be excluded from
+ serialization.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#addListener(org.mozilla.javascript.ContextFactory.Listener)"><B>addListener(ContextFactory.Listener)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#addOptionalExcludedName(java.lang.String)"><B>addOptionalExcludedName(String)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>Adds a qualified name to the list of object to be excluded from
+ serialization.
+<DT><A HREF="./org/mozilla/javascript/Context.html#addPropertyChangeListener(java.beans.PropertyChangeListener)"><B>addPropertyChangeListener(PropertyChangeListener)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Register an object to receive notifications when a bound property
+ has changed
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#associate(org.mozilla.javascript.ScriptableObject)"><B>associate(ScriptableObject)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Associate ClassCache object with the given top-level scope.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#associateValue(java.lang.Object, java.lang.Object)"><B>associateValue(Object, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Associate arbitrary application-specific value with this object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#avoidObjectDetection()"><B>avoidObjectDetection()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Emulate the SpiderMonkey (and Firefox) feature of allowing
+ custom objects to avoid detection by normal "object detection"
+ code patterns.
+</DL>
+<HR>
+<A NAME="_C_"><!-- --></A><H2>
+<B>C</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>call(Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>
+<DD>Perform the call.
+<DT><A HREF="./org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)"><B>call(ContextAction)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="./org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as
+ this method relies on usage of a static singleton "global"
+ ContextFactory.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextFactory, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>call(ContextFactory, Callable, Scriptable, Scriptable, Object[])</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Call <A HREF="./org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ using the Context instance associated with the current thread.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><B>call(ContextAction)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Call <A HREF="./org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context cx)</CODE></A>
+ using the <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance associated with the current thread.
+<DT><A HREF="./org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>call(Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>
+<DD>Call the function.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>call(Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Performs conversions on argument types if needed and
+ invokes the underlying Java method or constructor.
+<DT><A HREF="./org/mozilla/javascript/Synchronizer.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>call(Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><B>Callable</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Generic notion of callable object that can execute some script-related code
+ upon request with specified values for script scope and this objects.<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><B>callMethod(Scriptable, String, Object[])</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Call a method of an object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><B>callMethod(Context, Scriptable, String, Object[])</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Call a method of an object.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>callWithDomain(Object, Context, Callable, Scriptable, Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Call <A HREF="./org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ of <i>callable</i> under restricted security domain where an action is
+ allowed only if it is allowed according to the Java stack on the
+ moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.
+<DT><A HREF="./org/mozilla/javascript/Context.html#checkLanguageVersion(int)"><B>checkLanguageVersion(int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#checkNotSealed()"><B>checkNotSealed()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#checkOptimizationLevel(int)"><B>checkOptimizationLevel(int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>ClassCache</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Cache of generated classes and data structures to access Java runtime
+ from JavaScript.<DT><A HREF="./org/mozilla/javascript/ClassCache.html#ClassCache()"><B>ClassCache()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer"><B>ClassCompiler</B></A> - Class in <A HREF="./org/mozilla/javascript/optimizer/package-summary.html">org.mozilla.javascript.optimizer</A><DD>Generates class files from script sources.<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#ClassCompiler(org.mozilla.javascript.CompilerEnvirons)"><B>ClassCompiler(CompilerEnvirons)</B></A> -
+Constructor for class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Construct ClassCompiler that uses the specified compiler environment
+ when generating classes.
+<DT><A HREF="./org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>ClassShutter</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Embeddings that wish to filter Java classes that are visible to scripts
+through the LiveConnect, should implement this interface.<DT><A HREF="./org/mozilla/javascript/ClassCache.html#clearCaches()"><B>clearCaches()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Empty caches of generated Java classes and Java reflection information.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#columnNumber()"><B>columnNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>The column number of the location of the error, or zero if unknown.
+<DT><A HREF="./org/mozilla/javascript/Context.html#compileFunction(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)"><B>compileFunction(Scriptable, String, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Compile a JavaScript function.
+<DT><A HREF="./org/mozilla/javascript/Context.html#compileReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)"><B>compileReader(Scriptable, Reader, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#compileReader(java.io.Reader, java.lang.String, int, java.lang.Object)"><B>compileReader(Reader, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Compiles the source in the given reader.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>CompilerEnvirons</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>&nbsp;<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#CompilerEnvirons()"><B>CompilerEnvirons()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#compileString(java.lang.String, java.lang.String, int, java.lang.Object)"><B>compileString(String, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Compiles the source in the given string.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#compileToClassFiles(java.lang.String, java.lang.String, int, java.lang.String)"><B>compileToClassFiles(String, String, int, String)</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Compile JavaScript source into one or more Java class files.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#CONST"><B>CONST</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Function.html#construct(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>construct(Context, Scriptable, Object[])</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>
+<DD>Call the function as a constructor.
+<DT><A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>Context</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This class represents the runtime context of an executing script.<DT><A HREF="./org/mozilla/javascript/Context.html#Context()"><B>Context()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="./org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="./org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead.</I>
+<DT><A HREF="./org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>ContextAction</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Interface to represent arbitrary action that requires to have Context
+ object associated with the current thread for its execution.<DT><A HREF="./org/mozilla/javascript/ContextFactory.Listener.html#contextCreated(org.mozilla.javascript.Context)"><B>contextCreated(Context)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>
+<DD>Notify about newly created <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> object.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>ContextFactory</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Factory class that Rhino runtime uses to create new <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>
+ instances.<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#ContextFactory()"><B>ContextFactory()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>ContextFactory.Listener</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Listener of <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> creation and release events.<DT><A HREF="./org/mozilla/javascript/ContextFactory.Listener.html#contextReleased(org.mozilla.javascript.Context)"><B>contextReleased(Context)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>
+<DD>Notify that the specified <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance is no longer
+ associated with the current thread.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><B>convertArg(Context, Scriptable, Object, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><B>convertArg(Context, Scriptable, Object, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)"><CODE>FunctionObject.getTypeTag(Class)</CODE></A>
+ and <A HREF="./org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><CODE>FunctionObject.convertArg(Context, Scriptable, Object, int)</CODE></A>
+ for type convertion.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#createClassLoader(java.lang.ClassLoader)"><B>createClassLoader(ClassLoader)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Create class loader for generated classes.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#createClassLoader(java.lang.ClassLoader)"><B>createClassLoader(ClassLoader)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Create class loader for generated classes.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#createClassLoader(java.lang.ClassLoader, java.lang.Object)"><B>createClassLoader(ClassLoader, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Get class loader-like object that can be used
+ to define classes with the given security context.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#createLoader(java.lang.ClassLoader, java.lang.Object)"><B>createLoader(ClassLoader, Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Create <A HREF="./org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><CODE>GeneratedClassLoader</CODE></A> with restrictions imposed by
+ staticDomain and all current stack frames.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#createObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)"><B>createObject(Context, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Return new <A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A> instance using the default
+ constructor for the class of the underlying Java method.
+</DL>
+<HR>
+<A NAME="_D_"><!-- --></A><H2>
+<B>D</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug"><B>DebuggableScript</B></A> - Interface in <A HREF="./org/mozilla/javascript/debug/package-summary.html">org.mozilla.javascript.debug</A><DD>This interface exposes debugging information from executable
+ code (either functions or top-level scripts).<DT><A HREF="./org/mozilla/javascript/Context.html#decompileFunction(org.mozilla.javascript.Function, int)"><B>decompileFunction(Function, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Decompile a JavaScript Function.
+<DT><A HREF="./org/mozilla/javascript/Context.html#decompileFunctionBody(org.mozilla.javascript.Function, int)"><B>decompileFunctionBody(Function, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Decompile the body of a JavaScript Function.
+<DT><A HREF="./org/mozilla/javascript/Context.html#decompileScript(org.mozilla.javascript.Script, int)"><B>decompileScript(Script, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Decompile the script.
+<DT><A HREF="./org/mozilla/javascript/GeneratedClassLoader.html#defineClass(java.lang.String, byte[])"><B>defineClass(String, byte[])</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A>
+<DD>Define a new Java class.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)"><B>defineClass(Scriptable, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Defines JavaScript objects from a Java class that implements Scriptable.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean)"><B>defineClass(Scriptable, Class, boolean)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Defines JavaScript objects from a Java class, optionally
+ allowing sealing.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean, boolean)"><B>defineClass(Scriptable, Class, boolean, boolean)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Defines JavaScript objects from a Java class, optionally
+ allowing sealing and mapping of Java inheritance to JavaScript
+ prototype-based inheritance.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineConst(java.lang.String, org.mozilla.javascript.Scriptable)"><B>defineConst(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineConstProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><B>defineConstProperty(Scriptable, String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Utility method to add properties to arbitrary Scriptable object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineFunctionProperties(java.lang.String[], java.lang.Class, int)"><B>defineFunctionProperties(String[], Class, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Search for names in a class, adding the resulting methods
+ as properties.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, int)"><B>defineProperty(String, Object, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Define a JavaScript property.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object, int)"><B>defineProperty(Scriptable, String, Object, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Utility method to add properties to arbitrary Scriptable object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Class, int)"><B>defineProperty(String, Class, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Define a JavaScript property with getter and setter side effects.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, int)"><B>defineProperty(String, Object, Method, Method, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Define a JavaScript property.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#delete(java.lang.String)"><B>delete(String)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Removes a property from this object.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#delete(int)"><B>delete(int)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Removes a property from this object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#delete(java.lang.String)"><B>delete(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Removes a named property from the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#delete(int)"><B>delete(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Removes the indexed property from the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><B>deleteProperty(Scriptable, String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Removes the property from an object or its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)"><B>deleteProperty(Scriptable, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Removes the property from an object or its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#details()"><B>details()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#details()"><B>details()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#details()"><B>details()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#DONTENUM"><B>DONTENUM</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Property attribute indicating property is not enumerated.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#doTopCall(org.mozilla.javascript.Callable, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>doTopCall(Callable, Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Execute top call to script or function.
+</DL>
+<HR>
+<A NAME="_E_"><!-- --></A><H2>
+<B>E</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>EcmaError</B></A> - Exception in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>The class of exceptions raised by the engine as described in
+ ECMA edition 3.<DT><A HREF="./org/mozilla/javascript/EcmaError.html#EcmaError(org.mozilla.javascript.Scriptable, java.lang.String, int, int, java.lang.String)"><B>EcmaError(Scriptable, String, int, int, String)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>EcmaError error instances should not be constructed
+ explicitly since they are generated by the engine.</I>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#EMPTY"><B>EMPTY</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>The empty property attribute.
+<DT><A HREF="./org/mozilla/javascript/Context.html#emptyArgs"><B>emptyArgs</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convenient value to use as zero-length array of objects.
+<DT><A HREF="./org/mozilla/javascript/Context.html#enter()"><B>enter()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="./org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="./org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as this method relies
+ on usage of a static singleton "global" ContextFactory.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#enter(org.mozilla.javascript.Context)"><B>enter(Context)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="./org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><CODE>ContextFactory.enterContext(Context)</CODE></A> instead as
+ this method relies on usage of a static singleton "global" ContextFactory.</I>
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#enter()"><B>enter()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="./org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A> instead</I>
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#enterContext()"><B>enterContext()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Get a context associated with the current thread, creating one if need
+ be.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><B>enterContext(Context)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Get a Context associated with the current thread, using the given
+ Context if need be.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#equivalentValues(java.lang.Object)"><B>equivalentValues(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Custom <tt>==</tt> operator.
+<DT><A HREF="./org/mozilla/javascript/ErrorReporter.html#error(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>error(String, String, int, String, int)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>
+<DD>Report an error.
+<DT><A HREF="./org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>ErrorReporter</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This is interface defines a protocol for the reporting of
+ errors during JavaScript translation or execution.<DT><A HREF="./org/mozilla/javascript/Context.html#errorReporterProperty"><B>errorReporterProperty</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#evaluateReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)"><B>evaluateReader(Scriptable, Reader, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Evaluate a reader as JavaScript source.
+<DT><A HREF="./org/mozilla/javascript/Context.html#evaluateString(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)"><B>evaluateString(Scriptable, String, String, int, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Evaluate a JavaScript source string.
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>EvaluatorException</B></A> - Exception in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>The class of exceptions thrown by the JavaScript engine.<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String)"><B>EvaluatorException(String)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String, java.lang.String, int)"><B>EvaluatorException(String, String, int)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD>Create an exception with the specified detail message.
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>EvaluatorException(String, String, int, String, int)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD>Create an exception with the specified detail message.
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#excludeStandardObjectNames()"><B>excludeStandardObjectNames()</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>Adds the names of the standard objects and their
+ prototypes to the list of excluded names.
+<DT><A HREF="./org/mozilla/javascript/Script.html#exec(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)"><B>exec(Context, Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>
+<DD>Execute the script.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#execIdCall(org.mozilla.javascript.IdFunctionObject, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>execIdCall(IdFunctionObject, Context, Scriptable, Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#execWithDomain(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Script, java.lang.Object)"><B>execWithDomain(Context, Scriptable, Script, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD><B>Deprecated.</B>&nbsp;<I>The application should not override this method and instead
+ override
+ <A HREF="./org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>SecurityController.callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)</CODE></A>.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#exit()"><B>exit()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Exit a block of code requiring a Context.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#exit()"><B>exit()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A> instead.</I>
+</DL>
+<HR>
+<A NAME="_F_"><!-- --></A><H2>
+<B>F</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE"><B>FEATURE_DYNAMIC_SCOPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if dynamic scope should be used for name access.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_E4X"><B>FEATURE_E4X</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if support for E4X(ECMAScript for XML) extension is available.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_ENHANCED_JAVA_ACCESS"><B>FEATURE_ENHANCED_JAVA_ACCESS</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Enables enhanced access to Java.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_LOCATION_INFORMATION_IN_ERROR"><B>FEATURE_LOCATION_INFORMATION_IN_ERROR</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>When the feature is on Rhino will add a "fileName" and "lineNumber"
+ properties to Error objects automatically.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME"><B>FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if member expression as function name extension is available.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_NON_ECMA_GET_YEAR"><B>FEATURE_NON_ECMA_GET_YEAR</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Controls behaviour of <tt>Date.prototype.getYear()</tt>.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPERTIES"><B>FEATURE_PARENT_PROTO_PROPERTIES</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if properties <tt>__proto__</tt> and <tt>__parent__</tt>
+ are treated specially.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPRTIES"><B>FEATURE_PARENT_PROTO_PROPRTIES</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I>In previous releases, this name was given to
+ FEATURE_PARENT_PROTO_PROPERTIES.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER"><B>FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if reserved keywords are treated as identifiers.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_STRICT_EVAL"><B>FEATURE_STRICT_EVAL</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if strict eval mode is enabled.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_STRICT_MODE"><B>FEATURE_STRICT_MODE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Controls whether JS 1.5 'strict mode' is enabled.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_STRICT_VARS"><B>FEATURE_STRICT_VARS</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if strict variable mode is enabled.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_TO_STRING_AS_SOURCE"><B>FEATURE_TO_STRING_AS_SOURCE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Control if <tt>toString()</tt> should returns the same result
+ as <tt>toSource()</tt> when applied to objects and arrays.
+<DT><A HREF="./org/mozilla/javascript/Context.html#FEATURE_WARNING_AS_ERROR"><B>FEATURE_WARNING_AS_ERROR</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Controls whether a warning should be treated as an error.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#findPrototypeId(java.lang.String)"><B>findPrototypeId(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>Function</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This is interface that all functions in JavaScript must implement.<DT><A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>FunctionObject</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>&nbsp;<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#FunctionObject(java.lang.String, java.lang.reflect.Member, org.mozilla.javascript.Scriptable)"><B>FunctionObject(String, Member, Scriptable)</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Create a JavaScript function object from a Java method.
+</DL>
+<HR>
+<A NAME="_G_"><!-- --></A><H2>
+<B>G</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>GeneratedClassLoader</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Interface to define classes from generated byte code.<DT><A HREF="./org/mozilla/javascript/Context.html#generateObserverCount"><B>generateObserverCount</B></A> -
+Variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#get(org.mozilla.javascript.Scriptable)"><B>get(Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Search for ClassCache object in the given scope.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><B>get(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><B>get(String, Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get a named property from the object.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><B>get(int, Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get a property from the object selected by an integral index.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><B>get(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns the value of the named property or NOT_FOUND.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#get(int, org.mozilla.javascript.Scriptable)"><B>get(int, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns the value of the indexed property or NOT_FOUND.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAllIds()"><B>getAllIds()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns an array of ids for the properties of the object.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getApplicationClassLoader()"><B>getApplicationClassLoader()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#getApplicationClassLoader()"><B>getApplicationClassLoader()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Get ClassLoader to use when searching for Java classes.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#getArity()"><B>getArity()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Return the value defined by the method used to construct the object
+ (number of parameters of the method, or 1 if the method is a "varargs"
+ form).
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)"><B>getAssociatedValue(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get arbitrary application-specific value associated with this object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)"><B>getAttributes(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>ScriptableObject.getAttributes(String name)</CODE></A>. The engine always
+ ignored the start argument.</I>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(int, org.mozilla.javascript.Scriptable)"><B>getAttributes(int, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(int)"><CODE>ScriptableObject.getAttributes(int index)</CODE></A>. The engine always
+ ignored the start argument.</I>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><B>getAttributes(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the attributes of a named property.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getAttributes(int)"><B>getAttributes(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the attributes of an indexed property.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#getClassName()"><B>getClassName()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#getClassName()"><B>getClassName()</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get the name of the set of objects implemented by this Java class.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getClassName()"><B>getClassName()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Return the name of the class.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getClassPrototype(org.mozilla.javascript.Scriptable, java.lang.String)"><B>getClassPrototype(Scriptable, String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the prototype for the named class.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getColumnNumber()"><B>getColumnNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#getColumnNumber()"><B>getColumnNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#getCompilerEnv()"><B>getCompilerEnv()</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Get the compiler environment the compiler uses.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getCurrentContext()"><B>getCurrentContext()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the current Context.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getDebuggableView(org.mozilla.javascript.Script)"><B>getDebuggableView(Script)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Return DebuggableScript instance if any associated with the script.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getDebugger()"><B>getDebugger()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Return the current debugger.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getDebuggerContextData()"><B>getDebuggerContextData()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Return the debugger context data associated with current context.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#getDefaultValue(java.lang.Class)"><B>getDefaultValue(Class)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get the default value of the object with a given hint.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getDefaultValue(java.lang.Class)"><B>getDefaultValue(Class)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Implements the [[DefaultValue]] internal method.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getDefaultValue(org.mozilla.javascript.Scriptable, java.lang.Class)"><B>getDefaultValue(Scriptable, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#getDynamicSecurityDomain(java.lang.Object)"><B>getDynamicSecurityDomain(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Get dynamic security domain that allows an action only if it is allowed
+ by the current Java stack and <i>securityDomain</i>.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getE4xImplementationFactory()"><B>getE4xImplementationFactory()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Returns an object which specifies an E4X implementation to use within
+ this <code>Context</code>.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#getE4xImplementationFactory()"><B>getE4xImplementationFactory()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Provides a default
+ <CODE>XMLLib.Factory</CODE>
+ to be used by the <code>Context</code> instances produced by this
+ factory.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getElements(org.mozilla.javascript.Scriptable)"><B>getElements(Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the elements of a JavaScript array.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getErrorMessage()"><B>getErrorMessage()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD>Gets the message corresponding to the error.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getErrorObject()"><B>getErrorObject()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Always returns <b>null</b>.</I>
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#getErrorReporter()"><B>getErrorReporter()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#getErrorReporter()"><B>getErrorReporter()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the current error reporter.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getFactory()"><B>getFactory()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Return <A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><CODE>ContextFactory</CODE></A> instance used to create this Context.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getFunction(int)"><B>getFunction(int)</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getFunctionCount()"><B>getFunctionCount()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getFunctionName()"><B>getFunctionName()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get name of the function described by this script.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#getFunctionName()"><B>getFunctionName()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getFunctionPrototype(org.mozilla.javascript.Scriptable)"><B>getFunctionPrototype(Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the Function.prototype property.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getGetterOrSetter(java.lang.String, int, boolean)"><B>getGetterOrSetter(String, int, boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the getter or setter for a given property.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#getGlobal()"><B>getGlobal()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Get global ContextFactory.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#getIds()"><B>getIds()</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get an array of property ids.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getIds()"><B>getIds()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns an array of ids for the properties of the object.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getImplementationVersion()"><B>getImplementationVersion()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the implementation version.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getInstructionObserverThreshold()"><B>getInstructionObserverThreshold()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#getLanguageVersion()"><B>getLanguageVersion()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#getLanguageVersion()"><B>getLanguageVersion()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the current language version.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#getLength()"><B>getLength()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Return the same value as <A HREF="./org/mozilla/javascript/FunctionObject.html#getArity()"><CODE>FunctionObject.getArity()</CODE></A>.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getLineNumber()"><B>getLineNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#getLineNumber()"><B>getLineNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#getLineNumber()"><B>getLineNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getLineNumbers()"><B>getLineNumbers()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get array containing the line numbers that
+ that can be passed to <code>DebugFrame.onLineChange()<code>.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getLineSource()"><B>getLineSource()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#getLineSource()"><B>getLineSource()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/Context.html#getLocale()"><B>getLocale()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the current locale.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#getMainMethodClass()"><B>getMainMethodClass()</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Get the name of the class for main method implementation.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getMaximumInterpreterStackDepth()"><B>getMaximumInterpreterStackDepth()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Returns the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#getMessage()"><B>getMessage()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#getMethodOrConstructor()"><B>getMethodOrConstructor()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>Get Java method or constructor this function represent.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getName()"><B>getName()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD>Gets the name of the error.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getObjectPrototype(org.mozilla.javascript.Scriptable)"><B>getObjectPrototype(Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the Object.prototype property.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#getOptimizationLevel()"><B>getOptimizationLevel()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#getOptimizationLevel()"><B>getOptimizationLevel()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the current optimization level.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getParamAndVarCount()"><B>getParamAndVarCount()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get number of declared parameters and local variables.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getParamCount()"><B>getParamCount()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get number of declared parameters in the function.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getParamOrVarName(int)"><B>getParamOrVarName(int)</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get name of a declared parameter or local variable.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getParent()"><B>getParent()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#getParentScope()"><B>getParentScope()</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get the parent scope of the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getParentScope()"><B>getParentScope()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns the parent (enclosing) scope of the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><B>getProperty(Scriptable, String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Gets a named property from an object or any object in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)"><B>getProperty(Scriptable, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Gets an indexed property from an object or any object in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getPropertyIds(org.mozilla.javascript.Scriptable)"><B>getPropertyIds(Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns an array of all ids from an object and its prototypes.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#getPrototype()"><B>getPrototype()</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Get the prototype of the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getPrototype()"><B>getPrototype()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns the prototype of the object.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#getScriptStackTrace()"><B>getScriptStackTrace()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Get a string representing the script stack of this exception.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)"><B>getScriptStackTrace(FilenameFilter)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Get a string representing the script stack of this exception.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#getSourceName()"><B>getSourceName()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Get the name of the source (usually filename or URL)
+ of the script.
+<DT><A HREF="./org/mozilla/javascript/EcmaError.html#getSourceName()"><B>getSourceName()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/EvaluatorException.html#getSourceName()"><B>getSourceName()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#getSourceName()"><B>getSourceName()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#getStaticSecurityDomainClass()"><B>getStaticSecurityDomainClass()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#getStaticSecurityDomainClassInternal()"><B>getStaticSecurityDomainClassInternal()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetExtends()"><B>getTargetExtends()</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Get the class that the generated target will extend.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetImplements()"><B>getTargetImplements()</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Get the interfaces that the generated target will implement.
+<DT><A HREF="./org/mozilla/javascript/Context.html#getThreadLocal(java.lang.Object)"><B>getThreadLocal(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get a value corresponding to a key.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)"><B>getTopLevelScope(Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get the global scope.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#getTopScopeValue(org.mozilla.javascript.Scriptable, java.lang.Object)"><B>getTopScopeValue(Scriptable, Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Get arbitrary application-specific value associated with the top scope
+ of the given scope.
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)"><B>getTypeTag(Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#getUndefinedValue()"><B>getUndefinedValue()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Get the singleton object that represents the JavaScript Undefined value.
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#getValue()"><B>getValue()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#getWrapFactory()"><B>getWrapFactory()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Return the current WrapFactory, or null if none is defined.
+<DT><A HREF="./org/mozilla/javascript/WrappedException.html#getWrappedException()"><B>getWrappedException()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A>
+<DD>Get the wrapped exception.
+</DL>
+<HR>
+<A NAME="_H_"><!-- --></A><H2>
+<B>H</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><B>has(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><B>has(String, Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Indicates whether or not a named property is defined in an object.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)"><B>has(int, Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Indicates whether or not an indexed property is defined in an object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><B>has(String, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns true if the named property is defined.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#has(int, org.mozilla.javascript.Scriptable)"><B>has(int, Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns true if the property index is defined.
+<DT><A HREF="./org/mozilla/javascript/Context.html#hasCompileFunctionsWithDynamicScope()"><B>hasCompileFunctionsWithDynamicScope()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#hasExcludedName(java.lang.String)"><B>hasExcludedName(String)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>Returns true if the name is excluded from serialization.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#hasExplicitGlobal()"><B>hasExplicitGlobal()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Check if global factory was set.
+<DT><A HREF="./org/mozilla/javascript/Context.html#hasFeature(int)"><B>hasFeature(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Controls certain aspects of script semantics.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#hasFeature(org.mozilla.javascript.Context, int)"><B>hasFeature(Context, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Implementation of <A HREF="./org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>Context.hasFeature(int featureIndex)</CODE></A>.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#hasGlobal()"><B>hasGlobal()</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Check if global <A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><CODE>SecurityController</CODE></A> was already installed.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#hasInstance(org.mozilla.javascript.Scriptable)"><B>hasInstance(Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>The instanceof operator.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#hasInstance(org.mozilla.javascript.Scriptable)"><B>hasInstance(Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Implements the instanceof operator.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><B>hasProperty(Scriptable, String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns whether a named property is defined in an object or any object
+ in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, int)"><B>hasProperty(Scriptable, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns whether an indexed property is defined in an object or any object
+ in its prototype chain.
+</DL>
+<HR>
+<A NAME="_I_"><!-- --></A><H2>
+<B>I</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>ImporterTopLevel</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Class ImporterTopLevel
+
+ This class defines a ScriptableObject that can be instantiated
+ as a top-level ("global") object to provide functionality similar
+ to Java's "import" statement.<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel()"><B>ImporterTopLevel()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel(org.mozilla.javascript.Context)"><B>ImporterTopLevel(Context)</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel(org.mozilla.javascript.Context, boolean)"><B>ImporterTopLevel(Context, boolean)</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#importPackage(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[], org.mozilla.javascript.Function)"><B>importPackage(Context, Scriptable, Object[], Function)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Kept only for compatibility.</I>
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#init(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, boolean)"><B>init(Context, Scriptable, boolean)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#initApplicationClassLoader(java.lang.ClassLoader)"><B>initApplicationClassLoader(ClassLoader)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Set explicit class loader to use when searching for Java classes.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#initColumnNumber(int)"><B>initColumnNumber(int)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Initialize the column number of the script statement causing the error.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#initFromContext(org.mozilla.javascript.Context)"><B>initFromContext(Context)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)"><B>initGlobal(ContextFactory)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Set global ContextFactory.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html#initGlobal(org.mozilla.javascript.SecurityController)"><B>initGlobal(SecurityController)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>Initialize global controller that will be used for all
+ security-related operations.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#initLineNumber(int)"><B>initLineNumber(int)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Initialize the line number of the script statement causing the error.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)"><B>initLineSource(String)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Initialize the text of the source line containing the error.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#initPrototypeId(int)"><B>initPrototypeId(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)"><B>initSourceName(String)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Initialize the uri of the script source containing the error.
+<DT><A HREF="./org/mozilla/javascript/Context.html#initStandardObjects()"><B>initStandardObjects()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Initialize the standard objects.
+<DT><A HREF="./org/mozilla/javascript/Context.html#initStandardObjects(org.mozilla.javascript.ScriptableObject)"><B>initStandardObjects(ScriptableObject)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Initialize the standard objects.
+<DT><A HREF="./org/mozilla/javascript/Context.html#initStandardObjects(org.mozilla.javascript.ScriptableObject, boolean)"><B>initStandardObjects(ScriptableObject, boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Initialize the standard objects.
+<DT><A HREF="./org/mozilla/javascript/ImporterTopLevel.html#initStandardObjects(org.mozilla.javascript.Context, boolean)"><B>initStandardObjects(Context, boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isActivationNeeded(java.lang.String)"><B>isActivationNeeded(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Check whether the name is in the list of names of objects
+ forcing the creation of activation objects.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isAllowMemberExprAsFunctionName()"><B>isAllowMemberExprAsFunctionName()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#isCachingEnabled()"><B>isCachingEnabled()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Check if generated Java classes and Java reflection information
+ is cached.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#isConst(java.lang.String)"><B>isConst(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns true if the named property is defined as a const on this object.
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#isFunction()"><B>isFunction()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Returns true if this is a function, false if it is a script.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isGenerateDebugInfo()"><B>isGenerateDebugInfo()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#isGeneratedScript()"><B>isGeneratedScript()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>Returns true if this script or function were runtime-generated
+ from JavaScript using <tt>eval</tt> function or <tt>Function</tt>
+ or <tt>Script</tt> constructors.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isGenerateObserverCount()"><B>isGenerateObserverCount()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isGeneratingDebug()"><B>isGeneratingDebug()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Tell whether debug information is being generated.
+<DT><A HREF="./org/mozilla/javascript/Context.html#isGeneratingDebugChanged()"><B>isGeneratingDebugChanged()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isGeneratingSource()"><B>isGeneratingSource()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isGeneratingSource()"><B>isGeneratingSource()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Tell whether source information is being generated.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#isGetterOrSetter(java.lang.String, int, boolean)"><B>isGetterOrSetter(String, int, boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Returns whether a property is a getter or a setter
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#isInvokerOptimizationEnabled()"><B>isInvokerOptimizationEnabled()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD><B>Deprecated.</B>&nbsp;<I>The method always returns false.</I>
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#isJavaPrimitiveWrap()"><B>isJavaPrimitiveWrap()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>Return <code>false</code> if result of Java method, which is instance of
+ <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ <code>Character</code>, should be used directly as JavaScript primitive
+ type.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isReservedKeywordAsIdentifier()"><B>isReservedKeywordAsIdentifier()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isSealed()"><B>isSealed()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Checks if this is a sealed Context.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#isSealed()"><B>isSealed()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Checks if this is a sealed ContextFactory.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#isSealed()"><B>isSealed()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Return true if this object is sealed.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isStrictMode()"><B>isStrictMode()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/debug/DebuggableScript.html#isTopLevel()"><B>isTopLevel()</B></A> -
+Method in interface org.mozilla.javascript.debug.<A HREF="./org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isUseDynamicScope()"><B>isUseDynamicScope()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isValidLanguageVersion(int)"><B>isValidLanguageVersion(int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#isValidOptimizationLevel(int)"><B>isValidOptimizationLevel(int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#isXmlAvailable()"><B>isXmlAvailable()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_J_"><!-- --></A><H2>
+<B>J</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_BOOLEAN_TYPE"><B>JAVA_BOOLEAN_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_DOUBLE_TYPE"><B>JAVA_DOUBLE_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_INT_TYPE"><B>JAVA_INT_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_OBJECT_TYPE"><B>JAVA_OBJECT_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_SCRIPTABLE_TYPE"><B>JAVA_SCRIPTABLE_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_STRING_TYPE"><B>JAVA_STRING_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/FunctionObject.html#JAVA_UNSUPPORTED_TYPE"><B>JAVA_UNSUPPORTED_TYPE</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>JavaScriptException</B></A> - Exception in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Java reflection of JavaScript exceptions.<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#JavaScriptException(java.lang.Object)"><B>JavaScriptException(Object)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)"><CODE>WrappedException.WrappedException(Throwable)</CODE></A> to report
+ exceptions in Java code.</I>
+<DT><A HREF="./org/mozilla/javascript/JavaScriptException.html#JavaScriptException(java.lang.Object, java.lang.String, int)"><B>JavaScriptException(Object, String, int)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A>
+<DD>Create a JavaScript exception wrapping the given JavaScript value
+<DT><A HREF="./org/mozilla/javascript/Context.html#javaToJS(java.lang.Object, org.mozilla.javascript.Scriptable)"><B>javaToJS(Object, Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convenient method to convert java value to its closest representation
+ in JavaScript.
+<DT><A HREF="./org/mozilla/javascript/Context.html#jsToJava(java.lang.Object, java.lang.Class)"><B>jsToJava(Object, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convert a JavaScript value into the desired type.
+</DL>
+<HR>
+<A NAME="_L_"><!-- --></A><H2>
+<B>L</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#languageVersionProperty"><B>languageVersionProperty</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#lineNumber()"><B>lineNumber()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Returns the line number of the statement causing the error,
+ or zero if not available.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#lineSource()"><B>lineSource()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>The source text of the line causing the error, or null if unknown.
+<DT><A HREF="./org/mozilla/javascript/GeneratedClassLoader.html#linkClass(java.lang.Class)"><B>linkClass(Class)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A>
+<DD>Link the given class.
+</DL>
+<HR>
+<A NAME="_M_"><!-- --></A><H2>
+<B>M</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#makeAuxiliaryClassName(java.lang.String, java.lang.String)"><B>makeAuxiliaryClassName(String, String)</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Build class name for a auxiliary class generated by compiler.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#makeContext()"><B>makeContext()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Create new <A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance to be associated with the current
+ thread.
+</DL>
+<HR>
+<A NAME="_N_"><!-- --></A><H2>
+<B>N</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#newArray(org.mozilla.javascript.Scriptable, int)"><B>newArray(Scriptable, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Create an array with a specified initial length.
+<DT><A HREF="./org/mozilla/javascript/Context.html#newArray(org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>newArray(Scriptable, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Create an array with a set of initial elements.
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#newClassSerialNumber()"><B>newClassSerialNumber()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Internal engine method to return serial number for generated classes
+ to ensure name uniqueness.
+<DT><A HREF="./org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable)"><B>newObject(Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Create a new JavaScript object.
+<DT><A HREF="./org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable, java.lang.String)"><B>newObject(Scriptable, String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Create a new JavaScript object by executing the named constructor.
+<DT><A HREF="./org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><B>newObject(Scriptable, String, Object[])</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Creates a new JavaScript object by executing the named constructor.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#NOT_FOUND"><B>NOT_FOUND</B></A> -
+Static variable in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Value returned from <code>get</code> if the property is not
+ found.
+</DL>
+<HR>
+<A NAME="_O_"><!-- --></A><H2>
+<B>O</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#observeInstructionCount(int)"><B>observeInstructionCount(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Allow application to monitor counter of executed script instructions
+ in Context subclasses.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#observeInstructionCount(org.mozilla.javascript.Context, int)"><B>observeInstructionCount(Context, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Implementation of
+ <A HREF="./org/mozilla/javascript/Context.html#observeInstructionCount(int)"><CODE>Context.observeInstructionCount(int instructionCount)</CODE></A>.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#onContextCreated(org.mozilla.javascript.Context)"><B>onContextCreated(Context)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#onContextReleased(org.mozilla.javascript.Context)"><B>onContextReleased(Context)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/package-summary.html"><B>org.mozilla.javascript</B></A> - package org.mozilla.javascript<DD>&nbsp;<DT><A HREF="./org/mozilla/javascript/debug/package-summary.html"><B>org.mozilla.javascript.debug</B></A> - package org.mozilla.javascript.debug<DD>&nbsp;<DT><A HREF="./org/mozilla/javascript/optimizer/package-summary.html"><B>org.mozilla.javascript.optimizer</B></A> - package org.mozilla.javascript.optimizer<DD>&nbsp;<DT><A HREF="./org/mozilla/javascript/serialize/package-summary.html"><B>org.mozilla.javascript.serialize</B></A> - package org.mozilla.javascript.serialize<DD>&nbsp;</DL>
+<HR>
+<A NAME="_P_"><!-- --></A><H2>
+<B>P</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#PERMANENT"><B>PERMANENT</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Property attribute indicating property cannot be deleted.
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)"><B>printStackTrace(PrintWriter)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)"><B>printStackTrace(PrintStream)</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>put(String, Scriptable, Object)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Sets a named property in this object.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>put(int, Scriptable, Object)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Sets an indexed property in this object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>put(String, Scriptable, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Sets the value of the named property, creating it if need be.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>put(int, Scriptable, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Sets the value of the indexed property, creating it if need be.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#putConst(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>putConst(String, Scriptable, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Sets the value of the named const property, creating it if need be.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#putConstProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><B>putConstProperty(Scriptable, String, Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Puts a named property in an object or in an object in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><B>putProperty(Scriptable, String, Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Puts a named property in an object or in an object in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)"><B>putProperty(Scriptable, int, Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Puts an indexed property in an object or in an object in its prototype chain.
+<DT><A HREF="./org/mozilla/javascript/Context.html#putThreadLocal(java.lang.Object, java.lang.Object)"><B>putThreadLocal(Object, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Put a value that can later be retrieved using a given key.
+</DL>
+<HR>
+<A NAME="_R_"><!-- --></A><H2>
+<B>R</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#READONLY"><B>READONLY</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Property attribute indicating assignment to this property is ignored.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#redefineProperty(org.mozilla.javascript.Scriptable, java.lang.String, boolean)"><B>redefineProperty(Scriptable, String, boolean)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>If hasProperty(obj, name) would return true, then if the property that
+ was found is compatible with the new property, this method just returns.
+<DT><A HREF="./org/mozilla/javascript/RefCallable.html#refCall(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])"><B>refCall(Context, Scriptable, Object[])</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript">RefCallable</A>
+<DD>Perform function call in reference context.
+<DT><A HREF="./org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>RefCallable</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Object that can allows assignments to the result of function calls.<DT><A HREF="./org/mozilla/javascript/Context.html#removeActivationName(java.lang.String)"><B>removeActivationName(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Remove a name from the list of names forcing the creation of real
+ activation objects for functions.
+<DT><A HREF="./org/mozilla/javascript/Context.html#removeContextListener(org.mozilla.javascript.ContextListener)"><B>removeContextListener(ContextListener)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#removeExcludedName(java.lang.String)"><B>removeExcludedName(String)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>Removes a name from the list of names to exclude.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#removeListener(org.mozilla.javascript.ContextFactory.Listener)"><B>removeListener(ContextFactory.Listener)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#removePropertyChangeListener(java.beans.PropertyChangeListener)"><B>removePropertyChangeListener(PropertyChangeListener)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Remove an object from the list of objects registered to receive
+ notification of changes to a bounded property
+<DT><A HREF="./org/mozilla/javascript/Context.html#removeThreadLocal(java.lang.Object)"><B>removeThreadLocal(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Remove values from thread-local storage.
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#replaceObject(java.lang.Object)"><B>replaceObject(Object)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportError(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>reportError(String, String, int, String, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report an error using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportError(java.lang.String)"><B>reportError(String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report an error using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportRuntimeError(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>reportRuntimeError(String, String, int, String, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report a runtime error using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportRuntimeError(java.lang.String)"><B>reportRuntimeError(String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report a runtime error using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportWarning(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>reportWarning(String, String, int, String, int)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report a warning using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportWarning(java.lang.String)"><B>reportWarning(String)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Report a warning using the error reporter for the current thread.
+<DT><A HREF="./org/mozilla/javascript/Context.html#reportWarning(java.lang.String, java.lang.Throwable)"><B>reportWarning(String, Throwable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#reportWarningAsError()"><B>reportWarningAsError()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html#resolveClass(java.io.ObjectStreamClass)"><B>resolveClass(ObjectStreamClass)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html#resolveObject(java.lang.Object)"><B>resolveObject(Object)</B></A> -
+Method in class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableInputStream</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>RhinoException</B></A> - Exception in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>The class of exceptions thrown by the JavaScript engine.<DT><A HREF="./org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><B>run(Context)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A>
+<DD>Execute action using the supplied Context instance.
+<DT><A HREF="./org/mozilla/javascript/ErrorReporter.html#runtimeError(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>runtimeError(String, String, int, String, int)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>
+<DD>Creates an EvaluatorException that may be thrown.
+</DL>
+<HR>
+<A NAME="_S_"><!-- --></A><H2>
+<B>S</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>Script</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>All compiled scripts implement this interface.<DT><A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>Scriptable</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This is interface that all objects in JavaScript must implement.<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableInputStream</B></A> - Class in <A HREF="./org/mozilla/javascript/serialize/package-summary.html">org.mozilla.javascript.serialize</A><DD>Class ScriptableInputStream is used to read in a JavaScript
+ object or function previously serialized with a ScriptableOutputStream.<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html#ScriptableInputStream(java.io.InputStream, org.mozilla.javascript.Scriptable)"><B>ScriptableInputStream(InputStream, Scriptable)</B></A> -
+Constructor for class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableInputStream</A>
+<DD>Create a ScriptableInputStream.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>ScriptableObject</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This is the default implementation of the Scriptable interface.<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#ScriptableObject()"><B>ScriptableObject()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#ScriptableObject(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)"><B>ScriptableObject(Scriptable, Scriptable)</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableOutputStream</B></A> - Class in <A HREF="./org/mozilla/javascript/serialize/package-summary.html">org.mozilla.javascript.serialize</A><DD>Class ScriptableOutputStream is an ObjectOutputStream used
+ to serialize JavaScript objects and functions.<DT><A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html#ScriptableOutputStream(java.io.OutputStream, org.mozilla.javascript.Scriptable)"><B>ScriptableOutputStream(OutputStream, Scriptable)</B></A> -
+Constructor for class org.mozilla.javascript.serialize.<A HREF="./org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A>
+<DD>ScriptableOutputStream constructor.
+<DT><A HREF="./org/mozilla/javascript/Context.html#seal(java.lang.Object)"><B>seal(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Seal this Context object so any attempt to modify any of its properties
+ including calling <A HREF="./org/mozilla/javascript/Context.html#enter()"><CODE>Context.enter()</CODE></A> and <A HREF="./org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A> methods will
+ throw an exception.
+<DT><A HREF="./org/mozilla/javascript/ContextFactory.html#seal()"><B>seal()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>
+<DD>Seal this ContextFactory so any attempt to modify it like to add or
+ remove its listeners will throw an exception.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#sealObject()"><B>sealObject()</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Seal this object.
+<DT><A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>SecurityController</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This class describes the support needed to implement security.<DT><A HREF="./org/mozilla/javascript/SecurityController.html#SecurityController()"><B>SecurityController()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setAllowMemberExprAsFunctionName(boolean)"><B>setAllowMemberExprAsFunctionName(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setApplicationClassLoader(java.lang.ClassLoader)"><B>setApplicationClassLoader(ClassLoader)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)"><B>setAttributes(String, Scriptable, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>ScriptableObject.setAttributes(String name, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(int, org.mozilla.javascript.Scriptable, int)"><B>setAttributes(int, Scriptable, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)"><CODE>ScriptableObject.setAttributes(int index, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><B>setAttributes(String, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Set the attributes of a named property.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)"><B>setAttributes(int, int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Set the attributes of an indexed property.
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#setCachingEnabled(boolean)"><B>setCachingEnabled(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD>Set whether to cache some values.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setCachingEnabled(boolean)"><B>setCachingEnabled(boolean)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setClassShutter(org.mozilla.javascript.ClassShutter)"><B>setClassShutter(ClassShutter)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the LiveConnect access filter for this context.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setCompileFunctionsWithDynamicScope(boolean)"><B>setCompileFunctionsWithDynamicScope(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setDebugger(org.mozilla.javascript.debug.Debugger, java.lang.Object)"><B>setDebugger(Debugger, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the associated debugger.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setErrorReporter(org.mozilla.javascript.ErrorReporter)"><B>setErrorReporter(ErrorReporter)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setErrorReporter(org.mozilla.javascript.ErrorReporter)"><B>setErrorReporter(ErrorReporter)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Change the current error reporter.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setGenerateDebugInfo(boolean)"><B>setGenerateDebugInfo(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setGenerateObserverCount(boolean)"><B>setGenerateObserverCount(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>Turn on or off generation of code with callbacks to
+ track the count of executed instructions.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setGenerateObserverCount(boolean)"><B>setGenerateObserverCount(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Turn on or off generation of code with callbacks to
+ track the count of executed instructions.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setGeneratingDebug(boolean)"><B>setGeneratingDebug(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Specify whether or not debug information should be generated.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setGeneratingSource(boolean)"><B>setGeneratingSource(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>Specify whether or not source information should be generated.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setGeneratingSource(boolean)"><B>setGeneratingSource(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Specify whether or not source information should be generated.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setGetterOrSetter(java.lang.String, int, org.mozilla.javascript.Callable, boolean)"><B>setGetterOrSetter(String, int, Callable, boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>XXX: write docs.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setInstructionObserverThreshold(int)"><B>setInstructionObserverThreshold(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.
+<DT><A HREF="./org/mozilla/javascript/ClassCache.html#setInvokerOptimizationEnabled(boolean)"><B>setInvokerOptimizationEnabled(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A>
+<DD><B>Deprecated.</B>&nbsp;<I>The method does nothing.
+ Invoker optimization is no longer used by Rhino.
+ On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
+ like increased memory usage or longer initialization time overweight
+ small speed increase that can be gained using generated proxy class
+ to replace reflection.</I>
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#setJavaPrimitiveWrap(boolean)"><B>setJavaPrimitiveWrap(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setLanguageVersion(int)"><B>setLanguageVersion(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setLanguageVersion(int)"><B>setLanguageVersion(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the language version.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setLocale(java.util.Locale)"><B>setLocale(Locale)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the current locale.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#setMainMethodClass(java.lang.String)"><B>setMainMethodClass(String)</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Set the class name to use for main method implementation.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setMaximumInterpreterStackDepth(int)"><B>setMaximumInterpreterStackDepth(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Sets the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setOptimizationLevel(int)"><B>setOptimizationLevel(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setOptimizationLevel(int)"><B>setOptimizationLevel(int)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the current optimization level.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)"><B>setParentScope(Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Set the parent scope of the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setParentScope(org.mozilla.javascript.Scriptable)"><B>setParentScope(Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Sets the parent (enclosing) scope of the object.
+<DT><A HREF="./org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)"><B>setPrototype(Scriptable)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>
+<DD>Set the prototype of the object.
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#setPrototype(org.mozilla.javascript.Scriptable)"><B>setPrototype(Scriptable)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Sets the prototype of the object.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setReservedKeywordAsIdentifier(boolean)"><B>setReservedKeywordAsIdentifier(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#setSecurityController(org.mozilla.javascript.SecurityController)"><B>setSecurityController(SecurityController)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set the security controller for this context.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#setTargetExtends(java.lang.Class)"><B>setTargetExtends(Class)</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Set the class that the generated target will extend.
+<DT><A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html#setTargetImplements(java.lang.Class[])"><B>setTargetImplements(Class[])</B></A> -
+Method in class org.mozilla.javascript.optimizer.<A HREF="./org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A>
+<DD>Set the interfaces that the generated target will implement.
+<DT><A HREF="./org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)"><B>setWrapFactory(WrapFactory)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Set a WrapFactory for this Context.
+<DT><A HREF="./org/mozilla/javascript/CompilerEnvirons.html#setXmlAvailable(boolean)"><B>setXmlAvailable(boolean)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/RhinoException.html#sourceName()"><B>sourceName()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A>
+<DD>Get the uri of the script source containing the error, or null
+ if that information is not available.
+<DT><A HREF="./org/mozilla/javascript/Context.html#stringIsCompilableUnit(java.lang.String)"><B>stringIsCompilableUnit(String)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Check whether a string is ready to be compiled.
+<DT><A HREF="./org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>Synchronizer</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>This class provides support for implementing Java-style synchronized
+ methods in Javascript.<DT><A HREF="./org/mozilla/javascript/Synchronizer.html#Synchronizer(org.mozilla.javascript.Scriptable)"><B>Synchronizer(Scriptable)</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A>
+<DD>Create a new synchronized function from an existing one.
+</DL>
+<HR>
+<A NAME="_T_"><!-- --></A><H2>
+<B>T</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#throwAsScriptRuntimeEx(java.lang.Throwable)"><B>throwAsScriptRuntimeEx(Throwable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Rethrow the exception wrapping it as the script runtime exception.
+<DT><A HREF="./org/mozilla/javascript/Context.html#toBoolean(java.lang.Object)"><B>toBoolean(Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convert the value to a JavaScript boolean value.
+<DT><A HREF="./org/mozilla/javascript/Context.html#toNumber(java.lang.Object)"><B>toNumber(Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convert the value to a JavaScript Number value.
+<DT><A HREF="./org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><B>toObject(Object, Scriptable)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convert the value to an JavaScript object value.
+<DT><A HREF="./org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable, java.lang.Class)"><B>toObject(Object, Scriptable, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Context.html#toString(java.lang.Object)"><B>toString(Object)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Convert the value to a JavaScript String value.
+<DT><A HREF="./org/mozilla/javascript/Context.html#toType(java.lang.Object, java.lang.Class)"><B>toType(Object, Class)</B></A> -
+Static method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD><B>Deprecated.</B>&nbsp;<I></I>&nbsp;
+</DL>
+<HR>
+<A NAME="_U_"><!-- --></A><H2>
+<B>U</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ScriptableObject.html#UNINITIALIZED_CONST"><B>UNINITIALIZED_CONST</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>
+<DD>Property attribute indicating that this is a const property that has not
+ been assigned yet.
+<DT><A HREF="./org/mozilla/javascript/Context.html#unseal(java.lang.Object)"><B>unseal(Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>Unseal previously sealed Context object.
+<DT><A HREF="./org/mozilla/javascript/WrappedException.html#unwrap()"><B>unwrap()</B></A> -
+Method in exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="./org/mozilla/javascript/WrappedException.html#getWrappedException()"><CODE>WrappedException.getWrappedException()</CODE></A> instead.</I>
+<DT><A HREF="./org/mozilla/javascript/Wrapper.html#unwrap()"><B>unwrap()</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript">Wrapper</A>
+<DD>Unwrap the object by returning the wrapped value.
+</DL>
+<HR>
+<A NAME="_V_"><!-- --></A><H2>
+<B>V</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_0"><B>VERSION_1_0</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.0
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_1"><B>VERSION_1_1</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.1
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_2"><B>VERSION_1_2</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.2
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_3"><B>VERSION_1_3</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.3
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_4"><B>VERSION_1_4</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.4
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_5"><B>VERSION_1_5</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.5
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_6"><B>VERSION_1_6</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.6
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_1_7"><B>VERSION_1_7</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>JavaScript 1.7
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_DEFAULT"><B>VERSION_DEFAULT</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>The default version.
+<DT><A HREF="./org/mozilla/javascript/Context.html#VERSION_UNKNOWN"><B>VERSION_UNKNOWN</B></A> -
+Static variable in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>
+<DD>The unknown version.
+<DT><A HREF="./org/mozilla/javascript/ClassShutter.html#visibleToScripts(java.lang.String)"><B>visibleToScripts(String)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript">ClassShutter</A>
+<DD>Return true iff the Java class with the given name should be exposed
+ to scripts.
+</DL>
+<HR>
+<A NAME="_W_"><!-- --></A><H2>
+<B>W</B></H2>
+<DL>
+<DT><A HREF="./org/mozilla/javascript/ErrorReporter.html#warning(java.lang.String, java.lang.String, int, java.lang.String, int)"><B>warning(String, String, int, String, int)</B></A> -
+Method in interface org.mozilla.javascript.<A HREF="./org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>
+<DD>Report a warning.
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#wrap(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><B>wrap(Context, Scriptable, Object, Class)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>Wrap the object.
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#wrapAsJavaObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><B>wrapAsJavaObject(Context, Scriptable, Object, Class)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>Wrap Java object as Scriptable instance to allow full access to its
+ methods and fields from JavaScript.
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>WrapFactory</B></A> - Class in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Embeddings that wish to provide their own custom wrappings for Java
+ objects may extend this class and call
+ <A HREF="./org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)"><CODE>Context.setWrapFactory(WrapFactory)</CODE></A>
+ Once an instance of this class or an extension of this class is enabled
+ for a given context (by calling setWrapFactory on that context), Rhino
+ will call the methods of this class whenever it needs to wrap a value
+ resulting from a call to a Java method or an access to a Java field.<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#WrapFactory()"><B>WrapFactory()</B></A> -
+Constructor for class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/WrapFactory.html#wrapNewObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object)"><B>wrapNewObject(Context, Scriptable, Object)</B></A> -
+Method in class org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>
+<DD>Wrap an object newly created by a constructor call.
+<DT><A HREF="./org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>WrappedException</B></A> - Exception in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>A wrapper for runtime exceptions.<DT><A HREF="./org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)"><B>WrappedException(Throwable)</B></A> -
+Constructor for exception org.mozilla.javascript.<A HREF="./org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A>
+<DD>&nbsp;
+<DT><A HREF="./org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><B>Wrapper</B></A> - Interface in <A HREF="./org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A><DD>Objects that can wrap other values for reflection in the JS environment
+ will implement Wrapper.</DL>
+<HR>
+<A HREF="#_A_">A</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_F_">F</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_J_">J</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_P_">P</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <A HREF="#_W_">W</A>
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="./help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="./index.html?index-all.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="index-all.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="./allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="./allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/index.html b/infrastructure/rhino1_7R1/javadoc/index.html
new file mode 100644
index 0000000..fa48043
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/index.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Thu Mar 06 17:19:16 EST 2008-->
+<TITLE>
+Rhino
+</TITLE>
+<SCRIPT type="text/javascript">
+ targetPage = "" + window.location.search;
+ if (targetPage != "" && targetPage != "undefined")
+ targetPage = targetPage.substring(1);
+ function loadFrames() {
+ if (targetPage != "" && targetPage != "undefined")
+ top.classFrame.location = top.targetPage;
+ }
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+</HEAD>
+<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
+<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
+<FRAME src="overview-frame.html" name="packageListFrame" title="All Packages">
+<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
+</FRAMESET>
+<FRAME src="overview-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
+<NOFRAMES>
+<H2>
+Frame Alert</H2>
+
+<P>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<BR>
+Link to<A HREF="overview-summary.html">Non-frame version.</A>
+</NOFRAMES>
+</FRAMESET>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Callable.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Callable.html
new file mode 100644
index 0000000..07c38c5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Callable.html
@@ -0,0 +1,224 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+Callable (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Callable (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Callable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Callable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface Callable</H2>
+<DL>
+<DT><B>All Known Subinterfaces:</B> <DD><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>, <A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript">RefCallable</A></DD>
+</DL>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD>org.mozilla.javascript.BaseFunction, org.mozilla.javascript.Delegator, <A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>, <A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Callable</B></DL>
+</PRE>
+
+<P>
+Generic notion of callable object that can execute some script-related code
+ upon request with specified values for script scope and this objects.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform the call.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+call</H3>
+<PRE>
+java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Perform the call.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope to use to resolve properties.<DD><CODE>thisObj</CODE> - the JavaScript <code>this</code> object<DD><CODE>args</CODE> - the array of arguments
+<DT><B>Returns:</B><DD>the result of the call</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Callable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Callable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassCache.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassCache.html
new file mode 100644
index 0000000..8d8b3ef
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassCache.html
@@ -0,0 +1,445 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+ClassCache (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ClassCache (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ClassCache.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassCache.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class ClassCache</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.ClassCache</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>ClassCache</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Cache of generated classes and data structures to access Java runtime
+ from JavaScript.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>Rhino 1.5 Release 5</DD>
+<DT><B>Author:</B></DT>
+ <DD>Igor Bukanov</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#ClassCache()">ClassCache</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#associate(org.mozilla.javascript.ScriptableObject)">associate</A></B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;topScope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Associate ClassCache object with the given top-level scope.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#clearCaches()">clearCaches</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Empty caches of generated Java classes and Java reflection information.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#get(org.mozilla.javascript.Scriptable)">get</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Search for ClassCache object in the given scope.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#isCachingEnabled()">isCachingEnabled</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check if generated Java classes and Java reflection information
+ is cached.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#isInvokerOptimizationEnabled()">isInvokerOptimizationEnabled</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>The method always returns false.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#newClassSerialNumber()">newClassSerialNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Internal engine method to return serial number for generated classes
+ to ensure name uniqueness.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#setCachingEnabled(boolean)">setCachingEnabled</A></B>(boolean&nbsp;enabled)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set whether to cache some values.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassCache.html#setInvokerOptimizationEnabled(boolean)">setInvokerOptimizationEnabled</A></B>(boolean&nbsp;enabled)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>The method does nothing.
+ Invoker optimization is no longer used by Rhino.
+ On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
+ like increased memory usage or longer initialization time overweight
+ small speed increase that can be gained using generated proxy class
+ to replace reflection.</I></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ClassCache()"><!-- --></A><H3>
+ClassCache</H3>
+<PRE>
+public <B>ClassCache</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="get(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A> <B>get</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Search for ClassCache object in the given scope.
+ The method first calls
+ <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)"><CODE>ScriptableObject.getTopLevelScope(Scriptable scope)</CODE></A>
+ to get the top most scope and then tries to locate associated
+ ClassCache object in the prototype chain of the top scope.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - scope to search for ClassCache object.
+<DT><B>Returns:</B><DD>previously associated ClassCache object or a new instance of
+ ClassCache if no ClassCache object was found.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ClassCache.html#associate(org.mozilla.javascript.ScriptableObject)"><CODE>associate(ScriptableObject topScope)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="associate(org.mozilla.javascript.ScriptableObject)"><!-- --></A><H3>
+associate</H3>
+<PRE>
+public boolean <B>associate</B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;topScope)</PRE>
+<DL>
+<DD>Associate ClassCache object with the given top-level scope.
+ The ClassCache object can only be associated with the given scope once.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>topScope</CODE> - scope to associate this ClassCache object with.
+<DT><B>Returns:</B><DD>true if no previous ClassCache objects were embedded into
+ the scope and this ClassCache were successfully associated
+ or false otherwise.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ClassCache.html#get(org.mozilla.javascript.Scriptable)"><CODE>get(Scriptable scope)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clearCaches()"><!-- --></A><H3>
+clearCaches</H3>
+<PRE>
+public void <B>clearCaches</B>()</PRE>
+<DL>
+<DD>Empty caches of generated Java classes and Java reflection information.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isCachingEnabled()"><!-- --></A><H3>
+isCachingEnabled</H3>
+<PRE>
+public final boolean <B>isCachingEnabled</B>()</PRE>
+<DL>
+<DD>Check if generated Java classes and Java reflection information
+ is cached.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCachingEnabled(boolean)"><!-- --></A><H3>
+setCachingEnabled</H3>
+<PRE>
+public void <B>setCachingEnabled</B>(boolean&nbsp;enabled)</PRE>
+<DL>
+<DD>Set whether to cache some values.
+ <p>
+ By default, the engine will cache the results of
+ <tt>Class.getMethods()</tt> and similar calls.
+ This can speed execution dramatically, but increases the memory
+ footprint. Also, with caching enabled, references may be held to
+ objects past the lifetime of any real usage.
+ <p>
+ If caching is enabled and this method is called with a
+ <code>false</code> argument, the caches will be emptied.
+ <p>
+ Caching is enabled by default.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>enabled</CODE> - if true, caching is enabled<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ClassCache.html#clearCaches()"><CODE>clearCaches()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isInvokerOptimizationEnabled()"><!-- --></A><H3>
+isInvokerOptimizationEnabled</H3>
+<PRE>
+public boolean <B>isInvokerOptimizationEnabled</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>The method always returns false.</I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ClassCache.html#setInvokerOptimizationEnabled(boolean)"><CODE>setInvokerOptimizationEnabled(boolean enabled)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInvokerOptimizationEnabled(boolean)"><!-- --></A><H3>
+setInvokerOptimizationEnabled</H3>
+<PRE>
+public void <B>setInvokerOptimizationEnabled</B>(boolean&nbsp;enabled)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>The method does nothing.
+ Invoker optimization is no longer used by Rhino.
+ On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
+ like increased memory usage or longer initialization time overweight
+ small speed increase that can be gained using generated proxy class
+ to replace reflection.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newClassSerialNumber()"><!-- --></A><H3>
+newClassSerialNumber</H3>
+<PRE>
+public final int <B>newClassSerialNumber</B>()</PRE>
+<DL>
+<DD>Internal engine method to return serial number for generated classes
+ to ensure name uniqueness.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ClassCache.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassCache.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassShutter.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassShutter.html
new file mode 100644
index 0000000..924cfb5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ClassShutter.html
@@ -0,0 +1,247 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+ClassShutter (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ClassShutter (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ClassShutter.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassShutter.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface ClassShutter</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>ClassShutter</B></DL>
+</PRE>
+
+<P>
+Embeddings that wish to filter Java classes that are visible to scripts
+through the LiveConnect, should implement this interface.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.5 Release 4</DD>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#setClassShutter(org.mozilla.javascript.ClassShutter)"><CODE>Context.setClassShutter(ClassShutter)</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ClassShutter.html#visibleToScripts(java.lang.String)">visibleToScripts</A></B>(java.lang.String&nbsp;fullClassName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return true iff the Java class with the given name should be exposed
+ to scripts.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="visibleToScripts(java.lang.String)"><!-- --></A><H3>
+visibleToScripts</H3>
+<PRE>
+boolean <B>visibleToScripts</B>(java.lang.String&nbsp;fullClassName)</PRE>
+<DL>
+<DD>Return true iff the Java class with the given name should be exposed
+ to scripts.
+ <p>
+ An embedding may filter which Java classes are exposed through
+ LiveConnect to JavaScript scripts.
+ <p>
+ Due to the fact that there is no package reflection in Java,
+ this method will also be called with package names. There
+ is no way for Rhino to tell if "Packages.a.b" is a package name
+ or a class that doesn't exist. What Rhino does is attempt
+ to load each segment of "Packages.a.b.c": It first attempts to
+ load class "a", then attempts to load class "a.b", then
+ finally attempts to load class "a.b.c". On a Rhino installation
+ without any ClassShutter set, and without any of the
+ above classes, the expression "Packages.a.b.c" will result in
+ a [JavaPackage a.b.c] and not an error.
+ <p>
+ With ClassShutter supplied, Rhino will first call
+ visibleToScripts before attempting to look up the class name. If
+ visibleToScripts returns false, the class name lookup is not
+ performed and subsequent Rhino execution assumes the class is
+ not present. So for "java.lang.System.out.println" the lookup
+ of "java.lang.System" is skipped and thus Rhino assumes that
+ "java.lang.System" doesn't exist. So then for "java.lang.System.out",
+ Rhino attempts to load the class "java.lang.System.out" because
+ it assumes that "java.lang.System" is a package name.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>fullClassName</CODE> - the full name of the class (including the package
+ name, with '.' as a delimiter). For example the
+ standard string class is "java.lang.String"
+<DT><B>Returns:</B><DD>whether or not to reveal this class to scripts</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ClassShutter.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassShutter.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/CompilerEnvirons.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/CompilerEnvirons.html
new file mode 100644
index 0000000..8b5e109
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/CompilerEnvirons.html
@@ -0,0 +1,669 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+CompilerEnvirons (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="CompilerEnvirons (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/CompilerEnvirons.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CompilerEnvirons.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class CompilerEnvirons</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.CompilerEnvirons</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>CompilerEnvirons</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#CompilerEnvirons()">CompilerEnvirons</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#getErrorReporter()">getErrorReporter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#getLanguageVersion()">getLanguageVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#getOptimizationLevel()">getOptimizationLevel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#initFromContext(org.mozilla.javascript.Context)">initFromContext</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isAllowMemberExprAsFunctionName()">isAllowMemberExprAsFunctionName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isGenerateDebugInfo()">isGenerateDebugInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isGenerateObserverCount()">isGenerateObserverCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isGeneratingSource()">isGeneratingSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isReservedKeywordAsIdentifier()">isReservedKeywordAsIdentifier</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isStrictMode()">isStrictMode</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isUseDynamicScope()">isUseDynamicScope</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#isXmlAvailable()">isXmlAvailable</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#reportWarningAsError()">reportWarningAsError</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setAllowMemberExprAsFunctionName(boolean)">setAllowMemberExprAsFunctionName</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setErrorReporter(org.mozilla.javascript.ErrorReporter)">setErrorReporter</A></B>(<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>&nbsp;errorReporter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setGenerateDebugInfo(boolean)">setGenerateDebugInfo</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setGenerateObserverCount(boolean)">setGenerateObserverCount</A></B>(boolean&nbsp;generateObserverCount)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Turn on or off generation of code with callbacks to
+ track the count of executed instructions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setGeneratingSource(boolean)">setGeneratingSource</A></B>(boolean&nbsp;generatingSource)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Specify whether or not source information should be generated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setLanguageVersion(int)">setLanguageVersion</A></B>(int&nbsp;languageVersion)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setOptimizationLevel(int)">setOptimizationLevel</A></B>(int&nbsp;level)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setReservedKeywordAsIdentifier(boolean)">setReservedKeywordAsIdentifier</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html#setXmlAvailable(boolean)">setXmlAvailable</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="CompilerEnvirons()"><!-- --></A><H3>
+CompilerEnvirons</H3>
+<PRE>
+public <B>CompilerEnvirons</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="initFromContext(org.mozilla.javascript.Context)"><!-- --></A><H3>
+initFromContext</H3>
+<PRE>
+public void <B>initFromContext</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getErrorReporter()"><!-- --></A><H3>
+getErrorReporter</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A> <B>getErrorReporter</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setErrorReporter(org.mozilla.javascript.ErrorReporter)"><!-- --></A><H3>
+setErrorReporter</H3>
+<PRE>
+public void <B>setErrorReporter</B>(<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>&nbsp;errorReporter)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLanguageVersion()"><!-- --></A><H3>
+getLanguageVersion</H3>
+<PRE>
+public final int <B>getLanguageVersion</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLanguageVersion(int)"><!-- --></A><H3>
+setLanguageVersion</H3>
+<PRE>
+public void <B>setLanguageVersion</B>(int&nbsp;languageVersion)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGenerateDebugInfo()"><!-- --></A><H3>
+isGenerateDebugInfo</H3>
+<PRE>
+public final boolean <B>isGenerateDebugInfo</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGenerateDebugInfo(boolean)"><!-- --></A><H3>
+setGenerateDebugInfo</H3>
+<PRE>
+public void <B>setGenerateDebugInfo</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isUseDynamicScope()"><!-- --></A><H3>
+isUseDynamicScope</H3>
+<PRE>
+public final boolean <B>isUseDynamicScope</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isReservedKeywordAsIdentifier()"><!-- --></A><H3>
+isReservedKeywordAsIdentifier</H3>
+<PRE>
+public final boolean <B>isReservedKeywordAsIdentifier</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setReservedKeywordAsIdentifier(boolean)"><!-- --></A><H3>
+setReservedKeywordAsIdentifier</H3>
+<PRE>
+public void <B>setReservedKeywordAsIdentifier</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isAllowMemberExprAsFunctionName()"><!-- --></A><H3>
+isAllowMemberExprAsFunctionName</H3>
+<PRE>
+public final boolean <B>isAllowMemberExprAsFunctionName</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAllowMemberExprAsFunctionName(boolean)"><!-- --></A><H3>
+setAllowMemberExprAsFunctionName</H3>
+<PRE>
+public void <B>setAllowMemberExprAsFunctionName</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isXmlAvailable()"><!-- --></A><H3>
+isXmlAvailable</H3>
+<PRE>
+public final boolean <B>isXmlAvailable</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setXmlAvailable(boolean)"><!-- --></A><H3>
+setXmlAvailable</H3>
+<PRE>
+public void <B>setXmlAvailable</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptimizationLevel()"><!-- --></A><H3>
+getOptimizationLevel</H3>
+<PRE>
+public final int <B>getOptimizationLevel</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptimizationLevel(int)"><!-- --></A><H3>
+setOptimizationLevel</H3>
+<PRE>
+public void <B>setOptimizationLevel</B>(int&nbsp;level)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGeneratingSource()"><!-- --></A><H3>
+isGeneratingSource</H3>
+<PRE>
+public final boolean <B>isGeneratingSource</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isStrictMode()"><!-- --></A><H3>
+isStrictMode</H3>
+<PRE>
+public final boolean <B>isStrictMode</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportWarningAsError()"><!-- --></A><H3>
+reportWarningAsError</H3>
+<PRE>
+public final boolean <B>reportWarningAsError</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGeneratingSource(boolean)"><!-- --></A><H3>
+setGeneratingSource</H3>
+<PRE>
+public void <B>setGeneratingSource</B>(boolean&nbsp;generatingSource)</PRE>
+<DL>
+<DD>Specify whether or not source information should be generated.
+ <p>
+ Without source information, evaluating the "toString" method
+ on JavaScript functions produces only "[native code]" for
+ the body of the function.
+ Note that code generated without source is not fully ECMA
+ conformant.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGenerateObserverCount()"><!-- --></A><H3>
+isGenerateObserverCount</H3>
+<PRE>
+public boolean <B>isGenerateObserverCount</B>()</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true iff code will be generated with callbacks to enable
+ instruction thresholds</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGenerateObserverCount(boolean)"><!-- --></A><H3>
+setGenerateObserverCount</H3>
+<PRE>
+public void <B>setGenerateObserverCount</B>(boolean&nbsp;generateObserverCount)</PRE>
+<DL>
+<DD>Turn on or off generation of code with callbacks to
+ track the count of executed instructions.
+ Currently only affects JVM byte code generation: this slows down the
+ generated code, but code generated without the callbacks will not
+ be counted toward instruction thresholds. Rhino's interpretive
+ mode does instruction counting without inserting callbacks, so
+ there is no requirement to compile code differently.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>generateObserverCount</CODE> - if true, generated code will contain
+ calls to accumulate an estimate of the instructions executed.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/CompilerEnvirons.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="CompilerEnvirons.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Context.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Context.html
new file mode 100644
index 0000000..64fb637
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Context.html
@@ -0,0 +1,3581 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+Context (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Context (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Context.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Context.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class Context</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.Context</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>Context</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+This class represents the runtime context of an executing script.
+
+ Before executing a script, an instance of Context must be created
+ and associated with the thread that will be executing the script.
+ The Context will be used to store information about the executing
+ of the script such as the call stack. Contexts are associated with
+ the current thread using the <A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A>
+ or <A HREF="../../../org/mozilla/javascript/Context.html#enter()"><CODE>enter()</CODE></A> methods.<p>
+
+ Different forms of script execution are supported. Scripts may be
+ evaluated from the source directly, or first compiled and then later
+ executed. Interactive execution is also supported.<p>
+
+ Some aspects of script execution, such as type conversions and
+ object creation, may be accessed directly through methods of
+ Context.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd, Brendan Eich</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#emptyArgs">emptyArgs</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convenient value to use as zero-length array of objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#errorReporterProperty">errorReporterProperty</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE">FEATURE_DYNAMIC_SCOPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if dynamic scope should be used for name access.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_E4X">FEATURE_E4X</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if support for E4X(ECMAScript for XML) extension is available.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_ENHANCED_JAVA_ACCESS">FEATURE_ENHANCED_JAVA_ACCESS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enables enhanced access to Java.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_LOCATION_INFORMATION_IN_ERROR">FEATURE_LOCATION_INFORMATION_IN_ERROR</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;When the feature is on Rhino will add a "fileName" and "lineNumber"
+ properties to Error objects automatically.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME">FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if member expression as function name extension is available.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_NON_ECMA_GET_YEAR">FEATURE_NON_ECMA_GET_YEAR</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Controls behaviour of <tt>Date.prototype.getYear()</tt>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPERTIES">FEATURE_PARENT_PROTO_PROPERTIES</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if properties <tt>__proto__</tt> and <tt>__parent__</tt>
+ are treated specially.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPRTIES">FEATURE_PARENT_PROTO_PROPRTIES</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>In previous releases, this name was given to
+ FEATURE_PARENT_PROTO_PROPERTIES.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER">FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if reserved keywords are treated as identifiers.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_EVAL">FEATURE_STRICT_EVAL</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if strict eval mode is enabled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_MODE">FEATURE_STRICT_MODE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Controls whether JS 1.5 'strict mode' is enabled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_VARS">FEATURE_STRICT_VARS</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if strict variable mode is enabled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_TO_STRING_AS_SOURCE">FEATURE_TO_STRING_AS_SOURCE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Control if <tt>toString()</tt> should returns the same result
+ as <tt>toSource()</tt> when applied to objects and arrays.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_WARNING_AS_ERROR">FEATURE_WARNING_AS_ERROR</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Controls whether a warning should be treated as an error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#generateObserverCount">generateObserverCount</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#languageVersionProperty">languageVersionProperty</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_0">VERSION_1_0</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.0</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_1">VERSION_1_1</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.1</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_2">VERSION_1_2</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.2</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_3">VERSION_1_3</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.3</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_4">VERSION_1_4</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.4</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_5">VERSION_1_5</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.5</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_6">VERSION_1_6</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.6</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_7">VERSION_1_7</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JavaScript 1.7</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_DEFAULT">VERSION_DEFAULT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The default version.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#VERSION_UNKNOWN">VERSION_UNKNOWN</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The unknown version.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#Context()">Context</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead.</I></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#addActivationName(java.lang.String)">addActivationName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add a name to the list of names forcing the creation of real
+ activation objects for functions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#addContextListener(org.mozilla.javascript.ContextListener)">addContextListener</A></B>(org.mozilla.javascript.ContextListener&nbsp;listener)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#addPropertyChangeListener(java.beans.PropertyChangeListener)">addPropertyChangeListener</A></B>(java.beans.PropertyChangeListener&nbsp;l)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Register an object to receive notifications when a bound property
+ has changed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)">call</A></B>(<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A>&nbsp;action)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as
+ this method relies on usage of a static singleton "global"
+ ContextFactory.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextFactory, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>&nbsp;factory,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call <A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ using the Context instance associated with the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#checkLanguageVersion(int)">checkLanguageVersion</A></B>(int&nbsp;version)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#checkOptimizationLevel(int)">checkOptimizationLevel</A></B>(int&nbsp;optimizationLevel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#compileFunction(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)">compileFunction</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compile a JavaScript function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#compileReader(java.io.Reader, java.lang.String, int, java.lang.Object)">compileReader</A></B>(java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compiles the source in the given reader.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#compileReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)">compileReader</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#compileString(java.lang.String, java.lang.String, int, java.lang.Object)">compileString</A></B>(java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compiles the source in the given string.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#createClassLoader(java.lang.ClassLoader)">createClassLoader</A></B>(java.lang.ClassLoader&nbsp;parent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create class loader for generated classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#decompileFunction(org.mozilla.javascript.Function, int)">decompileFunction</A></B>(<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;fun,
+ int&nbsp;indent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decompile a JavaScript Function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#decompileFunctionBody(org.mozilla.javascript.Function, int)">decompileFunctionBody</A></B>(<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;fun,
+ int&nbsp;indent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decompile the body of a JavaScript Function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#decompileScript(org.mozilla.javascript.Script, int)">decompileScript</A></B>(<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script,
+ int&nbsp;indent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decompile the script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#enter()">enter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as this method relies
+ on usage of a static singleton "global" ContextFactory.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#enter(org.mozilla.javascript.Context)">enter</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><CODE>ContextFactory.enterContext(Context)</CODE></A> instead as
+ this method relies on usage of a static singleton "global" ContextFactory.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#evaluateReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)">evaluateReader</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Evaluate a reader as JavaScript source.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#evaluateString(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)">evaluateString</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Evaluate a JavaScript source string.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#exit()">exit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exit a block of code requiring a Context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.ClassLoader</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getApplicationClassLoader()">getApplicationClassLoader</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getCurrentContext()">getCurrentContext</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current Context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getDebuggableView(org.mozilla.javascript.Script)">getDebuggableView</A></B>(<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return DebuggableScript instance if any associated with the script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;org.mozilla.javascript.debug.Debugger</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getDebugger()">getDebugger</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the current debugger.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getDebuggerContextData()">getDebuggerContextData</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the debugger context data associated with current context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;org.mozilla.javascript.xml.XMLLib.Factory</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getE4xImplementationFactory()">getE4xImplementationFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an object which specifies an E4X implementation to use within
+ this <code>Context</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getElements(org.mozilla.javascript.Scriptable)">getElements</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;object)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the elements of a JavaScript array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getErrorReporter()">getErrorReporter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current error reporter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getFactory()">getFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><CODE>ContextFactory</CODE></A> instance used to create this Context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getImplementationVersion()">getImplementationVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the implementation version.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getInstructionObserverThreshold()">getInstructionObserverThreshold</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getLanguageVersion()">getLanguageVersion</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current language version.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Locale</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getLocale()">getLocale</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current locale.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getMaximumInterpreterStackDepth()">getMaximumInterpreterStackDepth</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getOptimizationLevel()">getOptimizationLevel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current optimization level.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getThreadLocal(java.lang.Object)">getThreadLocal</A></B>(java.lang.Object&nbsp;key)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a value corresponding to a key.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getUndefinedValue()">getUndefinedValue</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the singleton object that represents the JavaScript Undefined value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#getWrapFactory()">getWrapFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the current WrapFactory, or null if none is defined.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#hasCompileFunctionsWithDynamicScope()">hasCompileFunctionsWithDynamicScope</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)">hasFeature</A></B>(int&nbsp;featureIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Controls certain aspects of script semantics.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#initStandardObjects()">initStandardObjects</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the standard objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#initStandardObjects(org.mozilla.javascript.ScriptableObject)">initStandardObjects</A></B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the standard objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#initStandardObjects(org.mozilla.javascript.ScriptableObject, boolean)">initStandardObjects</A></B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;scope,
+ boolean&nbsp;sealed)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the standard objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isActivationNeeded(java.lang.String)">isActivationNeeded</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check whether the name is in the list of names of objects
+ forcing the creation of activation objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isGeneratingDebug()">isGeneratingDebug</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tell whether debug information is being generated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isGeneratingDebugChanged()">isGeneratingDebugChanged</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isGeneratingSource()">isGeneratingSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tell whether source information is being generated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isSealed()">isSealed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Checks if this is a sealed Context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isValidLanguageVersion(int)">isValidLanguageVersion</A></B>(int&nbsp;version)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#isValidOptimizationLevel(int)">isValidOptimizationLevel</A></B>(int&nbsp;optimizationLevel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#javaToJS(java.lang.Object, org.mozilla.javascript.Scriptable)">javaToJS</A></B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convenient method to convert java value to its closest representation
+ in JavaScript.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#jsToJava(java.lang.Object, java.lang.Class)">jsToJava</A></B>(java.lang.Object&nbsp;value,
+ java.lang.Class&nbsp;desiredType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert a JavaScript value into the desired type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#newArray(org.mozilla.javascript.Scriptable, int)">newArray</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ int&nbsp;length)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create an array with a specified initial length.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#newArray(org.mozilla.javascript.Scriptable, java.lang.Object[])">newArray</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object[]&nbsp;elements)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create an array with a set of initial elements.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable)">newObject</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new JavaScript object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable, java.lang.String)">newObject</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;constructorName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new JavaScript object by executing the named constructor.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#newObject(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">newObject</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;constructorName,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates a new JavaScript object by executing the named constructor.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#observeInstructionCount(int)">observeInstructionCount</A></B>(int&nbsp;instructionCount)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Allow application to monitor counter of executed script instructions
+ in Context subclasses.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#putThreadLocal(java.lang.Object, java.lang.Object)">putThreadLocal</A></B>(java.lang.Object&nbsp;key,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Put a value that can later be retrieved using a given key.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#removeActivationName(java.lang.String)">removeActivationName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Remove a name from the list of names forcing the creation of real
+ activation objects for functions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#removeContextListener(org.mozilla.javascript.ContextListener)">removeContextListener</A></B>(org.mozilla.javascript.ContextListener&nbsp;listener)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#removePropertyChangeListener(java.beans.PropertyChangeListener)">removePropertyChangeListener</A></B>(java.beans.PropertyChangeListener&nbsp;l)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Remove an object from the list of objects registered to receive
+ notification of changes to a bounded property</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#removeThreadLocal(java.lang.Object)">removeThreadLocal</A></B>(java.lang.Object&nbsp;key)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Remove values from thread-local storage.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportError(java.lang.String)">reportError</A></B>(java.lang.String&nbsp;message)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report an error using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportError(java.lang.String, java.lang.String, int, java.lang.String, int)">reportError</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report an error using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportRuntimeError(java.lang.String)">reportRuntimeError</A></B>(java.lang.String&nbsp;message)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report a runtime error using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportRuntimeError(java.lang.String, java.lang.String, int, java.lang.String, int)">reportRuntimeError</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report a runtime error using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportWarning(java.lang.String)">reportWarning</A></B>(java.lang.String&nbsp;message)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report a warning using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportWarning(java.lang.String, java.lang.String, int, java.lang.String, int)">reportWarning</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report a warning using the error reporter for the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#reportWarning(java.lang.String, java.lang.Throwable)">reportWarning</A></B>(java.lang.String&nbsp;message,
+ java.lang.Throwable&nbsp;t)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#seal(java.lang.Object)">seal</A></B>(java.lang.Object&nbsp;sealKey)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seal this Context object so any attempt to modify any of its properties
+ including calling <A HREF="../../../org/mozilla/javascript/Context.html#enter()"><CODE>enter()</CODE></A> and <A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>exit()</CODE></A> methods will
+ throw an exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setApplicationClassLoader(java.lang.ClassLoader)">setApplicationClassLoader</A></B>(java.lang.ClassLoader&nbsp;loader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setCachingEnabled(boolean)">setCachingEnabled</A></B>(boolean&nbsp;cachingEnabled)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setClassShutter(org.mozilla.javascript.ClassShutter)">setClassShutter</A></B>(<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript">ClassShutter</A>&nbsp;shutter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the LiveConnect access filter for this context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setCompileFunctionsWithDynamicScope(boolean)">setCompileFunctionsWithDynamicScope</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setDebugger(org.mozilla.javascript.debug.Debugger, java.lang.Object)">setDebugger</A></B>(org.mozilla.javascript.debug.Debugger&nbsp;debugger,
+ java.lang.Object&nbsp;contextData)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the associated debugger.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setErrorReporter(org.mozilla.javascript.ErrorReporter)">setErrorReporter</A></B>(<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>&nbsp;reporter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change the current error reporter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setGenerateObserverCount(boolean)">setGenerateObserverCount</A></B>(boolean&nbsp;generateObserverCount)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Turn on or off generation of code with callbacks to
+ track the count of executed instructions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setGeneratingDebug(boolean)">setGeneratingDebug</A></B>(boolean&nbsp;generatingDebug)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Specify whether or not debug information should be generated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setGeneratingSource(boolean)">setGeneratingSource</A></B>(boolean&nbsp;generatingSource)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Specify whether or not source information should be generated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setInstructionObserverThreshold(int)">setInstructionObserverThreshold</A></B>(int&nbsp;threshold)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setLanguageVersion(int)">setLanguageVersion</A></B>(int&nbsp;version)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the language version.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Locale</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setLocale(java.util.Locale)">setLocale</A></B>(java.util.Locale&nbsp;loc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the current locale.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setMaximumInterpreterStackDepth(int)">setMaximumInterpreterStackDepth</A></B>(int&nbsp;max)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setOptimizationLevel(int)">setOptimizationLevel</A></B>(int&nbsp;optimizationLevel)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the current optimization level.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setSecurityController(org.mozilla.javascript.SecurityController)">setSecurityController</A></B>(<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>&nbsp;controller)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the security controller for this context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)">setWrapFactory</A></B>(<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>&nbsp;wrapFactory)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set a WrapFactory for this Context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#stringIsCompilableUnit(java.lang.String)">stringIsCompilableUnit</A></B>(java.lang.String&nbsp;source)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check whether a string is ready to be compiled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.RuntimeException</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#throwAsScriptRuntimeEx(java.lang.Throwable)">throwAsScriptRuntimeEx</A></B>(java.lang.Throwable&nbsp;e)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rethrow the exception wrapping it as the script runtime exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toBoolean(java.lang.Object)">toBoolean</A></B>(java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert the value to a JavaScript boolean value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;double</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toNumber(java.lang.Object)">toNumber</A></B>(java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert the value to a JavaScript Number value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)">toObject</A></B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert the value to an JavaScript object value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable, java.lang.Class)">toObject</A></B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;staticType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toString(java.lang.Object)">toString</A></B>(java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert the value to a JavaScript String value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#toType(java.lang.Object, java.lang.Class)">toType</A></B>(java.lang.Object&nbsp;value,
+ java.lang.Class&nbsp;desiredType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I></I>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Context.html#unseal(java.lang.Object)">unseal</A></B>(java.lang.Object&nbsp;sealKey)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Unseal previously sealed Context object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="VERSION_UNKNOWN"><!-- --></A><H3>
+VERSION_UNKNOWN</H3>
+<PRE>
+public static final int <B>VERSION_UNKNOWN</B></PRE>
+<DL>
+<DD>The unknown version.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_UNKNOWN">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_DEFAULT"><!-- --></A><H3>
+VERSION_DEFAULT</H3>
+<PRE>
+public static final int <B>VERSION_DEFAULT</B></PRE>
+<DL>
+<DD>The default version.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_DEFAULT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_0"><!-- --></A><H3>
+VERSION_1_0</H3>
+<PRE>
+public static final int <B>VERSION_1_0</B></PRE>
+<DL>
+<DD>JavaScript 1.0
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_0">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_1"><!-- --></A><H3>
+VERSION_1_1</H3>
+<PRE>
+public static final int <B>VERSION_1_1</B></PRE>
+<DL>
+<DD>JavaScript 1.1
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_1">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_2"><!-- --></A><H3>
+VERSION_1_2</H3>
+<PRE>
+public static final int <B>VERSION_1_2</B></PRE>
+<DL>
+<DD>JavaScript 1.2
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_2">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_3"><!-- --></A><H3>
+VERSION_1_3</H3>
+<PRE>
+public static final int <B>VERSION_1_3</B></PRE>
+<DL>
+<DD>JavaScript 1.3
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_3">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_4"><!-- --></A><H3>
+VERSION_1_4</H3>
+<PRE>
+public static final int <B>VERSION_1_4</B></PRE>
+<DL>
+<DD>JavaScript 1.4
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_4">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_5"><!-- --></A><H3>
+VERSION_1_5</H3>
+<PRE>
+public static final int <B>VERSION_1_5</B></PRE>
+<DL>
+<DD>JavaScript 1.5
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_5">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_6"><!-- --></A><H3>
+VERSION_1_6</H3>
+<PRE>
+public static final int <B>VERSION_1_6</B></PRE>
+<DL>
+<DD>JavaScript 1.6
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_6">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="VERSION_1_7"><!-- --></A><H3>
+VERSION_1_7</H3>
+<PRE>
+public static final int <B>VERSION_1_7</B></PRE>
+<DL>
+<DD>JavaScript 1.7
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.VERSION_1_7">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_NON_ECMA_GET_YEAR"><!-- --></A><H3>
+FEATURE_NON_ECMA_GET_YEAR</H3>
+<PRE>
+public static final int <B>FEATURE_NON_ECMA_GET_YEAR</B></PRE>
+<DL>
+<DD>Controls behaviour of <tt>Date.prototype.getYear()</tt>.
+ If <tt>hasFeature(FEATURE_NON_ECMA_GET_YEAR)</tt> returns true,
+ Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000.
+ The default behavior of <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> is always to subtruct
+ 1900 as rquired by ECMAScript B.2.4.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_NON_ECMA_GET_YEAR">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME"><!-- --></A><H3>
+FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</H3>
+<PRE>
+public static final int <B>FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</B></PRE>
+<DL>
+<DD>Control if member expression as function name extension is available.
+ If <tt>hasFeature(FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)</tt> returns
+ true, allow <tt>function memberExpression(args) { body }</tt> to be
+ syntax sugar for <tt>memberExpression = function(args) { body }</tt>,
+ when memberExpression is not a simple identifier.
+ See ECMAScript-262, section 11.2 for definition of memberExpression.
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER"><!-- --></A><H3>
+FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</H3>
+<PRE>
+public static final int <B>FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</B></PRE>
+<DL>
+<DD>Control if reserved keywords are treated as identifiers.
+ If <tt>hasFeature(RESERVED_KEYWORD_AS_IDENTIFIER)</tt> returns true,
+ treat future reserved keyword (see Ecma-262, section 7.5.3) as ordinary
+ identifiers but warn about this usage.
+
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_TO_STRING_AS_SOURCE"><!-- --></A><H3>
+FEATURE_TO_STRING_AS_SOURCE</H3>
+<PRE>
+public static final int <B>FEATURE_TO_STRING_AS_SOURCE</B></PRE>
+<DL>
+<DD>Control if <tt>toString()</tt> should returns the same result
+ as <tt>toSource()</tt> when applied to objects and arrays.
+ If <tt>hasFeature(FEATURE_TO_STRING_AS_SOURCE)</tt> returns true,
+ calling <tt>toString()</tt> on JS objects gives the same result as
+ calling <tt>toSource()</tt>. That is it returns JS source with code
+ to create an object with all enumeratable fields of the original object
+ instead of printing <tt>[object <i>result of
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()"><CODE>Scriptable.getClassName()</CODE></A></i>]</tt>.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns true only if
+ the current JS version is set to <A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_2"><CODE>VERSION_1_2</CODE></A>.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_TO_STRING_AS_SOURCE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_PARENT_PROTO_PROPERTIES"><!-- --></A><H3>
+FEATURE_PARENT_PROTO_PROPERTIES</H3>
+<PRE>
+public static final int <B>FEATURE_PARENT_PROTO_PROPERTIES</B></PRE>
+<DL>
+<DD>Control if properties <tt>__proto__</tt> and <tt>__parent__</tt>
+ are treated specially.
+ If <tt>hasFeature(FEATURE_PARENT_PROTO_PROPERTIES)</tt> returns true,
+ treat <tt>__parent__</tt> and <tt>__proto__</tt> as special properties.
+ <p>
+ The properties allow to query and set scope and prototype chains for the
+ objects. The special meaning of the properties is available
+ only when they are used as the right hand side of the dot operator.
+ For example, while <tt>x.__proto__ = y</tt> changes the prototype
+ chain of the object <tt>x</tt> to point to <tt>y</tt>,
+ <tt>x["__proto__"] = y</tt> simply assigns a new value to the property
+ <tt>__proto__</tt> in <tt>x</tt> even when the feature is on.
+
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns true.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_PARENT_PROTO_PROPERTIES">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_PARENT_PROTO_PROPRTIES"><!-- --></A><H3>
+FEATURE_PARENT_PROTO_PROPRTIES</H3>
+<PRE>
+public static final int <B>FEATURE_PARENT_PROTO_PROPRTIES</B></PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>In previous releases, this name was given to
+ FEATURE_PARENT_PROTO_PROPERTIES.</I><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_PARENT_PROTO_PROPRTIES">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_E4X"><!-- --></A><H3>
+FEATURE_E4X</H3>
+<PRE>
+public static final int <B>FEATURE_E4X</B></PRE>
+<DL>
+<DD>Control if support for E4X(ECMAScript for XML) extension is available.
+ If hasFeature(FEATURE_E4X) returns true, the XML syntax is available.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns true if
+ the current JS version is set to <A HREF="../../../org/mozilla/javascript/Context.html#VERSION_DEFAULT"><CODE>VERSION_DEFAULT</CODE></A>
+ or is at least <A HREF="../../../org/mozilla/javascript/Context.html#VERSION_1_6"><CODE>VERSION_1_6</CODE></A>.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 1</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_E4X">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_DYNAMIC_SCOPE"><!-- --></A><H3>
+FEATURE_DYNAMIC_SCOPE</H3>
+<PRE>
+public static final int <B>FEATURE_DYNAMIC_SCOPE</B></PRE>
+<DL>
+<DD>Control if dynamic scope should be used for name access.
+ If hasFeature(FEATURE_DYNAMIC_SCOPE) returns true, then the name lookup
+ during name resolution will use the top scope of the script or function
+ which is at the top of JS execution stack instead of the top scope of the
+ script or function from the current stack frame if the top scope of
+ the top stack frame contains the top scope of the current stack frame
+ on its prototype chain.
+ <p>
+ This is useful to define shared scope containing functions that can
+ be called from scripts and functions using private scopes.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 1</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_DYNAMIC_SCOPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_STRICT_VARS"><!-- --></A><H3>
+FEATURE_STRICT_VARS</H3>
+<PRE>
+public static final int <B>FEATURE_STRICT_VARS</B></PRE>
+<DL>
+<DD>Control if strict variable mode is enabled.
+ When the feature is on Rhino reports runtime errors if assignment
+ to a global variable that does not exist is executed. When the feature
+ is off such assignments creates new variable in the global scope as
+ required by ECMA 262.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 1</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_STRICT_VARS">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_STRICT_EVAL"><!-- --></A><H3>
+FEATURE_STRICT_EVAL</H3>
+<PRE>
+public static final int <B>FEATURE_STRICT_EVAL</B></PRE>
+<DL>
+<DD>Control if strict eval mode is enabled.
+ When the feature is on Rhino reports runtime errors if non-string
+ argument is passed to the eval function. When the feature is off
+ eval simply return non-string argument as is without performing any
+ evaluation as required by ECMA 262.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 1</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_STRICT_EVAL">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_LOCATION_INFORMATION_IN_ERROR"><!-- --></A><H3>
+FEATURE_LOCATION_INFORMATION_IN_ERROR</H3>
+<PRE>
+public static final int <B>FEATURE_LOCATION_INFORMATION_IN_ERROR</B></PRE>
+<DL>
+<DD>When the feature is on Rhino will add a "fileName" and "lineNumber"
+ properties to Error objects automatically. When the feature is off, you
+ have to explicitly pass them as the second and third argument to the
+ Error constructor. Note that neither behaviour is fully ECMA 262
+ compliant (as 262 doesn't specify a three-arg constructor), but keeping
+ the feature off results in Error objects that don't have
+ additional non-ECMA properties when constructed using the ECMA-defined
+ single-arg constructor and is thus desirable if a stricter ECMA
+ compliance is desired, specifically adherence to the point 15.11.5. of
+ the standard.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 6</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_LOCATION_INFORMATION_IN_ERROR">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_STRICT_MODE"><!-- --></A><H3>
+FEATURE_STRICT_MODE</H3>
+<PRE>
+public static final int <B>FEATURE_STRICT_MODE</B></PRE>
+<DL>
+<DD>Controls whether JS 1.5 'strict mode' is enabled.
+ When the feature is on, Rhino reports more than a dozen different
+ warnings. When the feature is off, these warnings are not generated.
+ FEATURE_STRICT_MODE implies FEATURE_STRICT_VARS and FEATURE_STRICT_EVAL.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 6</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_STRICT_MODE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_WARNING_AS_ERROR"><!-- --></A><H3>
+FEATURE_WARNING_AS_ERROR</H3>
+<PRE>
+public static final int <B>FEATURE_WARNING_AS_ERROR</B></PRE>
+<DL>
+<DD>Controls whether a warning should be treated as an error.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.6 Release 6</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_WARNING_AS_ERROR">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="FEATURE_ENHANCED_JAVA_ACCESS"><!-- --></A><H3>
+FEATURE_ENHANCED_JAVA_ACCESS</H3>
+<PRE>
+public static final int <B>FEATURE_ENHANCED_JAVA_ACCESS</B></PRE>
+<DL>
+<DD>Enables enhanced access to Java.
+ Specifically, controls whether private and protected members can be
+ accessed, and whether scripts can catch all Java exceptions.
+ <p>
+ Note that this feature should only be enabled for trusted scripts.
+ <p>
+ By default <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A> returns false.
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.7 Release 1</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.FEATURE_ENHANCED_JAVA_ACCESS">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="languageVersionProperty"><!-- --></A><H3>
+languageVersionProperty</H3>
+<PRE>
+public static final java.lang.String <B>languageVersionProperty</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.languageVersionProperty">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="errorReporterProperty"><!-- --></A><H3>
+errorReporterProperty</H3>
+<PRE>
+public static final java.lang.String <B>errorReporterProperty</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.Context.errorReporterProperty">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="emptyArgs"><!-- --></A><H3>
+emptyArgs</H3>
+<PRE>
+public static final java.lang.Object[] <B>emptyArgs</B></PRE>
+<DL>
+<DD>Convenient value to use as zero-length array of objects.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="generateObserverCount"><!-- --></A><H3>
+generateObserverCount</H3>
+<PRE>
+public boolean <B>generateObserverCount</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="Context()"><!-- --></A><H3>
+Context</H3>
+<PRE>
+public <B>Context</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead.</I>
+<P>
+<DD>Create a new Context.
+
+ Note that the Context must be associated with a thread before
+ it can be used to execute a script.
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getCurrentContext()"><!-- --></A><H3>
+getCurrentContext</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>getCurrentContext</B>()</PRE>
+<DL>
+<DD>Get the current Context.
+
+ The current Context is per-thread; this method looks up
+ the Context associated with the current thread. <p>
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the Context associated with the current thread, or
+ null if no context is associated with the current
+ thread.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="enter()"><!-- --></A><H3>
+enter</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>enter</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enter()"><CODE>ContextFactory.enter()</CODE></A> or
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as this method relies
+ on usage of a static singleton "global" ContextFactory.</I>
+<P>
+<DD>Same as calling <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A> on the global
+ ContextFactory instance.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a Context associated with the current thread<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getCurrentContext()"><CODE>getCurrentContext()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>exit()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="enter(org.mozilla.javascript.Context)"><!-- --></A><H3>
+enter</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>enter</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><CODE>ContextFactory.enterContext(Context)</CODE></A> instead as
+ this method relies on usage of a static singleton "global" ContextFactory.</I>
+<P>
+<DD>Get a Context associated with the current thread, using
+ the given Context if need be.
+ <p>
+ The same as <code>enter()</code> except that <code>cx</code>
+ is associated with the current thread and returned if
+ the current thread has no associated context and <code>cx</code>
+ is not associated with any other thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - a Context to associate with the thread if possible
+<DT><B>Returns:</B><DD>a Context associated with the current thread<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)"><CODE>ContextFactory.enterContext(Context)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="exit()"><!-- --></A><H3>
+exit</H3>
+<PRE>
+public static void <B>exit</B>()</PRE>
+<DL>
+<DD>Exit a block of code requiring a Context.
+
+ Calling <code>exit()</code> will remove the association between
+ the current thread and a Context if the prior call to
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A> on this thread newly associated a
+ Context with this thread. Once the current thread no longer has an
+ associated Context, it cannot be used to execute JavaScript until it is
+ again associated with a Context.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>ContextFactory.enterContext()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="call(org.mozilla.javascript.ContextAction)"><!-- --></A><H3>
+call</H3>
+<PRE>
+public static java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A>&nbsp;action)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A> instead as
+ this method relies on usage of a static singleton "global"
+ ContextFactory.</I>
+<P>
+<DD>Call <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context cx)</CODE></A>
+ using the Context instance associated with the current thread.
+ If no Context is associated with the thread, then
+ <tt>ContextFactory.getGlobal().makeContext()</tt> will be called to
+ construct new Context instance. The instance will be temporary
+ associated with the thread during call to
+ <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context)</CODE></A>.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The result of <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context)</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="call(org.mozilla.javascript.ContextFactory, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+call</H3>
+<PRE>
+public static java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>&nbsp;factory,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call <A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ using the Context instance associated with the current thread.
+ If no Context is associated with the thread, then
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#makeContext()"><CODE>ContextFactory.makeContext()</CODE></A> will be called to construct
+ new Context instance. The instance will be temporary associated
+ with the thread during call to <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context)</CODE></A>.
+ <p>
+ It is allowed but not advisable to use null for <tt>factory</tt>
+ argument in which case the global static singleton ContextFactory
+ instance will be used to create new context instances.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addContextListener(org.mozilla.javascript.ContextListener)"><!-- --></A><H3>
+addContextListener</H3>
+<PRE>
+public static void <B>addContextListener</B>(org.mozilla.javascript.ContextListener&nbsp;listener)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#addListener(org.mozilla.javascript.ContextFactory.Listener)"><CODE>ContextFactory.addListener(ContextFactory.Listener)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()"><CODE>ContextFactory.getGlobal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removeContextListener(org.mozilla.javascript.ContextListener)"><!-- --></A><H3>
+removeContextListener</H3>
+<PRE>
+public static void <B>removeContextListener</B>(org.mozilla.javascript.ContextListener&nbsp;listener)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#removeListener(org.mozilla.javascript.ContextFactory.Listener)"><CODE>ContextFactory.removeListener(ContextFactory.Listener)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()"><CODE>ContextFactory.getGlobal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFactory()"><!-- --></A><H3>
+getFactory</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A> <B>getFactory</B>()</PRE>
+<DL>
+<DD>Return <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><CODE>ContextFactory</CODE></A> instance used to create this Context.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSealed()"><!-- --></A><H3>
+isSealed</H3>
+<PRE>
+public final boolean <B>isSealed</B>()</PRE>
+<DL>
+<DD>Checks if this is a sealed Context. A sealed Context instance does not
+ allow to modify any of its properties and will throw an exception
+ on any such attempt.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#seal(java.lang.Object)"><CODE>seal(Object sealKey)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="seal(java.lang.Object)"><!-- --></A><H3>
+seal</H3>
+<PRE>
+public final void <B>seal</B>(java.lang.Object&nbsp;sealKey)</PRE>
+<DL>
+<DD>Seal this Context object so any attempt to modify any of its properties
+ including calling <A HREF="../../../org/mozilla/javascript/Context.html#enter()"><CODE>enter()</CODE></A> and <A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>exit()</CODE></A> methods will
+ throw an exception.
+ <p>
+ If <tt>sealKey</tt> is not null, calling
+ <A HREF="../../../org/mozilla/javascript/Context.html#unseal(java.lang.Object)"><CODE>unseal(Object sealKey)</CODE></A> with the same key unseals
+ the object. If <tt>sealKey</tt> is null, unsealing is no longer possible.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#isSealed()"><CODE>isSealed()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#unseal(java.lang.Object)"><CODE>unseal(Object)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unseal(java.lang.Object)"><!-- --></A><H3>
+unseal</H3>
+<PRE>
+public final void <B>unseal</B>(java.lang.Object&nbsp;sealKey)</PRE>
+<DL>
+<DD>Unseal previously sealed Context object.
+ The <tt>sealKey</tt> argument should not be null and should match
+ <tt>sealKey</tt> suplied with the last call to
+ <A HREF="../../../org/mozilla/javascript/Context.html#seal(java.lang.Object)"><CODE>seal(Object)</CODE></A> or an exception will be thrown.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#isSealed()"><CODE>isSealed()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#seal(java.lang.Object)"><CODE>seal(Object sealKey)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLanguageVersion()"><!-- --></A><H3>
+getLanguageVersion</H3>
+<PRE>
+public final int <B>getLanguageVersion</B>()</PRE>
+<DL>
+<DD>Get the current language version.
+ <p>
+ The language version number affects JavaScript semantics as detailed
+ in the overview documentation.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an integer that is one of VERSION_1_0, VERSION_1_1, etc.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLanguageVersion(int)"><!-- --></A><H3>
+setLanguageVersion</H3>
+<PRE>
+public void <B>setLanguageVersion</B>(int&nbsp;version)</PRE>
+<DL>
+<DD>Set the language version.
+
+ <p>
+ Setting the language version will affect functions and scripts compiled
+ subsequently. See the overview documentation for version-specific
+ behavior.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>version</CODE> - the version as specified by VERSION_1_0, VERSION_1_1, etc.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isValidLanguageVersion(int)"><!-- --></A><H3>
+isValidLanguageVersion</H3>
+<PRE>
+public static boolean <B>isValidLanguageVersion</B>(int&nbsp;version)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="checkLanguageVersion(int)"><!-- --></A><H3>
+checkLanguageVersion</H3>
+<PRE>
+public static void <B>checkLanguageVersion</B>(int&nbsp;version)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getImplementationVersion()"><!-- --></A><H3>
+getImplementationVersion</H3>
+<PRE>
+public final java.lang.String <B>getImplementationVersion</B>()</PRE>
+<DL>
+<DD>Get the implementation version.
+
+ <p>
+ The implementation version is of the form
+ <pre>
+ "<i>name langVer</i> <code>release</code> <i>relNum date</i>"
+ </pre>
+ where <i>name</i> is the name of the product, <i>langVer</i> is
+ the language version, <i>relNum</i> is the release number, and
+ <i>date</i> is the release date for that specific
+ release in the form "yyyy mm dd".
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a string that encodes the product, language version, release
+ number, and date.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getErrorReporter()"><!-- --></A><H3>
+getErrorReporter</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A> <B>getErrorReporter</B>()</PRE>
+<DL>
+<DD>Get the current error reporter.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setErrorReporter(org.mozilla.javascript.ErrorReporter)"><!-- --></A><H3>
+setErrorReporter</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A> <B>setErrorReporter</B>(<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A>&nbsp;reporter)</PRE>
+<DL>
+<DD>Change the current error reporter.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the previous error reporter<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLocale()"><!-- --></A><H3>
+getLocale</H3>
+<PRE>
+public final java.util.Locale <B>getLocale</B>()</PRE>
+<DL>
+<DD>Get the current locale. Returns the default locale if none has
+ been set.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><CODE>Locale</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLocale(java.util.Locale)"><!-- --></A><H3>
+setLocale</H3>
+<PRE>
+public final java.util.Locale <B>setLocale</B>(java.util.Locale&nbsp;loc)</PRE>
+<DL>
+<DD>Set the current locale.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><CODE>Locale</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addPropertyChangeListener(java.beans.PropertyChangeListener)"><!-- --></A><H3>
+addPropertyChangeListener</H3>
+<PRE>
+public final void <B>addPropertyChangeListener</B>(java.beans.PropertyChangeListener&nbsp;l)</PRE>
+<DL>
+<DD>Register an object to receive notifications when a bound property
+ has changed
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>l</CODE> - the listener<DT><B>See Also:</B><DD><CODE>PropertyChangeEvent</CODE>,
+<A HREF="../../../org/mozilla/javascript/Context.html#removePropertyChangeListener(java.beans.PropertyChangeListener)"><CODE>removePropertyChangeListener(java.beans.PropertyChangeListener)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removePropertyChangeListener(java.beans.PropertyChangeListener)"><!-- --></A><H3>
+removePropertyChangeListener</H3>
+<PRE>
+public final void <B>removePropertyChangeListener</B>(java.beans.PropertyChangeListener&nbsp;l)</PRE>
+<DL>
+<DD>Remove an object from the list of objects registered to receive
+ notification of changes to a bounded property
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>l</CODE> - the listener<DT><B>See Also:</B><DD><CODE>PropertyChangeEvent</CODE>,
+<A HREF="../../../org/mozilla/javascript/Context.html#addPropertyChangeListener(java.beans.PropertyChangeListener)"><CODE>addPropertyChangeListener(java.beans.PropertyChangeListener)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportWarning(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+reportWarning</H3>
+<PRE>
+public static void <B>reportWarning</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Report a warning using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the warning message to report<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportWarning(java.lang.String)"><!-- --></A><H3>
+reportWarning</H3>
+<PRE>
+public static void <B>reportWarning</B>(java.lang.String&nbsp;message)</PRE>
+<DL>
+<DD>Report a warning using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the warning message to report<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportWarning(java.lang.String, java.lang.Throwable)"><!-- --></A><H3>
+reportWarning</H3>
+<PRE>
+public static void <B>reportWarning</B>(java.lang.String&nbsp;message,
+ java.lang.Throwable&nbsp;t)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportError(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+reportError</H3>
+<PRE>
+public static void <B>reportError</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Report an error using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the error message to report<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportError(java.lang.String)"><!-- --></A><H3>
+reportError</H3>
+<PRE>
+public static void <B>reportError</B>(java.lang.String&nbsp;message)</PRE>
+<DL>
+<DD>Report an error using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the error message to report<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportRuntimeError(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+reportRuntimeError</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A> <B>reportRuntimeError</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Report a runtime error using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the error message to report<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected
+<DT><B>Returns:</B><DD>a runtime exception that will be thrown to terminate the
+ execution of the script<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="reportRuntimeError(java.lang.String)"><!-- --></A><H3>
+reportRuntimeError</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A> <B>reportRuntimeError</B>(java.lang.String&nbsp;message)</PRE>
+<DL>
+<DD>Report a runtime error using the error reporter for the current thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - the error message to report<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><CODE>ErrorReporter</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initStandardObjects()"><!-- --></A><H3>
+initStandardObjects</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A> <B>initStandardObjects</B>()</PRE>
+<DL>
+<DD>Initialize the standard objects.
+
+ Creates instances of the standard objects and their constructors
+ (Object, String, Number, Date, etc.), setting up 'scope' to act
+ as a global object as in ECMA 15.1.<p>
+
+ This method must be called to initialize a scope before scripts
+ can be evaluated in that scope.<p>
+
+ This method does not affect the Context it is called upon.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the initialized scope</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initStandardObjects(org.mozilla.javascript.ScriptableObject)"><!-- --></A><H3>
+initStandardObjects</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>initStandardObjects</B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Initialize the standard objects.
+
+ Creates instances of the standard objects and their constructors
+ (Object, String, Number, Date, etc.), setting up 'scope' to act
+ as a global object as in ECMA 15.1.<p>
+
+ This method must be called to initialize a scope before scripts
+ can be evaluated in that scope.<p>
+
+ This method does not affect the Context it is called upon.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to initialize, or null, in which case a new
+ object will be created to serve as the scope
+<DT><B>Returns:</B><DD>the initialized scope. The method returns the value of the scope
+ argument if it is not null or newly allocated scope object which
+ is an instance <A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><CODE>ScriptableObject</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initStandardObjects(org.mozilla.javascript.ScriptableObject, boolean)"><!-- --></A><H3>
+initStandardObjects</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A> <B>initStandardObjects</B>(<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>&nbsp;scope,
+ boolean&nbsp;sealed)</PRE>
+<DL>
+<DD>Initialize the standard objects.
+
+ Creates instances of the standard objects and their constructors
+ (Object, String, Number, Date, etc.), setting up 'scope' to act
+ as a global object as in ECMA 15.1.<p>
+
+ This method must be called to initialize a scope before scripts
+ can be evaluated in that scope.<p>
+
+ This method does not affect the Context it is called upon.<p>
+
+ This form of the method also allows for creating "sealed" standard
+ objects. An object that is sealed cannot have properties added, changed,
+ or removed. This is useful to create a "superglobal" that can be shared
+ among several top-level objects. Note that sealing is not allowed in
+ the current ECMA/ISO language specification, but is likely for
+ the next version.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to initialize, or null, in which case a new
+ object will be created to serve as the scope<DD><CODE>sealed</CODE> - whether or not to create sealed standard objects that
+ cannot be modified.
+<DT><B>Returns:</B><DD>the initialized scope. The method returns the value of the scope
+ argument if it is not null or newly allocated scope object.<DT><B>Since:</B></DT>
+ <DD>1.4R3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUndefinedValue()"><!-- --></A><H3>
+getUndefinedValue</H3>
+<PRE>
+public static java.lang.Object <B>getUndefinedValue</B>()</PRE>
+<DL>
+<DD>Get the singleton object that represents the JavaScript Undefined value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="evaluateString(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+evaluateString</H3>
+<PRE>
+public final java.lang.Object <B>evaluateString</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD>Evaluate a JavaScript source string.
+
+ The provided source name and line number are used for error messages
+ and for producing debug information.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to execute in<DD><CODE>source</CODE> - the JavaScript source<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>securityDomain</CODE> - an arbitrary object that specifies security
+ information about the origin or owner of the script. For
+ implementations that don't care about security, this value
+ may be null.
+<DT><B>Returns:</B><DD>the result of evaluating the string<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><CODE>SecurityController</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="evaluateReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+evaluateReader</H3>
+<PRE>
+public final java.lang.Object <B>evaluateReader</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Evaluate a reader as JavaScript source.
+
+ All characters of the reader are consumed.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to execute in<DD><CODE>in</CODE> - the Reader to get JavaScript source from<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>securityDomain</CODE> - an arbitrary object that specifies security
+ information about the origin or owner of the script. For
+ implementations that don't care about security, this value
+ may be null.
+<DT><B>Returns:</B><DD>the result of evaluating the source
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE> - if an IOException was generated by the Reader</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="stringIsCompilableUnit(java.lang.String)"><!-- --></A><H3>
+stringIsCompilableUnit</H3>
+<PRE>
+public final boolean <B>stringIsCompilableUnit</B>(java.lang.String&nbsp;source)</PRE>
+<DL>
+<DD>Check whether a string is ready to be compiled.
+ <p>
+ stringIsCompilableUnit is intended to support interactive compilation of
+ javascript. If compiling the string would result in an error
+ that might be fixed by appending more source, this method
+ returns false. In every other case, it returns true.
+ <p>
+ Interactive shells may accumulate source lines, using this
+ method after each new line is appended to check whether the
+ statement being entered is complete.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>source</CODE> - the source buffer to check
+<DT><B>Returns:</B><DD>whether the source is ready for compilation<DT><B>Since:</B></DT>
+ <DD>1.4 Release 2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compileReader(org.mozilla.javascript.Scriptable, java.io.Reader, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+compileReader</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A> <B>compileReader</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE><DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#compileReader(java.io.Reader, java.lang.String, int, java.lang.Object)"><CODE>compileReader(Reader in, String sourceName, int lineno,
+ Object securityDomain)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compileReader(java.io.Reader, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+compileReader</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A> <B>compileReader</B>(java.io.Reader&nbsp;in,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Compiles the source in the given reader.
+ <p>
+ Returns a script that may later be executed.
+ Will consume all the source in the reader.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>in</CODE> - the input reader<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number for reporting errors<DD><CODE>securityDomain</CODE> - an arbitrary object that specifies security
+ information about the origin or owner of the script. For
+ implementations that don't care about security, this value
+ may be null.
+<DT><B>Returns:</B><DD>a script that may later be executed
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE> - if an IOException was generated by the Reader<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><CODE>Script</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compileString(java.lang.String, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+compileString</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A> <B>compileString</B>(java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD>Compiles the source in the given string.
+ <p>
+ Returns a script that may later be executed.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>source</CODE> - the source string<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number for reporting errors<DD><CODE>securityDomain</CODE> - an arbitrary object that specifies security
+ information about the origin or owner of the script. For
+ implementations that don't care about security, this value
+ may be null.
+<DT><B>Returns:</B><DD>a script that may later be executed<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><CODE>Script</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compileFunction(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.String, int, java.lang.Object)"><!-- --></A><H3>
+compileFunction</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A> <B>compileFunction</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineno,
+ java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD>Compile a JavaScript function.
+ <p>
+ The function source must be a function definition as defined by
+ ECMA (e.g., "function f(a) { return a; }").
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to compile relative to<DD><CODE>source</CODE> - the function definition source<DD><CODE>sourceName</CODE> - a string describing the source, such as a filename<DD><CODE>lineno</CODE> - the starting line number<DD><CODE>securityDomain</CODE> - an arbitrary object that specifies security
+ information about the origin or owner of the script. For
+ implementations that don't care about security, this value
+ may be null.
+<DT><B>Returns:</B><DD>a Function that may later be called<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><CODE>Function</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="decompileScript(org.mozilla.javascript.Script, int)"><!-- --></A><H3>
+decompileScript</H3>
+<PRE>
+public final java.lang.String <B>decompileScript</B>(<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script,
+ int&nbsp;indent)</PRE>
+<DL>
+<DD>Decompile the script.
+ <p>
+ The canonical source of the script is returned.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>script</CODE> - the script to decompile<DD><CODE>indent</CODE> - the number of spaces to indent the result
+<DT><B>Returns:</B><DD>a string representing the script source</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="decompileFunction(org.mozilla.javascript.Function, int)"><!-- --></A><H3>
+decompileFunction</H3>
+<PRE>
+public final java.lang.String <B>decompileFunction</B>(<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;fun,
+ int&nbsp;indent)</PRE>
+<DL>
+<DD>Decompile a JavaScript Function.
+ <p>
+ Decompiles a previously compiled JavaScript function object to
+ canonical source.
+ <p>
+ Returns function body of '[native code]' if no decompilation
+ information is available.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>fun</CODE> - the JavaScript function to decompile<DD><CODE>indent</CODE> - the number of spaces to indent the result
+<DT><B>Returns:</B><DD>a string representing the function source</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="decompileFunctionBody(org.mozilla.javascript.Function, int)"><!-- --></A><H3>
+decompileFunctionBody</H3>
+<PRE>
+public final java.lang.String <B>decompileFunctionBody</B>(<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;fun,
+ int&nbsp;indent)</PRE>
+<DL>
+<DD>Decompile the body of a JavaScript Function.
+ <p>
+ Decompiles the body a previously compiled JavaScript Function
+ object to canonical source, omitting the function header and
+ trailing brace.
+
+ Returns '[native code]' if no decompilation information is available.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>fun</CODE> - the JavaScript function to decompile<DD><CODE>indent</CODE> - the number of spaces to indent the result
+<DT><B>Returns:</B><DD>a string representing the function body source.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newObject(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+newObject</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>newObject</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Create a new JavaScript object.
+
+ Equivalent to evaluating "new Object()".
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to search for the constructor and to evaluate
+ against
+<DT><B>Returns:</B><DD>the new object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newObject(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+newObject</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>newObject</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;constructorName)</PRE>
+<DL>
+<DD>Create a new JavaScript object by executing the named constructor.
+
+ The call <code>newObject(scope, "Foo")</code> is equivalent to
+ evaluating "new Foo()".
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to search for the constructor and to evaluate against<DD><CODE>constructorName</CODE> - the name of the constructor to call
+<DT><B>Returns:</B><DD>the new object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newObject(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><!-- --></A><H3>
+newObject</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>newObject</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;constructorName,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Creates a new JavaScript object by executing the named constructor.
+
+ Searches <code>scope</code> for the named constructor, calls it with
+ the given arguments, and returns the result.<p>
+
+ The code
+ <pre>
+ Object[] args = { "a", "b" };
+ newObject(scope, "Foo", args)</pre>
+ is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo
+ constructor has been defined in <code>scope</code>.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - The scope to search for the constructor and to evaluate
+ against<DD><CODE>constructorName</CODE> - the name of the constructor to call<DD><CODE>args</CODE> - the array of arguments for the constructor
+<DT><B>Returns:</B><DD>the new object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newArray(org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+newArray</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>newArray</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ int&nbsp;length)</PRE>
+<DL>
+<DD>Create an array with a specified initial length.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to create the object in<DD><CODE>length</CODE> - the initial length (JavaScript arrays may have
+ additional properties added dynamically).
+<DT><B>Returns:</B><DD>the new array object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="newArray(org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+newArray</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>newArray</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object[]&nbsp;elements)</PRE>
+<DL>
+<DD>Create an array with a set of initial elements.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope to create the object in.<DD><CODE>elements</CODE> - the initial elements. Each object in this array
+ must be an acceptable JavaScript type and type
+ of array should be exactly Object[], not
+ SomeObjectSubclass[].
+<DT><B>Returns:</B><DD>the new array object.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getElements(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getElements</H3>
+<PRE>
+public final java.lang.Object[] <B>getElements</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;object)</PRE>
+<DL>
+<DD>Get the elements of a JavaScript array.
+ <p>
+ If the object defines a length property convertible to double number,
+ then the number is converted Uint32 value as defined in Ecma 9.6
+ and Java array of that size is allocated.
+ The array is initialized with the values obtained by
+ calling get() on object for each value of i in [0,length-1]. If
+ there is not a defined value for a property the Undefined value
+ is used to initialize the corresponding element in the array. The
+ Java array is then returned.
+ If the object doesn't define a length property or it is not a number,
+ empty array is returned.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>object</CODE> - the JavaScript array or array-like object
+<DT><B>Returns:</B><DD>a Java array of objects<DT><B>Since:</B></DT>
+ <DD>1.4 release 2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toBoolean(java.lang.Object)"><!-- --></A><H3>
+toBoolean</H3>
+<PRE>
+public static boolean <B>toBoolean</B>(java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Convert the value to a JavaScript boolean value.
+ <p>
+ See ECMA 9.2.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - a JavaScript value
+<DT><B>Returns:</B><DD>the corresponding boolean value converted using
+ the ECMA rules</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toNumber(java.lang.Object)"><!-- --></A><H3>
+toNumber</H3>
+<PRE>
+public static double <B>toNumber</B>(java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Convert the value to a JavaScript Number value.
+ <p>
+ Returns a Java double for the JavaScript Number.
+ <p>
+ See ECMA 9.3.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - a JavaScript value
+<DT><B>Returns:</B><DD>the corresponding double value converted using
+ the ECMA rules</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString(java.lang.Object)"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public static java.lang.String <B>toString</B>(java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Convert the value to a JavaScript String value.
+ <p>
+ See ECMA 9.8.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - a JavaScript value
+<DT><B>Returns:</B><DD>the corresponding String value converted using
+ the ECMA rules</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+toObject</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>toObject</B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Convert the value to an JavaScript object value.
+ <p>
+ Note that a scope must be provided to look up the constructors
+ for Number, Boolean, and String.
+ <p>
+ See ECMA 9.9.
+ <p>
+ Additionally, arbitrary Java objects and classes will be
+ wrapped in a Scriptable object with its Java fields and methods
+ reflected as JavaScript properties of the object.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - any Java object<DD><CODE>scope</CODE> - global scope containing constructors for Number,
+ Boolean, and String
+<DT><B>Returns:</B><DD>new JavaScript object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toObject(java.lang.Object, org.mozilla.javascript.Scriptable, java.lang.Class)"><!-- --></A><H3>
+toObject</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>toObject</B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;staticType)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="javaToJS(java.lang.Object, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+javaToJS</H3>
+<PRE>
+public static java.lang.Object <B>javaToJS</B>(java.lang.Object&nbsp;value,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Convenient method to convert java value to its closest representation
+ in JavaScript.
+ <p>
+ If value is an instance of String, Number, Boolean, Function or
+ Scriptable, it is returned as it and will be treated as the corresponding
+ JavaScript type of string, number, boolean, function and object.
+ <p>
+ Note that for Number instances during any arithmetic operation in
+ JavaScript the engine will always use the result of
+ <tt>Number.doubleValue()</tt> resulting in a precision loss if
+ the number can not fit into double.
+ <p>
+ If value is an instance of Character, it will be converted to string of
+ length 1 and its JavaScript type will be string.
+ <p>
+ The rest of values will be wrapped as LiveConnect objects
+ by calling <A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrap(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><CODE>WrapFactory.wrap(Context cx, Scriptable scope,
+ Object obj, Class staticType)</CODE></A> as in:
+ <pre>
+ Context cx = Context.getCurrentContext();
+ return cx.getWrapFactory().wrap(cx, scope, value, null);
+ </pre>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - any Java object<DD><CODE>scope</CODE> - top scope object
+<DT><B>Returns:</B><DD>value suitable to pass to any API that takes JavaScript values.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="jsToJava(java.lang.Object, java.lang.Class)"><!-- --></A><H3>
+jsToJava</H3>
+<PRE>
+public static java.lang.Object <B>jsToJava</B>(java.lang.Object&nbsp;value,
+ java.lang.Class&nbsp;desiredType)
+ throws <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></PRE>
+<DL>
+<DD>Convert a JavaScript value into the desired type.
+ Uses the semantics defined with LiveConnect3 and throws an
+ Illegal argument exception if the conversion cannot be performed.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - the JavaScript value to convert<DD><CODE>desiredType</CODE> - the Java type to convert to. Primitive Java
+ types are represented using the TYPE fields in the corresponding
+ wrapper class in java.lang.
+<DT><B>Returns:</B><DD>the converted value
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE> - if the conversion cannot be performed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toType(java.lang.Object, java.lang.Class)"><!-- --></A><H3>
+toType</H3>
+<PRE>
+public static java.lang.Object <B>toType</B>(java.lang.Object&nbsp;value,
+ java.lang.Class&nbsp;desiredType)
+ throws java.lang.IllegalArgumentException</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if the conversion cannot be performed.
+ Note that <A HREF="../../../org/mozilla/javascript/Context.html#jsToJava(java.lang.Object, java.lang.Class)"><CODE>jsToJava(Object, Class)</CODE></A> throws
+ <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A> instead.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#jsToJava(java.lang.Object, java.lang.Class)"><CODE>jsToJava(Object, Class)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="throwAsScriptRuntimeEx(java.lang.Throwable)"><!-- --></A><H3>
+throwAsScriptRuntimeEx</H3>
+<PRE>
+public static java.lang.RuntimeException <B>throwAsScriptRuntimeEx</B>(java.lang.Throwable&nbsp;e)</PRE>
+<DL>
+<DD>Rethrow the exception wrapping it as the script runtime exception.
+ Unless the exception is instance of <A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><CODE>EcmaError</CODE></A> or
+ <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A> it will be wrapped as
+ <A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><CODE>WrappedException</CODE></A>, a subclass of <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A>.
+ The resulting exception object always contains
+ source name and line number of script that triggered exception.
+ <p>
+ This method always throws an exception, its return value is provided
+ only for convenience to allow a usage like:
+ <pre>
+ throw Context.throwAsScriptRuntimeEx(ex);
+ </pre>
+ to indicate that code after the method is unreachable.
+<P>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A></CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGeneratingDebug()"><!-- --></A><H3>
+isGeneratingDebug</H3>
+<PRE>
+public final boolean <B>isGeneratingDebug</B>()</PRE>
+<DL>
+<DD>Tell whether debug information is being generated.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGeneratingDebug(boolean)"><!-- --></A><H3>
+setGeneratingDebug</H3>
+<PRE>
+public final void <B>setGeneratingDebug</B>(boolean&nbsp;generatingDebug)</PRE>
+<DL>
+<DD>Specify whether or not debug information should be generated.
+ <p>
+ Setting the generation of debug information on will set the
+ optimization level to zero.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGeneratingSource()"><!-- --></A><H3>
+isGeneratingSource</H3>
+<PRE>
+public final boolean <B>isGeneratingSource</B>()</PRE>
+<DL>
+<DD>Tell whether source information is being generated.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGeneratingSource(boolean)"><!-- --></A><H3>
+setGeneratingSource</H3>
+<PRE>
+public final void <B>setGeneratingSource</B>(boolean&nbsp;generatingSource)</PRE>
+<DL>
+<DD>Specify whether or not source information should be generated.
+ <p>
+ Without source information, evaluating the "toString" method
+ on JavaScript functions produces only "[native code]" for
+ the body of the function.
+ Note that code generated without source is not fully ECMA
+ conformant.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptimizationLevel()"><!-- --></A><H3>
+getOptimizationLevel</H3>
+<PRE>
+public final int <B>getOptimizationLevel</B>()</PRE>
+<DL>
+<DD>Get the current optimization level.
+ <p>
+ The optimization level is expressed as an integer between -1 and
+ 9.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptimizationLevel(int)"><!-- --></A><H3>
+setOptimizationLevel</H3>
+<PRE>
+public final void <B>setOptimizationLevel</B>(int&nbsp;optimizationLevel)</PRE>
+<DL>
+<DD>Set the current optimization level.
+ <p>
+ The optimization level is expected to be an integer between -1 and
+ 9. Any negative values will be interpreted as -1, and any values
+ greater than 9 will be interpreted as 9.
+ An optimization level of -1 indicates that interpretive mode will
+ always be used. Levels 0 through 9 indicate that class files may
+ be generated. Higher optimization levels trade off compile time
+ performance for runtime performance.
+ The optimizer level can't be set greater than -1 if the optimizer
+ package doesn't exist at run time.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>optimizationLevel</CODE> - an integer indicating the level of
+ optimization to perform<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isValidOptimizationLevel(int)"><!-- --></A><H3>
+isValidOptimizationLevel</H3>
+<PRE>
+public static boolean <B>isValidOptimizationLevel</B>(int&nbsp;optimizationLevel)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="checkOptimizationLevel(int)"><!-- --></A><H3>
+checkOptimizationLevel</H3>
+<PRE>
+public static void <B>checkOptimizationLevel</B>(int&nbsp;optimizationLevel)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaximumInterpreterStackDepth()"><!-- --></A><H3>
+getMaximumInterpreterStackDepth</H3>
+<PRE>
+public final int <B>getMaximumInterpreterStackDepth</B>()</PRE>
+<DL>
+<DD>Returns the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter. If the set depth would be
+ exceeded, the interpreter will throw an EvaluatorException in the script.
+ Defaults to Integer.MAX_VALUE. The setting only has effect for
+ interpreted functions (those compiled with optimization level set to -1).
+ As the interpreter doesn't use the Java stack but rather manages its own
+ stack in the heap memory, a runaway recursion in interpreted code would
+ eventually consume all available memory and cause OutOfMemoryError
+ instead of a StackOverflowError limited to only a single thread. This
+ setting helps prevent such situations.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>The current maximum interpreter stack depth.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaximumInterpreterStackDepth(int)"><!-- --></A><H3>
+setMaximumInterpreterStackDepth</H3>
+<PRE>
+public final void <B>setMaximumInterpreterStackDepth</B>(int&nbsp;max)</PRE>
+<DL>
+<DD>Sets the maximum stack depth (in terms of number of call frames)
+ allowed in a single invocation of interpreter. If the set depth would be
+ exceeded, the interpreter will throw an EvaluatorException in the script.
+ Defaults to Integer.MAX_VALUE. The setting only has effect for
+ interpreted functions (those compiled with optimization level set to -1).
+ As the interpreter doesn't use the Java stack but rather manages its own
+ stack in the heap memory, a runaway recursion in interpreted code would
+ eventually consume all available memory and cause OutOfMemoryError
+ instead of a StackOverflowError limited to only a single thread. This
+ setting helps prevent such situations.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>max</CODE> - the new maximum interpreter stack depth
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if this context's optimization level is not
+ -1
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if the new depth is not at least 1</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setSecurityController(org.mozilla.javascript.SecurityController)"><!-- --></A><H3>
+setSecurityController</H3>
+<PRE>
+public final void <B>setSecurityController</B>(<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>&nbsp;controller)</PRE>
+<DL>
+<DD>Set the security controller for this context.
+ <p> SecurityController may only be set if it is currently null
+ and <A HREF="../../../org/mozilla/javascript/SecurityController.html#hasGlobal()"><CODE>SecurityController.hasGlobal()</CODE></A> is <tt>false</tt>.
+ Otherwise a SecurityException is thrown.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>controller</CODE> - a SecurityController object
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.SecurityException</CODE> - if there is already a SecurityController
+ object for this Context or globally installed.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/SecurityController.html#initGlobal(org.mozilla.javascript.SecurityController)"><CODE>SecurityController.initGlobal(SecurityController controller)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/SecurityController.html#hasGlobal()"><CODE>SecurityController.hasGlobal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setClassShutter(org.mozilla.javascript.ClassShutter)"><!-- --></A><H3>
+setClassShutter</H3>
+<PRE>
+public final void <B>setClassShutter</B>(<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript">ClassShutter</A>&nbsp;shutter)</PRE>
+<DL>
+<DD>Set the LiveConnect access filter for this context.
+ <p> <A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><CODE>ClassShutter</CODE></A> may only be set if it is currently null.
+ Otherwise a SecurityException is thrown.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>shutter</CODE> - a ClassShutter object
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.SecurityException</CODE> - if there is already a ClassShutter
+ object for this Context</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getThreadLocal(java.lang.Object)"><!-- --></A><H3>
+getThreadLocal</H3>
+<PRE>
+public final java.lang.Object <B>getThreadLocal</B>(java.lang.Object&nbsp;key)</PRE>
+<DL>
+<DD>Get a value corresponding to a key.
+ <p>
+ Since the Context is associated with a thread it can be
+ used to maintain values that can be later retrieved using
+ the current thread.
+ <p>
+ Note that the values are maintained with the Context, so
+ if the Context is disassociated from the thread the values
+ cannot be retrieved. Also, if private data is to be maintained
+ in this manner the key should be a java.lang.Object
+ whose reference is not divulged to untrusted code.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>key</CODE> - the key used to lookup the value
+<DT><B>Returns:</B><DD>a value previously stored using putThreadLocal.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putThreadLocal(java.lang.Object, java.lang.Object)"><!-- --></A><H3>
+putThreadLocal</H3>
+<PRE>
+public final void <B>putThreadLocal</B>(java.lang.Object&nbsp;key,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Put a value that can later be retrieved using a given key.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>key</CODE> - the key used to index the value<DD><CODE>value</CODE> - the value to save</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removeThreadLocal(java.lang.Object)"><!-- --></A><H3>
+removeThreadLocal</H3>
+<PRE>
+public final void <B>removeThreadLocal</B>(java.lang.Object&nbsp;key)</PRE>
+<DL>
+<DD>Remove values from thread-local storage.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>key</CODE> - the key for the entry to remove.<DT><B>Since:</B></DT>
+ <DD>1.5 release 2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasCompileFunctionsWithDynamicScope()"><!-- --></A><H3>
+hasCompileFunctionsWithDynamicScope</H3>
+<PRE>
+public final boolean <B>hasCompileFunctionsWithDynamicScope</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE"><CODE>FEATURE_DYNAMIC_SCOPE</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCompileFunctionsWithDynamicScope(boolean)"><!-- --></A><H3>
+setCompileFunctionsWithDynamicScope</H3>
+<PRE>
+public final void <B>setCompileFunctionsWithDynamicScope</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE"><CODE>FEATURE_DYNAMIC_SCOPE</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCachingEnabled(boolean)"><!-- --></A><H3>
+setCachingEnabled</H3>
+<PRE>
+public static void <B>setCachingEnabled</B>(boolean&nbsp;cachingEnabled)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I></I>
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ClassCache.html#get(org.mozilla.javascript.Scriptable)"><CODE>ClassCache.get(Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ClassCache.html#setCachingEnabled(boolean)"><CODE>ClassCache.setCachingEnabled(boolean)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setWrapFactory(org.mozilla.javascript.WrapFactory)"><!-- --></A><H3>
+setWrapFactory</H3>
+<PRE>
+public final void <B>setWrapFactory</B>(<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A>&nbsp;wrapFactory)</PRE>
+<DL>
+<DD>Set a WrapFactory for this Context.
+ <p>
+ The WrapFactory allows custom object wrapping behavior for
+ Java object manipulated with JavaScript.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.5 Release 4</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><CODE>WrapFactory</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getWrapFactory()"><!-- --></A><H3>
+getWrapFactory</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A> <B>getWrapFactory</B>()</PRE>
+<DL>
+<DD>Return the current WrapFactory, or null if none is defined.
+<P>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.5 Release 4</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><CODE>WrapFactory</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebugger()"><!-- --></A><H3>
+getDebugger</H3>
+<PRE>
+public final org.mozilla.javascript.debug.Debugger <B>getDebugger</B>()</PRE>
+<DL>
+<DD>Return the current debugger.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the debugger, or null if none is attached.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebuggerContextData()"><!-- --></A><H3>
+getDebuggerContextData</H3>
+<PRE>
+public final java.lang.Object <B>getDebuggerContextData</B>()</PRE>
+<DL>
+<DD>Return the debugger context data associated with current context.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the debugger data, or null if debugger is not attached</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDebugger(org.mozilla.javascript.debug.Debugger, java.lang.Object)"><!-- --></A><H3>
+setDebugger</H3>
+<PRE>
+public final void <B>setDebugger</B>(org.mozilla.javascript.debug.Debugger&nbsp;debugger,
+ java.lang.Object&nbsp;contextData)</PRE>
+<DL>
+<DD>Set the associated debugger.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>debugger</CODE> - the debugger to be used on callbacks from
+ the engine.<DD><CODE>contextData</CODE> - arbitrary object that debugger can use to store
+ per Context data.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebuggableView(org.mozilla.javascript.Script)"><!-- --></A><H3>
+getDebuggableView</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A> <B>getDebuggableView</B>(<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script)</PRE>
+<DL>
+<DD>Return DebuggableScript instance if any associated with the script.
+ If callable supports DebuggableScript implementation, the method
+ returns it. Otherwise null is returned.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasFeature(int)"><!-- --></A><H3>
+hasFeature</H3>
+<PRE>
+public boolean <B>hasFeature</B>(int&nbsp;featureIndex)</PRE>
+<DL>
+<DD>Controls certain aspects of script semantics.
+ Should be overwritten to alter default behavior.
+ <p>
+ The default implementation calls
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasFeature(org.mozilla.javascript.Context, int)"><CODE>ContextFactory.hasFeature(Context cx, int featureIndex)</CODE></A>
+ that allows to customize Context behavior without introducing
+ Context subclasses. <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><CODE>ContextFactory</CODE></A> documentation gives
+ an example of hasFeature implementation.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>featureIndex</CODE> - feature index to check
+<DT><B>Returns:</B><DD>true if the <code>featureIndex</code> feature is turned on<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_NON_ECMA_GET_YEAR"><CODE>FEATURE_NON_ECMA_GET_YEAR</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME"><CODE>FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER"><CODE>FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_TO_STRING_AS_SOURCE"><CODE>FEATURE_TO_STRING_AS_SOURCE</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPRTIES"><CODE>FEATURE_PARENT_PROTO_PROPRTIES</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_E4X"><CODE>FEATURE_E4X</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_DYNAMIC_SCOPE"><CODE>FEATURE_DYNAMIC_SCOPE</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_VARS"><CODE>FEATURE_STRICT_VARS</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_EVAL"><CODE>FEATURE_STRICT_EVAL</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_LOCATION_INFORMATION_IN_ERROR"><CODE>FEATURE_LOCATION_INFORMATION_IN_ERROR</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_STRICT_MODE"><CODE>FEATURE_STRICT_MODE</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_WARNING_AS_ERROR"><CODE>FEATURE_WARNING_AS_ERROR</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_ENHANCED_JAVA_ACCESS"><CODE>FEATURE_ENHANCED_JAVA_ACCESS</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getE4xImplementationFactory()"><!-- --></A><H3>
+getE4xImplementationFactory</H3>
+<PRE>
+public org.mozilla.javascript.xml.XMLLib.Factory <B>getE4xImplementationFactory</B>()</PRE>
+<DL>
+<DD>Returns an object which specifies an E4X implementation to use within
+ this <code>Context</code>. Note
+ that the XMLLib.Factory interface should be considered experimental.
+
+ The default implementation uses the implementation provided by this
+ <code>Context</code>'s <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><CODE>ContextFactory</CODE></A>.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>An XMLLib.Factory. Should not return <code>null</code> if
+ <A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_E4X"><CODE>FEATURE_E4X</CODE></A> is enabled. See <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>hasFeature(int)</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInstructionObserverThreshold()"><!-- --></A><H3>
+getInstructionObserverThreshold</H3>
+<PRE>
+public final int <B>getInstructionObserverThreshold</B>()</PRE>
+<DL>
+<DD>Get threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.
+ When the threshold is zero, instruction counting is disabled,
+ otherwise each time the run-time executes at least the threshold value
+ of script instructions, <code>observeInstructionCount()</code> will
+ be called.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInstructionObserverThreshold(int)"><!-- --></A><H3>
+setInstructionObserverThreshold</H3>
+<PRE>
+public final void <B>setInstructionObserverThreshold</B>(int&nbsp;threshold)</PRE>
+<DL>
+<DD>Set threshold of executed instructions counter that triggers call to
+ <code>observeInstructionCount()</code>.
+ When the threshold is zero, instruction counting is disabled,
+ otherwise each time the run-time executes at least the threshold value
+ of script instructions, <code>observeInstructionCount()</code> will
+ be called.<p/>
+ Note that the meaning of "instruction" is not guaranteed to be
+ consistent between compiled and interpretive modes: executing a given
+ script or function in the different modes will result in different
+ instruction counts against the threshold.
+ <A HREF="../../../org/mozilla/javascript/Context.html#setGenerateObserverCount(boolean)"><CODE>setGenerateObserverCount(boolean)</CODE></A> is called with true if
+ <code>threshold</code> is greater than zero, false otherwise.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>threshold</CODE> - The instruction threshold</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGenerateObserverCount(boolean)"><!-- --></A><H3>
+setGenerateObserverCount</H3>
+<PRE>
+public void <B>setGenerateObserverCount</B>(boolean&nbsp;generateObserverCount)</PRE>
+<DL>
+<DD>Turn on or off generation of code with callbacks to
+ track the count of executed instructions.
+ Currently only affects JVM byte code generation: this slows down the
+ generated code, but code generated without the callbacks will not
+ be counted toward instruction thresholds. Rhino's interpretive
+ mode does instruction counting without inserting callbacks, so
+ there is no requirement to compile code differently.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>generateObserverCount</CODE> - if true, generated code will contain
+ calls to accumulate an estimate of the instructions executed.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="observeInstructionCount(int)"><!-- --></A><H3>
+observeInstructionCount</H3>
+<PRE>
+protected void <B>observeInstructionCount</B>(int&nbsp;instructionCount)</PRE>
+<DL>
+<DD>Allow application to monitor counter of executed script instructions
+ in Context subclasses.
+ Run-time calls this when instruction counting is enabled and the counter
+ reaches limit set by <code>setInstructionObserverThreshold()</code>.
+ The method is useful to observe long running scripts and if necessary
+ to terminate them.
+ <p>
+ The instruction counting support is available only for interpreted
+ scripts generated when the optimization level is set to -1.
+ <p>
+ The default implementation calls
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#observeInstructionCount(org.mozilla.javascript.Context, int)"><CODE>ContextFactory.observeInstructionCount(Context cx,
+ int instructionCount)</CODE></A>
+ that allows to customize Context behavior without introducing
+ Context subclasses.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instructionCount</CODE> - amount of script instruction executed since
+ last call to <code>observeInstructionCount</code>
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Error</CODE> - to terminate the script<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#setOptimizationLevel(int)"><CODE>setOptimizationLevel(int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createClassLoader(java.lang.ClassLoader)"><!-- --></A><H3>
+createClassLoader</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A> <B>createClassLoader</B>(java.lang.ClassLoader&nbsp;parent)</PRE>
+<DL>
+<DD>Create class loader for generated classes.
+ The method calls <A HREF="../../../org/mozilla/javascript/ContextFactory.html#createClassLoader(java.lang.ClassLoader)"><CODE>ContextFactory.createClassLoader(ClassLoader)</CODE></A>
+ using the result of <A HREF="../../../org/mozilla/javascript/Context.html#getFactory()"><CODE>getFactory()</CODE></A>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getApplicationClassLoader()"><!-- --></A><H3>
+getApplicationClassLoader</H3>
+<PRE>
+public final java.lang.ClassLoader <B>getApplicationClassLoader</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setApplicationClassLoader(java.lang.ClassLoader)"><!-- --></A><H3>
+setApplicationClassLoader</H3>
+<PRE>
+public final void <B>setApplicationClassLoader</B>(java.lang.ClassLoader&nbsp;loader)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGeneratingDebugChanged()"><!-- --></A><H3>
+isGeneratingDebugChanged</H3>
+<PRE>
+public final boolean <B>isGeneratingDebugChanged</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addActivationName(java.lang.String)"><!-- --></A><H3>
+addActivationName</H3>
+<PRE>
+public void <B>addActivationName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Add a name to the list of names forcing the creation of real
+ activation objects for functions.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the object to add to the list</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isActivationNeeded(java.lang.String)"><!-- --></A><H3>
+isActivationNeeded</H3>
+<PRE>
+public final boolean <B>isActivationNeeded</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Check whether the name is in the list of names of objects
+ forcing the creation of activation objects.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the object to test
+<DT><B>Returns:</B><DD>true if an function activation object is needed.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removeActivationName(java.lang.String)"><!-- --></A><H3>
+removeActivationName</H3>
+<PRE>
+public void <B>removeActivationName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Remove a name from the list of names forcing the creation of real
+ activation objects for functions.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the object to remove from the list</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Context.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Context.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextAction.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextAction.html
new file mode 100644
index 0000000..8e7116c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextAction.html
@@ -0,0 +1,214 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ContextAction (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ContextAction (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextAction.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextAction.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface ContextAction</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>ContextAction</B></DL>
+</PRE>
+
+<P>
+Interface to represent arbitrary action that requires to have Context
+ object associated with the current thread for its execution.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)">run</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Execute action using the supplied Context instance.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="run(org.mozilla.javascript.Context)"><!-- --></A><H3>
+run</H3>
+<PRE>
+java.lang.Object <B>run</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD>Execute action using the supplied Context instance.
+ When Rhino runtime calls the method, <tt>cx</tt> will be associated
+ with the current thread as active context.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextAction)"><CODE>Context.call(ContextAction)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>ContextFactory.call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextAction.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextAction.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.Listener.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.Listener.html
new file mode 100644
index 0000000..6290c8c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.Listener.html
@@ -0,0 +1,236 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ContextFactory.Listener (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ContextFactory.Listener (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextFactory.Listener.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextFactory.Listener.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface ContextFactory.Listener</H2>
+<DL>
+<DT><B>Enclosing class:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public static interface <B>ContextFactory.Listener</B></DL>
+</PRE>
+
+<P>
+Listener of <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> creation and release events.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html#contextCreated(org.mozilla.javascript.Context)">contextCreated</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Notify about newly created <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html#contextReleased(org.mozilla.javascript.Context)">contextReleased</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Notify that the specified <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance is no longer
+ associated with the current thread.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="contextCreated(org.mozilla.javascript.Context)"><!-- --></A><H3>
+contextCreated</H3>
+<PRE>
+void <B>contextCreated</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD>Notify about newly created <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="contextReleased(org.mozilla.javascript.Context)"><!-- --></A><H3>
+contextReleased</H3>
+<PRE>
+void <B>contextReleased</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD>Notify that the specified <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance is no longer
+ associated with the current thread.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextFactory.Listener.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextFactory.Listener.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.html
new file mode 100644
index 0000000..ef61a6f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ContextFactory.html
@@ -0,0 +1,935 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ContextFactory (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ContextFactory (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class ContextFactory</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.ContextFactory</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>ContextFactory</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Factory class that Rhino runtime uses to create new <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>
+ instances. A <code>ContextFactory</code> can also notify listeners
+ about context creation and release.
+ <p>
+ When the Rhino runtime needs to create new <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance during
+ execution of <A HREF="../../../org/mozilla/javascript/Context.html#enter()"><CODE>Context.enter()</CODE></A> or <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>, it will call
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#makeContext()"><CODE>makeContext()</CODE></A> of the current global ContextFactory.
+ See <A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()"><CODE>getGlobal()</CODE></A> and <A HREF="../../../org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)"><CODE>initGlobal(ContextFactory)</CODE></A>.
+ <p>
+ It is also possible to use explicit ContextFactory instances for Context
+ creation. This is useful to have a set of independent Rhino runtime
+ instances under single JVM. See <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A>.
+ <p>
+ The following example demonstrates Context customization to terminate
+ scripts running more then 10 seconds and to provide better compatibility
+ with JavaScript code using MSIE-specific features.
+ <pre>
+ import org.mozilla.javascript.*;
+
+ class MyFactory extends ContextFactory
+ {
+
+ // Custom <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> to store execution time.
+ private static class MyContext extends Context
+ {
+ long startTime;
+ }
+
+ static {
+ // Initialize GlobalFactory with custom factory
+ ContextFactory.initGlobal(new MyFactory());
+ }
+
+ // Override <A HREF="../../../org/mozilla/javascript/ContextFactory.html#makeContext()"><CODE>makeContext()</CODE></A>
+ protected Context makeContext()
+ {
+ MyContext cx = new MyContext();
+ // Use pure interpreter mode to allow for
+ // <A HREF="../../../org/mozilla/javascript/ContextFactory.html#observeInstructionCount(org.mozilla.javascript.Context, int)"><CODE>observeInstructionCount(Context, int)</CODE></A> to work
+ cx.setOptimizationLevel(-1);
+ // Make Rhino runtime to call observeInstructionCount
+ // each 10000 bytecode instructions
+ cx.setInstructionObserverThreshold(10000);
+ return cx;
+ }
+
+ // Override <A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasFeature(org.mozilla.javascript.Context, int)"><CODE>hasFeature(Context, int)</CODE></A>
+ public boolean hasFeature(Context cx, int featureIndex)
+ {
+ // Turn on maximum compatibility with MSIE scripts
+ switch (featureIndex) {
+ case <A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_NON_ECMA_GET_YEAR"><CODE>Context.FEATURE_NON_ECMA_GET_YEAR</CODE></A>:
+ return true;
+
+ case <A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME"><CODE>Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME</CODE></A>:
+ return true;
+
+ case <A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER"><CODE>Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER</CODE></A>:
+ return true;
+
+ case <A HREF="../../../org/mozilla/javascript/Context.html#FEATURE_PARENT_PROTO_PROPERTIES"><CODE>Context.FEATURE_PARENT_PROTO_PROPERTIES</CODE></A>:
+ return false;
+ }
+ return super.hasFeature(cx, featureIndex);
+ }
+
+ // Override <A HREF="../../../org/mozilla/javascript/ContextFactory.html#observeInstructionCount(org.mozilla.javascript.Context, int)"><CODE>observeInstructionCount(Context, int)</CODE></A>
+ protected void observeInstructionCount(Context cx, int instructionCount)
+ {
+ MyContext mcx = (MyContext)cx;
+ long currentTime = System.currentTimeMillis();
+ if (currentTime - mcx.startTime > 10*1000) {
+ // More then 10 seconds from Context creation time:
+ // it is time to stop the script.
+ // Throw Error instance to ensure that script will never
+ // get control back through catch or finally.
+ throw new Error();
+ }
+ }
+
+ // Override <A HREF="../../../org/mozilla/javascript/ContextFactory.html#doTopCall(org.mozilla.javascript.Callable, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>doTopCall(Callable,
+ Context, Scriptable,
+ Scriptable, Object[])</CODE></A>
+ protected Object doTopCall(Callable callable,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ MyContext mcx = (MyContext)cx;
+ mcx.startTime = System.currentTimeMillis();
+
+ return super.doTopCall(callable, cx, scope, thisObj, args);
+ }
+
+ }
+
+ </pre>
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;interface</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Listener of <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> creation and release events.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#ContextFactory()">ContextFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#addListener(org.mozilla.javascript.ContextFactory.Listener)">addListener</A></B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>&nbsp;listener)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)">call</A></B>(<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A>&nbsp;action)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context cx)</CODE></A>
+ using the <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance associated with the current thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#checkNotSealed()">checkNotSealed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#createClassLoader(java.lang.ClassLoader)">createClassLoader</A></B>(java.lang.ClassLoader&nbsp;parent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create class loader for generated classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#doTopCall(org.mozilla.javascript.Callable, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">doTopCall</A></B>(<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Execute top call to script or function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enter()">enter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>enterContext()</CODE></A> instead</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()">enterContext</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a context associated with the current thread, creating one if need
+ be.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext(org.mozilla.javascript.Context)">enterContext</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a Context associated with the current thread, using the given
+ Context if need be.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#exit()">exit</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A> instead.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.ClassLoader</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getApplicationClassLoader()">getApplicationClassLoader</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get ClassLoader to use when searching for Java classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;org.mozilla.javascript.xml.XMLLib.Factory</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getE4xImplementationFactory()">getE4xImplementationFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Provides a default
+ <CODE>XMLLib.Factory</CODE>
+ to be used by the <code>Context</code> instances produced by this
+ factory.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()">getGlobal</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get global ContextFactory.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasExplicitGlobal()">hasExplicitGlobal</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check if global factory was set.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasFeature(org.mozilla.javascript.Context, int)">hasFeature</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ int&nbsp;featureIndex)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implementation of <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>Context.hasFeature(int featureIndex)</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#initApplicationClassLoader(java.lang.ClassLoader)">initApplicationClassLoader</A></B>(java.lang.ClassLoader&nbsp;loader)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set explicit class loader to use when searching for Java classes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)">initGlobal</A></B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>&nbsp;factory)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set global ContextFactory.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#isSealed()">isSealed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Checks if this is a sealed ContextFactory.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#makeContext()">makeContext</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create new <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance to be associated with the current
+ thread.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#observeInstructionCount(org.mozilla.javascript.Context, int)">observeInstructionCount</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ int&nbsp;instructionCount)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implementation of
+ <A HREF="../../../org/mozilla/javascript/Context.html#observeInstructionCount(int)"><CODE>Context.observeInstructionCount(int instructionCount)</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#onContextCreated(org.mozilla.javascript.Context)">onContextCreated</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#onContextReleased(org.mozilla.javascript.Context)">onContextReleased</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#removeListener(org.mozilla.javascript.ContextFactory.Listener)">removeListener</A></B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>&nbsp;listener)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html#seal()">seal</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seal this ContextFactory so any attempt to modify it like to add or
+ remove its listeners will throw an exception.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ContextFactory()"><!-- --></A><H3>
+ContextFactory</H3>
+<PRE>
+public <B>ContextFactory</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getGlobal()"><!-- --></A><H3>
+getGlobal</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A> <B>getGlobal</B>()</PRE>
+<DL>
+<DD>Get global ContextFactory.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasExplicitGlobal()"><CODE>hasExplicitGlobal()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)"><CODE>initGlobal(ContextFactory)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasExplicitGlobal()"><!-- --></A><H3>
+hasExplicitGlobal</H3>
+<PRE>
+public static boolean <B>hasExplicitGlobal</B>()</PRE>
+<DL>
+<DD>Check if global factory was set.
+ Return true to indicate that <A HREF="../../../org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)"><CODE>initGlobal(ContextFactory)</CODE></A> was
+ already called and false to indicate that the global factory was not
+ explicitly set.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()"><CODE>getGlobal()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#initGlobal(org.mozilla.javascript.ContextFactory)"><CODE>initGlobal(ContextFactory)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initGlobal(org.mozilla.javascript.ContextFactory)"><!-- --></A><H3>
+initGlobal</H3>
+<PRE>
+public static void <B>initGlobal</B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A>&nbsp;factory)</PRE>
+<DL>
+<DD>Set global ContextFactory.
+ The method can only be called once.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getGlobal()"><CODE>getGlobal()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#hasExplicitGlobal()"><CODE>hasExplicitGlobal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="makeContext()"><!-- --></A><H3>
+makeContext</H3>
+<PRE>
+protected <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>makeContext</B>()</PRE>
+<DL>
+<DD>Create new <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance to be associated with the current
+ thread.
+ This is a callback method used by Rhino to create <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>
+ instance when it is necessary to associate one with the current
+ execution thread. <tt>makeContext()</tt> is allowed to call
+ <A HREF="../../../org/mozilla/javascript/Context.html#seal(java.lang.Object)"><CODE>Context.seal(Object)</CODE></A> on the result to prevent
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> changes by hostile scripts or applets.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasFeature(org.mozilla.javascript.Context, int)"><!-- --></A><H3>
+hasFeature</H3>
+<PRE>
+protected boolean <B>hasFeature</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ int&nbsp;featureIndex)</PRE>
+<DL>
+<DD>Implementation of <A HREF="../../../org/mozilla/javascript/Context.html#hasFeature(int)"><CODE>Context.hasFeature(int featureIndex)</CODE></A>.
+ This can be used to customize <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> without introducing
+ additional subclasses.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getE4xImplementationFactory()"><!-- --></A><H3>
+getE4xImplementationFactory</H3>
+<PRE>
+protected org.mozilla.javascript.xml.XMLLib.Factory <B>getE4xImplementationFactory</B>()</PRE>
+<DL>
+<DD>Provides a default
+ <CODE>XMLLib.Factory</CODE>
+ to be used by the <code>Context</code> instances produced by this
+ factory. See <A HREF="../../../org/mozilla/javascript/Context.html#getE4xImplementationFactory()"><CODE>Context.getE4xImplementationFactory()</CODE></A> for details.
+
+ May return null, in which case E4X functionality is not supported in
+ Rhino.
+
+ The default implementation now prefers the DOM3 E4X implementation.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createClassLoader(java.lang.ClassLoader)"><!-- --></A><H3>
+createClassLoader</H3>
+<PRE>
+protected <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A> <B>createClassLoader</B>(java.lang.ClassLoader&nbsp;parent)</PRE>
+<DL>
+<DD>Create class loader for generated classes.
+ This method creates an instance of the default implementation
+ of <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><CODE>GeneratedClassLoader</CODE></A>. Rhino uses this interface to load
+ generated JVM classes when no <A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><CODE>SecurityController</CODE></A>
+ is installed.
+ Application can override the method to provide custom class loading.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getApplicationClassLoader()"><!-- --></A><H3>
+getApplicationClassLoader</H3>
+<PRE>
+public final java.lang.ClassLoader <B>getApplicationClassLoader</B>()</PRE>
+<DL>
+<DD>Get ClassLoader to use when searching for Java classes.
+ Unless it was explicitly initialized with
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#initApplicationClassLoader(java.lang.ClassLoader)"><CODE>initApplicationClassLoader(ClassLoader)</CODE></A> the method returns
+ null to indicate that Thread.getContextClassLoader() should be used.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initApplicationClassLoader(java.lang.ClassLoader)"><!-- --></A><H3>
+initApplicationClassLoader</H3>
+<PRE>
+public final void <B>initApplicationClassLoader</B>(java.lang.ClassLoader&nbsp;loader)</PRE>
+<DL>
+<DD>Set explicit class loader to use when searching for Java classes.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#getApplicationClassLoader()"><CODE>getApplicationClassLoader()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="doTopCall(org.mozilla.javascript.Callable, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+doTopCall</H3>
+<PRE>
+protected java.lang.Object <B>doTopCall</B>(<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Execute top call to script or function.
+ When the runtime is about to execute a script or function that will
+ create the first stack frame with scriptable code, it calls this method
+ to perform the real call. In this way execution of any script
+ happens inside this function.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="observeInstructionCount(org.mozilla.javascript.Context, int)"><!-- --></A><H3>
+observeInstructionCount</H3>
+<PRE>
+protected void <B>observeInstructionCount</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ int&nbsp;instructionCount)</PRE>
+<DL>
+<DD>Implementation of
+ <A HREF="../../../org/mozilla/javascript/Context.html#observeInstructionCount(int)"><CODE>Context.observeInstructionCount(int instructionCount)</CODE></A>.
+ This can be used to customize <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> without introducing
+ additional subclasses.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="onContextCreated(org.mozilla.javascript.Context)"><!-- --></A><H3>
+onContextCreated</H3>
+<PRE>
+protected void <B>onContextCreated</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="onContextReleased(org.mozilla.javascript.Context)"><!-- --></A><H3>
+onContextReleased</H3>
+<PRE>
+protected void <B>onContextReleased</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addListener(org.mozilla.javascript.ContextFactory.Listener)"><!-- --></A><H3>
+addListener</H3>
+<PRE>
+public final void <B>addListener</B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>&nbsp;listener)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removeListener(org.mozilla.javascript.ContextFactory.Listener)"><!-- --></A><H3>
+removeListener</H3>
+<PRE>
+public final void <B>removeListener</B>(<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A>&nbsp;listener)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSealed()"><!-- --></A><H3>
+isSealed</H3>
+<PRE>
+public final boolean <B>isSealed</B>()</PRE>
+<DL>
+<DD>Checks if this is a sealed ContextFactory.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#seal()"><CODE>seal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="seal()"><!-- --></A><H3>
+seal</H3>
+<PRE>
+public final void <B>seal</B>()</PRE>
+<DL>
+<DD>Seal this ContextFactory so any attempt to modify it like to add or
+ remove its listeners will throw an exception.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#isSealed()"><CODE>isSealed()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="checkNotSealed()"><!-- --></A><H3>
+checkNotSealed</H3>
+<PRE>
+protected final void <B>checkNotSealed</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="call(org.mozilla.javascript.ContextAction)"><!-- --></A><H3>
+call</H3>
+<PRE>
+public final java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A>&nbsp;action)</PRE>
+<DL>
+<DD>Call <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context cx)</CODE></A>
+ using the <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> instance associated with the current thread.
+ If no Context is associated with the thread, then
+ <A HREF="../../../org/mozilla/javascript/ContextFactory.html#makeContext()"><CODE>makeContext()</CODE></A> will be called to construct
+ new Context instance. The instance will be temporary associated
+ with the thread during call to <A HREF="../../../org/mozilla/javascript/ContextAction.html#run(org.mozilla.javascript.Context)"><CODE>ContextAction.run(Context)</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#call(org.mozilla.javascript.ContextFactory, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Context.call(ContextFactory factory, Callable callable,
+ Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="enterContext()"><!-- --></A><H3>
+enterContext</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>enterContext</B>()</PRE>
+<DL>
+<DD>Get a context associated with the current thread, creating one if need
+ be. The Context stores the execution state of the JavaScript engine, so
+ it is required that the context be entered before execution may begin.
+ Once a thread has entered a Context, then getCurrentContext() may be
+ called to find the context that is associated with the current thread.
+ <p>
+ Calling <code>enterContext()</code> will return either the Context
+ currently associated with the thread, or will create a new context and
+ associate it with the current thread. Each call to
+ <code>enterContext()</code> must have a matching call to
+ <A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A>.
+ <pre>
+ Context cx = contextFactory.enterContext();
+ try {
+ ...
+ cx.evaluateString(...);
+ } finally {
+ Context.exit();
+ }
+ </pre>
+ Instead of using <tt>enterContext()</tt>, <tt>exit()</tt> pair consider
+ using <A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A> which guarantees proper association
+ of Context instances with the current thread.
+ With this method the above example becomes:
+ <pre>
+ ContextFactory.call(new ContextAction() {
+ public Object run(Context cx) {
+ ...
+ cx.evaluateString(...);
+ return null;
+ }
+ });
+ </pre>
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a Context associated with the current thread<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getCurrentContext()"><CODE>Context.getCurrentContext()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="enter()"><!-- --></A><H3>
+enter</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>enter</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>use <A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>enterContext()</CODE></A> instead</I>
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a Context associated with the current thread</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="exit()"><!-- --></A><H3>
+exit</H3>
+<PRE>
+public final void <B>exit</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/Context.html#exit()"><CODE>Context.exit()</CODE></A> instead.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="enterContext(org.mozilla.javascript.Context)"><!-- --></A><H3>
+enterContext</H3>
+<PRE>
+public final <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A> <B>enterContext</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+<DD>Get a Context associated with the current thread, using the given
+ Context if need be.
+ <p>
+ The same as <code>enterContext()</code> except that <code>cx</code>
+ is associated with the current thread and returned if the current thread
+ has no associated context and <code>cx</code> is not associated with any
+ other thread.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - a Context to associate with the thread if possible
+<DT><B>Returns:</B><DD>a Context associated with the current thread
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if <code>cx</code> is already associated
+ with a different thread<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ContextFactory.html#enterContext()"><CODE>enterContext()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ContextFactory.html#call(org.mozilla.javascript.ContextAction)"><CODE>call(ContextAction)</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ContextFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ContextFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_class_summary">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EcmaError.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EcmaError.html
new file mode 100644
index 0000000..71c774f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EcmaError.html
@@ -0,0 +1,455 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+EcmaError (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="EcmaError (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/EcmaError.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="EcmaError.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class EcmaError</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Throwable
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Exception
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.RuntimeException
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.RhinoException</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.EcmaError</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>EcmaError</B><DT>extends <A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></DL>
+</PRE>
+
+<P>
+The class of exceptions raised by the engine as described in
+ ECMA edition 3. See section 15.11.6 in particular.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.EcmaError">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#EcmaError(org.mozilla.javascript.Scriptable, java.lang.String, int, int, java.lang.String)">EcmaError</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;nativeError,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber,
+ int&nbsp;columnNumber,
+ java.lang.String&nbsp;lineSource)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>EcmaError error instances should not be constructed
+ explicitly since they are generated by the engine.</I></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#details()">details</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getColumnNumber()">getColumnNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getErrorMessage()">getErrorMessage</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the message corresponding to the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getErrorObject()">getErrorObject</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Always returns <b>null</b>.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getLineNumber()">getLineNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getLineSource()">getLineSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getName()">getName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the name of the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EcmaError.html#getSourceName()">getSourceName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.RhinoException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()">columnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getMessage()">getMessage</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace()">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initColumnNumber(int)">initColumnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineNumber(int)">initLineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)">initLineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)">initSourceName</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()">lineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()">lineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()">sourceName</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Throwable</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, setStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="EcmaError(org.mozilla.javascript.Scriptable, java.lang.String, int, int, java.lang.String)"><!-- --></A><H3>
+EcmaError</H3>
+<PRE>
+public <B>EcmaError</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;nativeError,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber,
+ int&nbsp;columnNumber,
+ java.lang.String&nbsp;lineSource)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>EcmaError error instances should not be constructed
+ explicitly since they are generated by the engine.</I>
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="details()"><!-- --></A><H3>
+details</H3>
+<PRE>
+public java.lang.String <B>details</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#details()">details</A></CODE> in class <CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getName()"><!-- --></A><H3>
+getName</H3>
+<PRE>
+public java.lang.String <B>getName</B>()</PRE>
+<DL>
+<DD>Gets the name of the error.
+
+ ECMA edition 3 defines the following
+ errors: EvalError, RangeError, ReferenceError,
+ SyntaxError, TypeError, and URIError. Additional error names
+ may be added in the future.
+
+ See ECMA edition 3, 15.11.7.9.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the name of the error.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getErrorMessage()"><!-- --></A><H3>
+getErrorMessage</H3>
+<PRE>
+public java.lang.String <B>getErrorMessage</B>()</PRE>
+<DL>
+<DD>Gets the message corresponding to the error.
+
+ See ECMA edition 3, 15.11.7.10.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an implemenation-defined string describing the error.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSourceName()"><!-- --></A><H3>
+getSourceName</H3>
+<PRE>
+public java.lang.String <B>getSourceName</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineNumber()"><!-- --></A><H3>
+getLineNumber</H3>
+<PRE>
+public int <B>getLineNumber</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnNumber()"><!-- --></A><H3>
+getColumnNumber</H3>
+<PRE>
+public int <B>getColumnNumber</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineSource()"><!-- --></A><H3>
+getLineSource</H3>
+<PRE>
+public java.lang.String <B>getLineSource</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getErrorObject()"><!-- --></A><H3>
+getErrorObject</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getErrorObject</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Always returns <b>null</b>.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/EcmaError.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="EcmaError.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ErrorReporter.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ErrorReporter.html
new file mode 100644
index 0000000..a559d25
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ErrorReporter.html
@@ -0,0 +1,299 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ErrorReporter (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ErrorReporter (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ErrorReporter.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ErrorReporter.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface ErrorReporter</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>ErrorReporter</B></DL>
+</PRE>
+
+<P>
+This is interface defines a protocol for the reporting of
+ errors during JavaScript translation or execution.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ErrorReporter.html#error(java.lang.String, java.lang.String, int, java.lang.String, int)">error</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report an error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ErrorReporter.html#runtimeError(java.lang.String, java.lang.String, int, java.lang.String, int)">runtimeError</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Creates an EvaluatorException that may be thrown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ErrorReporter.html#warning(java.lang.String, java.lang.String, int, java.lang.String, int)">warning</A></B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Report a warning.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="warning(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+warning</H3>
+<PRE>
+void <B>warning</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Report a warning.
+
+ The implementing class may choose to ignore the warning
+ if it desires.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - a String describing the warning<DD><CODE>sourceName</CODE> - a String describing the JavaScript source
+ where the warning occured; typically a filename or URL<DD><CODE>line</CODE> - the line number associated with the warning<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="error(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+error</H3>
+<PRE>
+void <B>error</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Report an error.
+
+ The implementing class is free to throw an exception if
+ it desires.
+
+ If execution has not yet begun, the JavaScript engine is
+ free to find additional errors rather than terminating
+ the translation. It will not execute a script that had
+ errors, however.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - a String describing the error<DD><CODE>sourceName</CODE> - a String describing the JavaScript source
+ where the error occured; typically a filename or URL<DD><CODE>line</CODE> - the line number associated with the error<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="runtimeError(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+runtimeError</H3>
+<PRE>
+<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A> <B>runtimeError</B>(java.lang.String&nbsp;message,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;line,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;lineOffset)</PRE>
+<DL>
+<DD>Creates an EvaluatorException that may be thrown.
+
+ runtimeErrors, unlike errors, will always terminate the
+ current script.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>message</CODE> - a String describing the error<DD><CODE>sourceName</CODE> - a String describing the JavaScript source
+ where the error occured; typically a filename or URL<DD><CODE>line</CODE> - the line number associated with the error<DD><CODE>lineSource</CODE> - the text of the line (may be null)<DD><CODE>lineOffset</CODE> - the offset into lineSource where problem was detected
+<DT><B>Returns:</B><DD>an EvaluatorException that will be thrown.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ErrorReporter.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ErrorReporter.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EvaluatorException.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EvaluatorException.html
new file mode 100644
index 0000000..6f06bb5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/EvaluatorException.html
@@ -0,0 +1,405 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+EvaluatorException (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="EvaluatorException (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/EvaluatorException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="EvaluatorException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class EvaluatorException</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Throwable
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Exception
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.RuntimeException
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.RhinoException</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.EvaluatorException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>EvaluatorException</B><DT>extends <A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></DL>
+</PRE>
+
+<P>
+The class of exceptions thrown by the JavaScript engine.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.EvaluatorException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String)">EvaluatorException</A></B>(java.lang.String&nbsp;detail)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String, java.lang.String, int)">EvaluatorException</A></B>(java.lang.String&nbsp;detail,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create an exception with the specified detail message.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#EvaluatorException(java.lang.String, java.lang.String, int, java.lang.String, int)">EvaluatorException</A></B>(java.lang.String&nbsp;detail,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;columnNumber)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create an exception with the specified detail message.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getColumnNumber()">getColumnNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getLineNumber()">getLineNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getLineSource()">getLineSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getSourceName()">getSourceName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.RhinoException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()">columnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#details()">details</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getMessage()">getMessage</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace()">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initColumnNumber(int)">initColumnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineNumber(int)">initLineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)">initLineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)">initSourceName</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()">lineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()">lineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()">sourceName</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Throwable</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, setStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="EvaluatorException(java.lang.String)"><!-- --></A><H3>
+EvaluatorException</H3>
+<PRE>
+public <B>EvaluatorException</B>(java.lang.String&nbsp;detail)</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="EvaluatorException(java.lang.String, java.lang.String, int)"><!-- --></A><H3>
+EvaluatorException</H3>
+<PRE>
+public <B>EvaluatorException</B>(java.lang.String&nbsp;detail,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber)</PRE>
+<DL>
+<DD>Create an exception with the specified detail message.
+
+ Errors internal to the JavaScript engine will simply throw a
+ RuntimeException.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>detail</CODE> - the error message<DD><CODE>sourceName</CODE> - the name of the source reponsible for the error<DD><CODE>lineNumber</CODE> - the line number of the source</DL>
+</DL>
+<HR>
+
+<A NAME="EvaluatorException(java.lang.String, java.lang.String, int, java.lang.String, int)"><!-- --></A><H3>
+EvaluatorException</H3>
+<PRE>
+public <B>EvaluatorException</B>(java.lang.String&nbsp;detail,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber,
+ java.lang.String&nbsp;lineSource,
+ int&nbsp;columnNumber)</PRE>
+<DL>
+<DD>Create an exception with the specified detail message.
+
+ Errors internal to the JavaScript engine will simply throw a
+ RuntimeException.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>detail</CODE> - the error message<DD><CODE>sourceName</CODE> - the name of the source responsible for the error<DD><CODE>lineNumber</CODE> - the line number of the source<DD><CODE>columnNumber</CODE> - the columnNumber of the source (may be zero if
+ unknown)<DD><CODE>lineSource</CODE> - the source of the line containing the error (may be
+ null if unknown)</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getSourceName()"><!-- --></A><H3>
+getSourceName</H3>
+<PRE>
+public java.lang.String <B>getSourceName</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineNumber()"><!-- --></A><H3>
+getLineNumber</H3>
+<PRE>
+public int <B>getLineNumber</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getColumnNumber()"><!-- --></A><H3>
+getColumnNumber</H3>
+<PRE>
+public int <B>getColumnNumber</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()"><CODE>RhinoException.columnNumber()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineSource()"><!-- --></A><H3>
+getLineSource</H3>
+<PRE>
+public java.lang.String <B>getLineSource</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()"><CODE>RhinoException.lineSource()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/EvaluatorException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="EvaluatorException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Function.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Function.html
new file mode 100644
index 0000000..55712dc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Function.html
@@ -0,0 +1,297 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Function (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Function (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Function.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Function.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface Function</H2>
+<DL>
+<DT><B>All Superinterfaces:</B> <DD><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></DD>
+</DL>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD>org.mozilla.javascript.BaseFunction, org.mozilla.javascript.Delegator, <A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>, <A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Function</B><DT>extends <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>, <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></DL>
+</PRE>
+
+<P>
+This is interface that all functions in JavaScript must implement.
+ The interface provides for calling functions and constructors.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call the function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Function.html#construct(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])">construct</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call the function as a constructor.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(int)">delete</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(java.lang.String)">delete</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()">getClassName</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getDefaultValue(java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getIds()">getIds</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getParentScope()">getParentScope</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getPrototype()">getPrototype</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#hasInstance(org.mozilla.javascript.Scriptable)">hasInstance</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+call</H3>
+<PRE>
+java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call the function.
+
+ Note that the array of arguments is not guaranteed to have
+ length greater than 0.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope to execute the function relative to. This is
+ set to the value returned by getParentScope() except
+ when the function is called from a closure.<DD><CODE>thisObj</CODE> - the JavaScript <code>this</code> object<DD><CODE>args</CODE> - the array of arguments
+<DT><B>Returns:</B><DD>the result of the call</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="construct(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+construct</H3>
+<PRE>
+<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>construct</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call the function as a constructor.
+
+ This method is invoked by the runtime in order to satisfy a use
+ of the JavaScript <code>new</code> operator. This method is
+ expected to create a new object and return it.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - an enclosing scope of the caller except
+ when the function is called from a closure.<DD><CODE>args</CODE> - the array of arguments
+<DT><B>Returns:</B><DD>the allocated object</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Function.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Function.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/FunctionObject.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/FunctionObject.html
new file mode 100644
index 0000000..4e9d011
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/FunctionObject.html
@@ -0,0 +1,774 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+FunctionObject (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="FunctionObject (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/FunctionObject.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionObject.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class FunctionObject</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">org.mozilla.javascript.ScriptableObject</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">org.mozilla.javascript.IdScriptableObject
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">org.mozilla.javascript.BaseFunction
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.FunctionObject</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>, org.mozilla.javascript.ConstProperties, org.mozilla.javascript.debug.DebuggableObject, <A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>, org.mozilla.javascript.IdFunctionCall, <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>FunctionObject</B><DT>extends org.mozilla.javascript.BaseFunction</DL>
+</PRE>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.FunctionObject">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_BOOLEAN_TYPE">JAVA_BOOLEAN_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_DOUBLE_TYPE">JAVA_DOUBLE_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_INT_TYPE">JAVA_INT_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_OBJECT_TYPE">JAVA_OBJECT_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_SCRIPTABLE_TYPE">JAVA_SCRIPTABLE_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_STRING_TYPE">JAVA_STRING_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_UNSUPPORTED_TYPE">JAVA_UNSUPPORTED_TYPE</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.ScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#CONST">CONST</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM">DONTENUM</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY">EMPTY</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT">PERMANENT</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY">READONLY</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#UNINITIALIZED_CONST">UNINITIALIZED_CONST</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#FunctionObject(java.lang.String, java.lang.reflect.Member, org.mozilla.javascript.Scriptable)">FunctionObject</A></B>(java.lang.String&nbsp;name,
+ java.lang.reflect.Member&nbsp;methodOrConstructor,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a JavaScript function object from a Java method.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#addAsConstructor(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)">addAsConstructor</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Define this function as a JavaScript constructor.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Performs conversions on argument types if needed and
+ invokes the underlying Java method or constructor.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)">convertArg</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;arg,
+ java.lang.Class&nbsp;desired)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)"><CODE>getTypeTag(Class)</CODE></A>
+ and <A HREF="../../../org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><CODE>convertArg(Context, Scriptable, Object, int)</CODE></A>
+ for type convertion.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)">convertArg</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;arg,
+ int&nbsp;typeTag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#createObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)">createObject</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return new <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A> instance using the default
+ constructor for the class of the underlying Java method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#getArity()">getArity</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the value defined by the method used to construct the object
+ (number of parameters of the method, or 1 if the method is a "varargs"
+ form).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#getFunctionName()">getFunctionName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#getLength()">getLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the same value as <A HREF="../../../org/mozilla/javascript/FunctionObject.html#getArity()"><CODE>getArity()</CODE></A>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.reflect.Member</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#getMethodOrConstructor()">getMethodOrConstructor</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get Java method or constructor this function represent.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)">getTypeTag</A></B>(java.lang.Class&nbsp;type)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.BaseFunction"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.BaseFunction</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>construct, execIdCall, fillConstructorProperties, findInstanceIdInfo, findPrototypeId, getClassName, getClassPrototype, getInstanceIdName, getInstanceIdValue, getMaxInstanceId, hasInstance, initPrototypeId, setImmunePrototypeProperty, setInstanceIdValue</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.IdScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.IdScriptableObject</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>activatePrototypeMap, addIdFunctionProperty, defaultGet, defaultPut, delete, exportAsJSClass, get, getAttributes, has, hasPrototypeMap, incompatibleCallError, initPrototypeConstructor, initPrototypeMethod, initPrototypeValue, instanceIdInfo, put, setAttributes</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.ScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#associateValue(java.lang.Object, java.lang.Object)">associateValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#avoidObjectDetection()">avoidObjectDetection</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean, boolean)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConst(java.lang.String, org.mozilla.javascript.Scriptable)">defineConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConstProperty(org.mozilla.javascript.Scriptable, java.lang.String)">defineConstProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineFunctionProperties(java.lang.String[], java.lang.Class, int)">defineFunctionProperties</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Class, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#delete(int)">delete</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)">deleteProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)">deleteProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#equivalentValues(java.lang.Object)">equivalentValues</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#get(int, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAllIds()">getAllIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)">getAssociatedValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int, org.mozilla.javascript.Scriptable)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassPrototype(org.mozilla.javascript.Scriptable, java.lang.String)">getClassPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(org.mozilla.javascript.Scriptable, java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getFunctionPrototype(org.mozilla.javascript.Scriptable)">getFunctionPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getGetterOrSetter(java.lang.String, int, boolean)">getGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getIds()">getIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getObjectPrototype(org.mozilla.javascript.Scriptable)">getObjectPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getParentScope()">getParentScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)">getProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)">getProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPropertyIds(org.mozilla.javascript.Scriptable)">getPropertyIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPrototype()">getPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)">getTopLevelScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopScopeValue(org.mozilla.javascript.Scriptable, java.lang.Object)">getTopScopeValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(int, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, int)">hasProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, java.lang.String)">hasProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isConst(java.lang.String)">isConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isGetterOrSetter(java.lang.String, int, boolean)">isGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isSealed()">isSealed</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConst(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">putConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConstProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putConstProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)">putProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#redefineProperty(org.mozilla.javascript.Scriptable, java.lang.String, boolean)">redefineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#sealObject()">sealObject</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, org.mozilla.javascript.Scriptable, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setGetterOrSetter(java.lang.String, int, org.mozilla.javascript.Callable, boolean)">setGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(int)">delete</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(java.lang.String)">delete</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getDefaultValue(java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getIds()">getIds</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getParentScope()">getParentScope</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#getPrototype()">getPrototype</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JAVA_UNSUPPORTED_TYPE"><!-- --></A><H3>
+JAVA_UNSUPPORTED_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_UNSUPPORTED_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_UNSUPPORTED_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_STRING_TYPE"><!-- --></A><H3>
+JAVA_STRING_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_STRING_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_STRING_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_INT_TYPE"><!-- --></A><H3>
+JAVA_INT_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_INT_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_INT_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_BOOLEAN_TYPE"><!-- --></A><H3>
+JAVA_BOOLEAN_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_BOOLEAN_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_BOOLEAN_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_DOUBLE_TYPE"><!-- --></A><H3>
+JAVA_DOUBLE_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_DOUBLE_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_DOUBLE_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_SCRIPTABLE_TYPE"><!-- --></A><H3>
+JAVA_SCRIPTABLE_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_SCRIPTABLE_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_SCRIPTABLE_TYPE">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="JAVA_OBJECT_TYPE"><!-- --></A><H3>
+JAVA_OBJECT_TYPE</H3>
+<PRE>
+public static final int <B>JAVA_OBJECT_TYPE</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.FunctionObject.JAVA_OBJECT_TYPE">Constant Field Values</A></DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="FunctionObject(java.lang.String, java.lang.reflect.Member, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+FunctionObject</H3>
+<PRE>
+public <B>FunctionObject</B>(java.lang.String&nbsp;name,
+ java.lang.reflect.Member&nbsp;methodOrConstructor,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Create a JavaScript function object from a Java method.
+
+ <p>The <code>member</code> argument must be either a java.lang.reflect.Method
+ or a java.lang.reflect.Constructor and must match one of two forms.<p>
+
+ The first form is a member with zero or more parameters
+ of the following types: Object, String, boolean, Scriptable,
+ int, or double. The Long type is not supported
+ because the double representation of a long (which is the
+ EMCA-mandated storage type for Numbers) may lose precision.
+ If the member is a Method, the return value must be void or one
+ of the types allowed for parameters.<p>
+
+ The runtime will perform appropriate conversions based
+ upon the type of the parameter. A parameter type of
+ Object specifies that no conversions are to be done. A parameter
+ of type String will use Context.toString to convert arguments.
+ Similarly, parameters of type double, boolean, and Scriptable
+ will cause Context.toNumber, Context.toBoolean, and
+ Context.toObject, respectively, to be called.<p>
+
+ If the method is not static, the Java 'this' value will
+ correspond to the JavaScript 'this' value. Any attempt
+ to call the function with a 'this' value that is not
+ of the right Java type will result in an error.<p>
+
+ The second form is the variable arguments (or "varargs")
+ form. If the FunctionObject will be used as a constructor,
+ the member must have the following parameters
+ <pre>
+ (Context cx, Object[] args, Function ctorObj,
+ boolean inNewExpr)</pre>
+ and if it is a Method, be static and return an Object result.<p>
+
+ Otherwise, if the FunctionObject will <i>not</i> be used to define a
+ constructor, the member must be a static Method with parameters
+ (Context cx, Scriptable thisObj, Object[] args,
+ Function funObj) </pre>
+ <pre>
+ and an Object result.<p>
+
+ When the function varargs form is called as part of a function call,
+ the <code>args</code> parameter contains the
+ arguments, with <code>thisObj</code>
+ set to the JavaScript 'this' value. <code>funObj</code>
+ is the function object for the invoked function.<p>
+
+ When the constructor varargs form is called or invoked while evaluating
+ a <code>new</code> expression, <code>args</code> contains the
+ arguments, <code>ctorObj</code> refers to this FunctionObject, and
+ <code>inNewExpr</code> is true if and only if a <code>new</code>
+ expression caused the call. This supports defining a function that
+ has different behavior when called as a constructor than when
+ invoked as a normal function call. (For example, the Boolean
+ constructor, when called as a function,
+ will convert to boolean rather than creating a new object.)<p>
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the function<DD><CODE>methodOrConstructor</CODE> - a java.lang.reflect.Method or a java.lang.reflect.Constructor
+ that defines the object<DD><CODE>scope</CODE> - enclosing scope of function<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getTypeTag(java.lang.Class)"><!-- --></A><H3>
+getTypeTag</H3>
+<PRE>
+public static int <B>getTypeTag</B>(java.lang.Class&nbsp;type)</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>One of <tt>JAVA_*_TYPE</tt> constants to indicate desired type
+ or <A HREF="../../../org/mozilla/javascript/FunctionObject.html#JAVA_UNSUPPORTED_TYPE"><CODE>JAVA_UNSUPPORTED_TYPE</CODE></A> if the convertion is not
+ possible</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><!-- --></A><H3>
+convertArg</H3>
+<PRE>
+public static java.lang.Object <B>convertArg</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;arg,
+ int&nbsp;typeTag)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getArity()"><!-- --></A><H3>
+getArity</H3>
+<PRE>
+public int <B>getArity</B>()</PRE>
+<DL>
+<DD>Return the value defined by the method used to construct the object
+ (number of parameters of the method, or 1 if the method is a "varargs"
+ form).
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>getArity</CODE> in class <CODE>org.mozilla.javascript.BaseFunction</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLength()"><!-- --></A><H3>
+getLength</H3>
+<PRE>
+public int <B>getLength</B>()</PRE>
+<DL>
+<DD>Return the same value as <A HREF="../../../org/mozilla/javascript/FunctionObject.html#getArity()"><CODE>getArity()</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>getLength</CODE> in class <CODE>org.mozilla.javascript.BaseFunction</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctionName()"><!-- --></A><H3>
+getFunctionName</H3>
+<PRE>
+public java.lang.String <B>getFunctionName</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>getFunctionName</CODE> in class <CODE>org.mozilla.javascript.BaseFunction</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMethodOrConstructor()"><!-- --></A><H3>
+getMethodOrConstructor</H3>
+<PRE>
+public java.lang.reflect.Member <B>getMethodOrConstructor</B>()</PRE>
+<DL>
+<DD>Get Java method or constructor this function represent.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addAsConstructor(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+addAsConstructor</H3>
+<PRE>
+public void <B>addAsConstructor</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</PRE>
+<DL>
+<DD>Define this function as a JavaScript constructor.
+ <p>
+ Sets up the "prototype" and "constructor" properties. Also
+ calls setParent and setPrototype with appropriate values.
+ Then adds the function object as a property of the given scope, using
+ <code>prototype.getClassName()</code>
+ as the name of the property.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the scope in which to define the constructor (typically
+ the global object)<DD><CODE>prototype</CODE> - the prototype object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)"><CODE>Scriptable.setParentScope(org.mozilla.javascript.Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)"><CODE>Scriptable.setPrototype(org.mozilla.javascript.Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()"><CODE>Scriptable.getClassName()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><!-- --></A><H3>
+convertArg</H3>
+<PRE>
+public static java.lang.Object <B>convertArg</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;arg,
+ java.lang.Class&nbsp;desired)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/FunctionObject.html#getTypeTag(java.lang.Class)"><CODE>getTypeTag(Class)</CODE></A>
+ and <A HREF="../../../org/mozilla/javascript/FunctionObject.html#convertArg(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, int)"><CODE>convertArg(Context, Scriptable, Object, int)</CODE></A>
+ for type convertion.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+call</H3>
+<PRE>
+public java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Performs conversions on argument types if needed and
+ invokes the underlying Java method or constructor.
+ <p>
+ Implements Function.call.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></CODE><DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A></CODE><DT><B>Overrides:</B><DD><CODE>call</CODE> in class <CODE>org.mozilla.javascript.BaseFunction</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope to execute the function relative to. This is
+ set to the value returned by getParentScope() except
+ when the function is called from a closure.<DD><CODE>thisObj</CODE> - the JavaScript <code>this</code> object<DD><CODE>args</CODE> - the array of arguments
+<DT><B>Returns:</B><DD>the result of the call<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Function.call(
+ Context, Scriptable, Scriptable, Object[])</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+createObject</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>createObject</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Return new <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A> instance using the default
+ constructor for the class of the underlying Java method.
+ Return null to indicate that the call method should be used to create
+ new objects.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>createObject</CODE> in class <CODE>org.mozilla.javascript.BaseFunction</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/FunctionObject.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="FunctionObject.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/GeneratedClassLoader.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/GeneratedClassLoader.html
new file mode 100644
index 0000000..2d998ac
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/GeneratedClassLoader.html
@@ -0,0 +1,236 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+GeneratedClassLoader (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="GeneratedClassLoader (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/GeneratedClassLoader.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="GeneratedClassLoader.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface GeneratedClassLoader</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>GeneratedClassLoader</B></DL>
+</PRE>
+
+<P>
+Interface to define classes from generated byte code.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html#defineClass(java.lang.String, byte[])">defineClass</A></B>(java.lang.String&nbsp;name,
+ byte[]&nbsp;data)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Define a new Java class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html#linkClass(java.lang.Class)">linkClass</A></B>(java.lang.Class&nbsp;cl)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Link the given class.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="defineClass(java.lang.String, byte[])"><!-- --></A><H3>
+defineClass</H3>
+<PRE>
+java.lang.Class <B>defineClass</B>(java.lang.String&nbsp;name,
+ byte[]&nbsp;data)</PRE>
+<DL>
+<DD>Define a new Java class.
+ Classes created via this method should have the same class loader.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - fully qualified class name<DD><CODE>data</CODE> - class byte code
+<DT><B>Returns:</B><DD>new class object</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="linkClass(java.lang.Class)"><!-- --></A><H3>
+linkClass</H3>
+<PRE>
+void <B>linkClass</B>(java.lang.Class&nbsp;cl)</PRE>
+<DL>
+<DD>Link the given class.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cl</CODE> - Class instance returned from the previous call to
+ <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html#defineClass(java.lang.String, byte[])"><CODE>defineClass(String, byte[])</CODE></A><DT><B>See Also:</B><DD><CODE>ClassLoader</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/GeneratedClassLoader.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="GeneratedClassLoader.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ImporterTopLevel.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ImporterTopLevel.html
new file mode 100644
index 0000000..78dd7a7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ImporterTopLevel.html
@@ -0,0 +1,583 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ImporterTopLevel (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ImporterTopLevel (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ImporterTopLevel.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ImporterTopLevel.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.mozilla.javascript.ScriptableObject">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class ImporterTopLevel</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">org.mozilla.javascript.ScriptableObject</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">org.mozilla.javascript.IdScriptableObject
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.ImporterTopLevel</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, org.mozilla.javascript.ConstProperties, org.mozilla.javascript.debug.DebuggableObject, org.mozilla.javascript.IdFunctionCall, <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>ImporterTopLevel</B><DT>extends org.mozilla.javascript.IdScriptableObject</DL>
+</PRE>
+
+<P>
+Class ImporterTopLevel
+
+ This class defines a ScriptableObject that can be instantiated
+ as a top-level ("global") object to provide functionality similar
+ to Java's "import" statement.
+ <p>
+ This class can be used to create a top-level scope using the following code:
+ <pre>
+ Scriptable scope = new ImporterTopLevel(cx);
+ </pre>
+ Then JavaScript code will have access to the following methods:
+ <ul>
+ <li>importClass - will "import" a class by making its unqualified name
+ available as a property of the top-level scope
+ <li>importPackage - will "import" all the classes of the package by
+ searching for unqualified names as classes qualified
+ by the given package.
+ </ul>
+ The following code from the shell illustrates this use:
+ <pre>
+ js> importClass(java.io.File)
+ js> f = new File('help.txt')
+ help.txt
+ js> importPackage(java.util)
+ js> v = new Vector()
+ []
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.ImporterTopLevel">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.ScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#CONST">CONST</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM">DONTENUM</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY">EMPTY</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT">PERMANENT</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY">READONLY</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#UNINITIALIZED_CONST">UNINITIALIZED_CONST</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel()">ImporterTopLevel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel(org.mozilla.javascript.Context)">ImporterTopLevel</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#ImporterTopLevel(org.mozilla.javascript.Context, boolean)">ImporterTopLevel</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ boolean&nbsp;sealed)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#execIdCall(org.mozilla.javascript.IdFunctionObject, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">execIdCall</A></B>(org.mozilla.javascript.IdFunctionObject&nbsp;f,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'thisObj' will be null if invoked as constructor, in which case
+ instance of Scriptable should be returned.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#findPrototypeId(java.lang.String)">findPrototypeId</A></B>(java.lang.String&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the value of the named property or NOT_FOUND.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#getClassName()">getClassName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the name of the class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the named property is defined.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#importPackage(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[], org.mozilla.javascript.Function)">importPackage</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args,
+ <A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;funObj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Kept only for compatibility.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#init(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, boolean)">init</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ boolean&nbsp;sealed)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#initPrototypeId(int)">initPrototypeId</A></B>(int&nbsp;id)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html#initStandardObjects(org.mozilla.javascript.Context, boolean)">initStandardObjects</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ boolean&nbsp;sealed)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.IdScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.IdScriptableObject</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>activatePrototypeMap, addIdFunctionProperty, defaultGet, defaultPut, delete, exportAsJSClass, fillConstructorProperties, findInstanceIdInfo, getAttributes, getInstanceIdName, getInstanceIdValue, getMaxInstanceId, hasPrototypeMap, incompatibleCallError, initPrototypeConstructor, initPrototypeMethod, initPrototypeValue, instanceIdInfo, put, setAttributes, setInstanceIdValue</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.ScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#associateValue(java.lang.Object, java.lang.Object)">associateValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#avoidObjectDetection()">avoidObjectDetection</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean, boolean)">defineClass</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConst(java.lang.String, org.mozilla.javascript.Scriptable)">defineConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConstProperty(org.mozilla.javascript.Scriptable, java.lang.String)">defineConstProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineFunctionProperties(java.lang.String[], java.lang.Class, int)">defineFunctionProperties</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Class, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, int)">defineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#delete(int)">delete</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)">deleteProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)">deleteProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#equivalentValues(java.lang.Object)">equivalentValues</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#get(int, org.mozilla.javascript.Scriptable)">get</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAllIds()">getAllIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)">getAssociatedValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int, org.mozilla.javascript.Scriptable)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)">getAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassPrototype(org.mozilla.javascript.Scriptable, java.lang.String)">getClassPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(org.mozilla.javascript.Scriptable, java.lang.Class)">getDefaultValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getFunctionPrototype(org.mozilla.javascript.Scriptable)">getFunctionPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getGetterOrSetter(java.lang.String, int, boolean)">getGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getIds()">getIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getObjectPrototype(org.mozilla.javascript.Scriptable)">getObjectPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getParentScope()">getParentScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)">getProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)">getProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPropertyIds(org.mozilla.javascript.Scriptable)">getPropertyIds</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPrototype()">getPrototype</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)">getTopLevelScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopScopeValue(org.mozilla.javascript.Scriptable, java.lang.Object)">getTopScopeValue</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(int, org.mozilla.javascript.Scriptable)">has</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasInstance(org.mozilla.javascript.Scriptable)">hasInstance</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, int)">hasProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, java.lang.String)">hasProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isConst(java.lang.String)">isConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isGetterOrSetter(java.lang.String, int, boolean)">isGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isSealed()">isSealed</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConst(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">putConst</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConstProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putConstProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)">putProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#redefineProperty(org.mozilla.javascript.Scriptable, java.lang.String, boolean)">redefineProperty</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#sealObject()">sealObject</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, org.mozilla.javascript.Scriptable, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)">setAttributes</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setGetterOrSetter(java.lang.String, int, org.mozilla.javascript.Callable, boolean)">setGetterOrSetter</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ImporterTopLevel()"><!-- --></A><H3>
+ImporterTopLevel</H3>
+<PRE>
+public <B>ImporterTopLevel</B>()</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="ImporterTopLevel(org.mozilla.javascript.Context)"><!-- --></A><H3>
+ImporterTopLevel</H3>
+<PRE>
+public <B>ImporterTopLevel</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx)</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="ImporterTopLevel(org.mozilla.javascript.Context, boolean)"><!-- --></A><H3>
+ImporterTopLevel</H3>
+<PRE>
+public <B>ImporterTopLevel</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ boolean&nbsp;sealed)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getClassName()"><!-- --></A><H3>
+getClassName</H3>
+<PRE>
+public java.lang.String <B>getClassName</B>()</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassName()">ScriptableObject</A></CODE></B></DD>
+<DD>Return the name of the class.
+
+ This is typically the same name as the constructor.
+ Classes extending ScriptableObject must implement this abstract
+ method.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()">getClassName</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE><DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassName()">getClassName</A></CODE> in class <CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="init(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, boolean)"><!-- --></A><H3>
+init</H3>
+<PRE>
+public static void <B>init</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ boolean&nbsp;sealed)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initStandardObjects(org.mozilla.javascript.Context, boolean)"><!-- --></A><H3>
+initStandardObjects</H3>
+<PRE>
+public void <B>initStandardObjects</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ boolean&nbsp;sealed)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="has(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+has</H3>
+<PRE>
+public boolean <B>has</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">ScriptableObject</A></CODE></B></DD>
+<DD>Returns true if the named property is defined.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE><DT><B>Overrides:</B><DD><CODE>has</CODE> in class <CODE>org.mozilla.javascript.IdScriptableObject</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>true if and only if the property was found in the object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><CODE>ScriptableObject.getProperty(Scriptable, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+public java.lang.Object <B>get</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">ScriptableObject</A></CODE></B></DD>
+<DD>Returns the value of the named property or NOT_FOUND.
+
+ If the property was created using defineProperty, the
+ appropriate getter method is called.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE><DT><B>Overrides:</B><DD><CODE>get</CODE> in class <CODE>org.mozilla.javascript.IdScriptableObject</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>the value of the property (may be null), or NOT_FOUND<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getUndefinedValue()"><CODE>Context.getUndefinedValue()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="importPackage(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[], org.mozilla.javascript.Function)"><!-- --></A><H3>
+importPackage</H3>
+<PRE>
+public void <B>importPackage</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args,
+ <A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>&nbsp;funObj)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Kept only for compatibility.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initPrototypeId(int)"><!-- --></A><H3>
+initPrototypeId</H3>
+<PRE>
+protected void <B>initPrototypeId</B>(int&nbsp;id)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>initPrototypeId</CODE> in class <CODE>org.mozilla.javascript.IdScriptableObject</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execIdCall(org.mozilla.javascript.IdFunctionObject, org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+execIdCall</H3>
+<PRE>
+public java.lang.Object <B>execIdCall</B>(org.mozilla.javascript.IdFunctionObject&nbsp;f,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD><B>Description copied from class: <CODE>org.mozilla.javascript.IdScriptableObject</CODE></B></DD>
+<DD>'thisObj' will be null if invoked as constructor, in which case
+ instance of Scriptable should be returned.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>execIdCall</CODE> in interface <CODE>org.mozilla.javascript.IdFunctionCall</CODE><DT><B>Overrides:</B><DD><CODE>execIdCall</CODE> in class <CODE>org.mozilla.javascript.IdScriptableObject</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="findPrototypeId(java.lang.String)"><!-- --></A><H3>
+findPrototypeId</H3>
+<PRE>
+protected int <B>findPrototypeId</B>(java.lang.String&nbsp;s)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>findPrototypeId</CODE> in class <CODE>org.mozilla.javascript.IdScriptableObject</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ImporterTopLevel.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ImporterTopLevel.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.mozilla.javascript.ScriptableObject">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/JavaScriptException.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/JavaScriptException.html
new file mode 100644
index 0000000..6dafa13
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/JavaScriptException.html
@@ -0,0 +1,375 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+JavaScriptException (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="JavaScriptException (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/JavaScriptException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="JavaScriptException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class JavaScriptException</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Throwable
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Exception
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.RuntimeException
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.RhinoException</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.JavaScriptException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>JavaScriptException</B><DT>extends <A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></DL>
+</PRE>
+
+<P>
+Java reflection of JavaScript exceptions.
+ Instances of this class are thrown by the JavaScript 'throw' keyword.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Mike McCabe</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.JavaScriptException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#JavaScriptException(java.lang.Object)">JavaScriptException</A></B>(java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)"><CODE>WrappedException.WrappedException(Throwable)</CODE></A> to report
+ exceptions in Java code.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#JavaScriptException(java.lang.Object, java.lang.String, int)">JavaScriptException</A></B>(java.lang.Object&nbsp;value,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a JavaScript exception wrapping the given JavaScript value</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#details()">details</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#getLineNumber()">getLineNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#getSourceName()">getSourceName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html#getValue()">getValue</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.RhinoException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()">columnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getMessage()">getMessage</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace()">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initColumnNumber(int)">initColumnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineNumber(int)">initLineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)">initLineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)">initSourceName</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()">lineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()">lineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()">sourceName</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Throwable</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, setStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="JavaScriptException(java.lang.Object)"><!-- --></A><H3>
+JavaScriptException</H3>
+<PRE>
+public <B>JavaScriptException</B>(java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)"><CODE>WrappedException.WrappedException(Throwable)</CODE></A> to report
+ exceptions in Java code.</I>
+<P>
+</DL>
+<HR>
+
+<A NAME="JavaScriptException(java.lang.Object, java.lang.String, int)"><!-- --></A><H3>
+JavaScriptException</H3>
+<PRE>
+public <B>JavaScriptException</B>(java.lang.Object&nbsp;value,
+ java.lang.String&nbsp;sourceName,
+ int&nbsp;lineNumber)</PRE>
+<DL>
+<DD>Create a JavaScript exception wrapping the given JavaScript value
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>value</CODE> - the JavaScript value thrown.</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="details()"><!-- --></A><H3>
+details</H3>
+<PRE>
+public java.lang.String <B>details</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#details()">details</A></CODE> in class <CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getValue()"><!-- --></A><H3>
+getValue</H3>
+<PRE>
+public java.lang.Object <B>getValue</B>()</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the value wrapped by this exception</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSourceName()"><!-- --></A><H3>
+getSourceName</H3>
+<PRE>
+public java.lang.String <B>getSourceName</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()"><CODE>RhinoException.sourceName()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineNumber()"><!-- --></A><H3>
+getLineNumber</H3>
+<PRE>
+public int <B>getLineNumber</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()"><CODE>RhinoException.lineNumber()</CODE></A> from the super class.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/JavaScriptException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="JavaScriptException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RefCallable.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RefCallable.html
new file mode 100644
index 0000000..910d0fd
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RefCallable.html
@@ -0,0 +1,233 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+RefCallable (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="RefCallable (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/RefCallable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="RefCallable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface RefCallable</H2>
+<DL>
+<DT><B>All Superinterfaces:</B> <DD><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>RefCallable</B><DT>extends <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></DL>
+</PRE>
+
+<P>
+Object that can allows assignments to the result of function calls.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;org.mozilla.javascript.Ref</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RefCallable.html#refCall(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])">refCall</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform function call in reference context.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.Callable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="refCall(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+refCall</H3>
+<PRE>
+org.mozilla.javascript.Ref <B>refCall</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Perform function call in reference context.
+ The args array reference should not be stored in any object that is
+ can be GC-reachable after this method returns. If this is necessary,
+ for example, to implement <CODE>Ref</CODE> methods, then store args.clone(),
+ not args array itself.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>thisObj</CODE> - the JavaScript <code>this</code> object<DD><CODE>args</CODE> - the array of arguments</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/RefCallable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="RefCallable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RhinoException.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RhinoException.html
new file mode 100644
index 0000000..4ad3d0f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/RhinoException.html
@@ -0,0 +1,544 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+RhinoException (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="RhinoException (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/RhinoException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="RhinoException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class RhinoException</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Throwable
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Exception
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.RuntimeException
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.RhinoException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A>, <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A>, <A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public abstract class <B>RhinoException</B><DT>extends java.lang.RuntimeException</DL>
+</PRE>
+
+<P>
+The class of exceptions thrown by the JavaScript engine.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.RhinoException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()">columnNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The column number of the location of the error, or zero if unknown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#details()">details</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#getMessage()">getMessage</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace()">getScriptStackTrace</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a string representing the script stack of this exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)">getScriptStackTrace</A></B>(java.io.FilenameFilter&nbsp;filter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a string representing the script stack of this exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#initColumnNumber(int)">initColumnNumber</A></B>(int&nbsp;columnNumber)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the column number of the script statement causing the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineNumber(int)">initLineNumber</A></B>(int&nbsp;lineNumber)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the line number of the script statement causing the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)">initLineSource</A></B>(java.lang.String&nbsp;lineSource)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the text of the source line containing the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)">initSourceName</A></B>(java.lang.String&nbsp;sourceName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize the uri of the script source containing the error.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()">lineNumber</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the line number of the statement causing the error,
+ or zero if not available.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()">lineSource</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The source text of the line causing the error, or null if unknown.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)">printStackTrace</A></B>(java.io.PrintStream&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)">printStackTrace</A></B>(java.io.PrintWriter&nbsp;s)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()">sourceName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the uri of the script source containing the error, or null
+ if that information is not available.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Throwable</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, setStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getMessage()"><!-- --></A><H3>
+getMessage</H3>
+<PRE>
+public final java.lang.String <B>getMessage</B>()</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>getMessage</CODE> in class <CODE>java.lang.Throwable</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="details()"><!-- --></A><H3>
+details</H3>
+<PRE>
+public java.lang.String <B>details</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sourceName()"><!-- --></A><H3>
+sourceName</H3>
+<PRE>
+public final java.lang.String <B>sourceName</B>()</PRE>
+<DL>
+<DD>Get the uri of the script source containing the error, or null
+ if that information is not available.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initSourceName(java.lang.String)"><!-- --></A><H3>
+initSourceName</H3>
+<PRE>
+public final void <B>initSourceName</B>(java.lang.String&nbsp;sourceName)</PRE>
+<DL>
+<DD>Initialize the uri of the script source containing the error.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sourceName</CODE> - the uri of the script source responsible for the error.
+ It should not be <tt>null</tt>.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if the method is called more then once.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="lineNumber()"><!-- --></A><H3>
+lineNumber</H3>
+<PRE>
+public final int <B>lineNumber</B>()</PRE>
+<DL>
+<DD>Returns the line number of the statement causing the error,
+ or zero if not available.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initLineNumber(int)"><!-- --></A><H3>
+initLineNumber</H3>
+<PRE>
+public final void <B>initLineNumber</B>(int&nbsp;lineNumber)</PRE>
+<DL>
+<DD>Initialize the line number of the script statement causing the error.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>lineNumber</CODE> - the line number in the script source.
+ It should be positive number.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if the method is called more then once.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="columnNumber()"><!-- --></A><H3>
+columnNumber</H3>
+<PRE>
+public final int <B>columnNumber</B>()</PRE>
+<DL>
+<DD>The column number of the location of the error, or zero if unknown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initColumnNumber(int)"><!-- --></A><H3>
+initColumnNumber</H3>
+<PRE>
+public final void <B>initColumnNumber</B>(int&nbsp;columnNumber)</PRE>
+<DL>
+<DD>Initialize the column number of the script statement causing the error.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>columnNumber</CODE> - the column number in the script source.
+ It should be positive number.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if the method is called more then once.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="lineSource()"><!-- --></A><H3>
+lineSource</H3>
+<PRE>
+public final java.lang.String <B>lineSource</B>()</PRE>
+<DL>
+<DD>The source text of the line causing the error, or null if unknown.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initLineSource(java.lang.String)"><!-- --></A><H3>
+initLineSource</H3>
+<PRE>
+public final void <B>initLineSource</B>(java.lang.String&nbsp;lineSource)</PRE>
+<DL>
+<DD>Initialize the text of the source line containing the error.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>lineSource</CODE> - the text of the source line responsible for the error.
+ It should not be <tt>null</tt>.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalStateException</CODE> - if the method is called more then once.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getScriptStackTrace()"><!-- --></A><H3>
+getScriptStackTrace</H3>
+<PRE>
+public java.lang.String <B>getScriptStackTrace</B>()</PRE>
+<DL>
+<DD>Get a string representing the script stack of this exception.
+ If optimization is enabled, this corresponds to all java stack elements
+ with a source name ending with ".js".
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a script stack dump<DT><B>Since:</B></DT>
+ <DD>1.6R6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getScriptStackTrace(java.io.FilenameFilter)"><!-- --></A><H3>
+getScriptStackTrace</H3>
+<PRE>
+public java.lang.String <B>getScriptStackTrace</B>(java.io.FilenameFilter&nbsp;filter)</PRE>
+<DL>
+<DD>Get a string representing the script stack of this exception.
+ If optimization is enabled, this corresponds to all java stack elements
+ with a source name matching the <code>filter</code>.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>filter</CODE> - the file name filter to determine whether a file is a
+ script file
+<DT><B>Returns:</B><DD>a script stack dump<DT><B>Since:</B></DT>
+ <DD>1.6R6</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="printStackTrace(java.io.PrintWriter)"><!-- --></A><H3>
+printStackTrace</H3>
+<PRE>
+public void <B>printStackTrace</B>(java.io.PrintWriter&nbsp;s)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>printStackTrace</CODE> in class <CODE>java.lang.Throwable</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="printStackTrace(java.io.PrintStream)"><!-- --></A><H3>
+printStackTrace</H3>
+<PRE>
+public void <B>printStackTrace</B>(java.io.PrintStream&nbsp;s)</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>printStackTrace</CODE> in class <CODE>java.lang.Throwable</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/RhinoException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="RhinoException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Script.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Script.html
new file mode 100644
index 0000000..65f250f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Script.html
@@ -0,0 +1,231 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Script (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Script (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Script.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Script.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface Script</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Script</B></DL>
+</PRE>
+
+<P>
+All compiled scripts implement this interface.
+ <p>
+ This class encapsulates script execution relative to an
+ object scope.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.3</DD>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Script.html#exec(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)">exec</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Execute the script.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="exec(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+exec</H3>
+<PRE>
+java.lang.Object <B>exec</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Execute the script.
+ <p>
+ The script is executed in a particular runtime Context, which
+ must be associated with the current thread.
+ The script is executed relative to a scope--definitions and
+ uses of global top-level variables and functions will access
+ properties of the scope object. For compliant ECMA
+ programs, the scope must be an object that has been initialized
+ as a global object using <code>Context.initStandardObjects</code>.
+ <p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the Context associated with the current thread<DD><CODE>scope</CODE> - the scope to execute relative to
+<DT><B>Returns:</B><DD>the result of executing the script<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#initStandardObjects()"><CODE>Context.initStandardObjects()</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Script.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Script.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Scriptable.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Scriptable.html
new file mode 100644
index 0000000..14ab7aa
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Scriptable.html
@@ -0,0 +1,756 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Scriptable (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Scriptable (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Scriptable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Scriptable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface Scriptable</H2>
+<DL>
+<DT><B>All Known Subinterfaces:</B> <DD><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A></DD>
+</DL>
+<DL>
+<DT><B>All Known Implementing Classes:</B> <DD>org.mozilla.javascript.BaseFunction, org.mozilla.javascript.Delegator, <A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A>, org.mozilla.javascript.IdScriptableObject, <A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A>, <A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A>, <A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Scriptable</B></DL>
+</PRE>
+
+<P>
+This is interface that all objects in JavaScript must implement.
+ The interface provides for the management of properties and for
+ performing conversions.
+ <p>
+ Host system implementors may find it easier to extend the ScriptableObject
+ class rather than implementing Scriptable when writing host objects.
+ <p>
+ There are many static methods defined in ScriptableObject that perform
+ the multiple calls to the Scriptable interface needed in order to
+ manipulate properties in prototype chains.
+ <p>
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd, Nick Thompson, Brendan Eich</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><CODE>ScriptableObject</CODE></A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value returned from <code>get</code> if the property is not
+ found.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(int)">delete</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes a property from this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(java.lang.String)">delete</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes a property from this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)">get</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a property from the object selected by an integral index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get a named property from the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()">getClassName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the name of the set of objects implemented by this Java class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#getDefaultValue(java.lang.Class)">getDefaultValue</A></B>(java.lang.Class&nbsp;hint)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the default value of the object with a given hint.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#getIds()">getIds</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get an array of property ids.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#getParentScope()">getParentScope</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the parent scope of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#getPrototype()">getPrototype</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the prototype of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)">has</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether or not an indexed property is defined in an object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Indicates whether or not a named property is defined in an object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#hasInstance(org.mozilla.javascript.Scriptable)">hasInstance</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;instance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The instanceof operator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets an indexed property in this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets a named property in this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;parent)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the parent scope of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the prototype of the object.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="NOT_FOUND"><!-- --></A><H3>
+NOT_FOUND</H3>
+<PRE>
+static final java.lang.Object <B>NOT_FOUND</B></PRE>
+<DL>
+<DD>Value returned from <code>get</code> if the property is not
+ found.
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getClassName()"><!-- --></A><H3>
+getClassName</H3>
+<PRE>
+java.lang.String <B>getClassName</B>()</PRE>
+<DL>
+<DD>Get the name of the set of objects implemented by this Java class.
+ This corresponds to the [[Class]] operation in ECMA and is used
+ by Object.prototype.toString() in ECMA.<p>
+ See ECMA 8.6.2 and 15.2.4.2.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+java.lang.Object <B>get</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Get a named property from the object.
+
+ Looks property up in this object and returns the associated value
+ if found. Returns NOT_FOUND if not found.
+ Note that this method is not expected to traverse the prototype
+ chain. This is different from the ECMA [[Get]] operation.
+
+ Depending on the property selector, the runtime will call
+ this method or the form of <code>get</code> that takes an
+ integer:
+ <table>
+ <tr><th>JavaScript code</th><th>Java code</th></tr>
+ <tr><td>a.b </td><td>a.get("b", a)</td></tr>
+ <tr><td>a["foo"] </td><td>a.get("foo", a)</td></tr>
+ <tr><td>a[3] </td><td>a.get(3, a)</td></tr>
+ <tr><td>a["3"] </td><td>a.get(3, a)</td></tr>
+ <tr><td>a[3.0] </td><td>a.get(3, a)</td></tr>
+ <tr><td>a["3.0"] </td><td>a.get("3.0", a)</td></tr>
+ <tr><td>a[1.1] </td><td>a.get("1.1", a)</td></tr>
+ <tr><td>a[-4] </td><td>a.get(-4, a)</td></tr>
+ </table>
+ <p>
+ The values that may be returned are limited to the following:
+ <UL>
+ <LI>java.lang.Boolean objects</LI>
+ <LI>java.lang.String objects</LI>
+ <LI>java.lang.Number objects</LI>
+ <LI>org.mozilla.javascript.Scriptable objects</LI>
+ <LI>null</LI>
+ <LI>The value returned by Context.getUndefinedValue()</LI>
+ <LI>NOT_FOUND</LI>
+ </UL>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>the value of the property (may be null), or NOT_FOUND<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getUndefinedValue()"><CODE>Context.getUndefinedValue()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(int, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+java.lang.Object <B>get</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Get a property from the object selected by an integral index.
+
+ Identical to <code>get(String, Scriptable)</code> except that
+ an integral index is used to select the property.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>the value of the property (may be null), or NOT_FOUND<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>get(String,Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="has(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+has</H3>
+<PRE>
+boolean <B>has</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Indicates whether or not a named property is defined in an object.
+
+ Does not traverse the prototype chain.<p>
+
+ The property is specified by a String name
+ as defined for the <code>get</code> method.<p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>true if and only if the named property is found in the object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><CODE>ScriptableObject.getProperty(Scriptable, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="has(int, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+has</H3>
+<PRE>
+boolean <B>has</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Indicates whether or not an indexed property is defined in an object.
+
+ Does not traverse the prototype chain.<p>
+
+ The property is specified by an integral index
+ as defined for the <code>get</code> method.<p>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>true if and only if the indexed property is found in the object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)"><CODE>ScriptableObject.getProperty(Scriptable, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+put</H3>
+<PRE>
+void <B>put</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Sets a named property in this object.
+ <p>
+ The property is specified by a string name
+ as defined for <code>get</code>.
+ <p>
+ The possible values that may be passed in are as defined for
+ <code>get</code>. A class that implements this method may choose
+ to ignore calls to set certain properties, in which case those
+ properties are effectively read-only.<p>
+ For properties defined in a prototype chain,
+ use <code>putProperty</code> in ScriptableObject. <p>
+ Note that if a property <i>a</i> is defined in the prototype <i>p</i>
+ of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
+ <code>set</code> to be called on the prototype <i>p</i> with
+ <i>o</i> as the <i>start</i> parameter.
+ To preserve JavaScript semantics, it is the Scriptable
+ object's responsibility to modify <i>o</i>. <p>
+ This design allows properties to be defined in prototypes and implemented
+ in terms of getters and setters of Java values without consuming slots
+ in each instance.<p>
+ <p>
+ The values that may be set are limited to the following:
+ <UL>
+ <LI>java.lang.Boolean objects</LI>
+ <LI>java.lang.String objects</LI>
+ <LI>java.lang.Number objects</LI>
+ <LI>org.mozilla.javascript.Scriptable objects</LI>
+ <LI>null</LI>
+ <LI>The value returned by Context.getUndefinedValue()</LI>
+ </UL><p>
+ Arbitrary Java objects may be wrapped in a Scriptable by first calling
+ <code>Context.toObject</code>. This allows the property of a JavaScript
+ object to contain an arbitrary Java object as a value.<p>
+ Note that <code>has</code> will be called by the runtime first before
+ <code>set</code> is called to determine in which object the
+ property is defined.
+ Note that this method is not expected to traverse the prototype chain,
+ which is different from the ECMA [[Put]] operation.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object whose property is being set<DD><CODE>value</CODE> - value to set the property to<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><CODE>ScriptableObject.putProperty(Scriptable, String, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>Context.toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="put(int, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+put</H3>
+<PRE>
+void <B>put</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Sets an indexed property in this object.
+ <p>
+ The property is specified by an integral index
+ as defined for <code>get</code>.<p>
+
+ Identical to <code>put(String, Scriptable, Object)</code> except that
+ an integral index is used to select the property.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object whose property is being set<DD><CODE>value</CODE> - value to set the property to<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)"><CODE>has(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)"><CODE>ScriptableObject.putProperty(Scriptable, int, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>Context.toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="delete(java.lang.String)"><!-- --></A><H3>
+delete</H3>
+<PRE>
+void <B>delete</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Removes a property from this object.
+ This operation corresponds to the ECMA [[Delete]] except that
+ the no result is returned. The runtime will guarantee that this
+ method is called only if the property exists. After this method
+ is called, the runtime will call Scriptable.has to see if the
+ property has been removed in order to determine the boolean
+ result of the delete operator as defined by ECMA 11.4.1.
+ <p>
+ A property can be made permanent by ignoring calls to remove
+ it.<p>
+ The property is specified by a String name
+ as defined for <code>get</code>.
+ <p>
+ To delete properties defined in a prototype chain,
+ see deleteProperty in ScriptableObject.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the identifier for the property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><CODE>ScriptableObject.deleteProperty(Scriptable, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="delete(int)"><!-- --></A><H3>
+delete</H3>
+<PRE>
+void <B>delete</B>(int&nbsp;index)</PRE>
+<DL>
+<DD>Removes a property from this object.
+
+ The property is specified by an integral index
+ as defined for <code>get</code>.
+ <p>
+ To delete properties defined in a prototype chain,
+ see deleteProperty in ScriptableObject.
+
+ Identical to <code>delete(String)</code> except that
+ an integral index is used to select the property.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)"><CODE>ScriptableObject.deleteProperty(Scriptable, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPrototype()"><!-- --></A><H3>
+getPrototype</H3>
+<PRE>
+<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getPrototype</B>()</PRE>
+<DL>
+<DD>Get the prototype of the object.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the prototype</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPrototype(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+setPrototype</H3>
+<PRE>
+void <B>setPrototype</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</PRE>
+<DL>
+<DD>Set the prototype of the object.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>prototype</CODE> - the prototype to set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParentScope()"><!-- --></A><H3>
+getParentScope</H3>
+<PRE>
+<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getParentScope</B>()</PRE>
+<DL>
+<DD>Get the parent scope of the object.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the parent scope</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setParentScope(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+setParentScope</H3>
+<PRE>
+void <B>setParentScope</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;parent)</PRE>
+<DL>
+<DD>Set the parent scope of the object.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parent</CODE> - the parent scope to set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getIds()"><!-- --></A><H3>
+getIds</H3>
+<PRE>
+java.lang.Object[] <B>getIds</B>()</PRE>
+<DL>
+<DD>Get an array of property ids.
+
+ Not all property ids need be returned. Those properties
+ whose ids are not returned are considered non-enumerable.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of Objects. Each entry in the array is either
+ a java.lang.String or a java.lang.Number</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultValue(java.lang.Class)"><!-- --></A><H3>
+getDefaultValue</H3>
+<PRE>
+java.lang.Object <B>getDefaultValue</B>(java.lang.Class&nbsp;hint)</PRE>
+<DL>
+<DD>Get the default value of the object with a given hint.
+ The hints are String.class for type String, Number.class for type
+ Number, Scriptable.class for type Object, and Boolean.class for
+ type Boolean. <p>
+
+ A <code>hint</code> of null means "no hint".
+
+ See ECMA 8.6.2.6.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>hint</CODE> - the type hint
+<DT><B>Returns:</B><DD>the default value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasInstance(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+hasInstance</H3>
+<PRE>
+boolean <B>hasInstance</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;instance)</PRE>
+<DL>
+<DD>The instanceof operator.
+
+ <p>
+ The JavaScript code "lhs instanceof rhs" causes rhs.hasInstance(lhs) to
+ be called.
+
+ <p>
+ The return value is implementation dependent so that embedded host objects can
+ return an appropriate value. See the JS 1.3 language documentation for more
+ detail.
+
+ <p>This operator corresponds to the proposed EMCA [[HasInstance]] operator.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instance</CODE> - The value that appeared on the LHS of the instanceof
+ operator
+<DT><B>Returns:</B><DD>an implementation dependent value</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Scriptable.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Scriptable.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ScriptableObject.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ScriptableObject.html
new file mode 100644
index 0000000..fce83d6
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/ScriptableObject.html
@@ -0,0 +1,2604 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ScriptableObject (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ScriptableObject (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ScriptableObject.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableObject.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class ScriptableObject</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.ScriptableObject</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable, org.mozilla.javascript.ConstProperties, org.mozilla.javascript.debug.DebuggableObject, <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD>org.mozilla.javascript.IdScriptableObject</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public abstract class <B>ScriptableObject</B><DT>extends java.lang.Object<DT>implements <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>, java.io.Serializable, org.mozilla.javascript.debug.DebuggableObject, org.mozilla.javascript.ConstProperties</DL>
+</PRE>
+
+<P>
+This is the default implementation of the Scriptable interface. This
+ class provides convenient default behavior that makes it easier to
+ define host objects.
+ <p>
+ Various properties and methods of JavaScript objects can be conveniently
+ defined using methods of ScriptableObject.
+ <p>
+ Classes extending ScriptableObject must define the getClassName method.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A>,
+<A HREF="../../../serialized-form.html#org.mozilla.javascript.ScriptableObject">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#CONST">CONST</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM">DONTENUM</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Property attribute indicating property is not enumerated.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY">EMPTY</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The empty property attribute.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT">PERMANENT</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Property attribute indicating property cannot be deleted.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY">READONLY</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Property attribute indicating assignment to this property is ignored.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#UNINITIALIZED_CONST">UNINITIALIZED_CONST</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Property attribute indicating that this is a const property that has not
+ been assigned yet.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#ScriptableObject()">ScriptableObject</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#ScriptableObject(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)">ScriptableObject</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#associateValue(java.lang.Object, java.lang.Object)">associateValue</A></B>(java.lang.Object&nbsp;key,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Associate arbitrary application-specific value with this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#avoidObjectDetection()">avoidObjectDetection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Emulate the SpiderMonkey (and Firefox) feature of allowing
+ custom objects to avoid detection by normal "object detection"
+ code patterns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;methodName,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call a method of an object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#callMethod(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])">callMethod</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;methodName,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call a method of an object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)">defineClass</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Defines JavaScript objects from a Java class that implements Scriptable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean)">defineClass</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz,
+ boolean&nbsp;sealed)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Defines JavaScript objects from a Java class, optionally
+ allowing sealing.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean, boolean)">defineClass</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz,
+ boolean&nbsp;sealed,
+ boolean&nbsp;mapInheritance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Defines JavaScript objects from a Java class, optionally
+ allowing sealing and mapping of Java inheritance to JavaScript
+ prototype-based inheritance.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConst(java.lang.String, org.mozilla.javascript.Scriptable)">defineConst</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reserves a definition spot for a const.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineConstProperty(org.mozilla.javascript.Scriptable, java.lang.String)">defineConstProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;destination,
+ java.lang.String&nbsp;propertyName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utility method to add properties to arbitrary Scriptable object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineFunctionProperties(java.lang.String[], java.lang.Class, int)">defineFunctionProperties</A></B>(java.lang.String[]&nbsp;names,
+ java.lang.Class&nbsp;clazz,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Search for names in a class, adding the resulting methods
+ as properties.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object, int)">defineProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;destination,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;value,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Utility method to add properties to arbitrary Scriptable object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Class, int)">defineProperty</A></B>(java.lang.String&nbsp;propertyName,
+ java.lang.Class&nbsp;clazz,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Define a JavaScript property with getter and setter side effects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, int)">defineProperty</A></B>(java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;value,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Define a JavaScript property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#defineProperty(java.lang.String, java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, int)">defineProperty</A></B>(java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;delegateTo,
+ java.lang.reflect.Method&nbsp;getter,
+ java.lang.reflect.Method&nbsp;setter,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Define a JavaScript property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#delete(int)">delete</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes the indexed property from the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#delete(java.lang.String)">delete</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes a named property from the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)">deleteProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes the property from an object or its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)">deleteProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes the property from an object or its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#equivalentValues(java.lang.Object)">equivalentValues</A></B>(java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Custom <tt>==</tt> operator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#get(int, org.mozilla.javascript.Scriptable)">get</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the value of the indexed property or NOT_FOUND.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the value of the named property or NOT_FOUND.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAllIds()">getAllIds</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array of ids for the properties of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)">getAssociatedValue</A></B>(java.lang.Object&nbsp;key)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get arbitrary application-specific value associated with this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int)">getAttributes</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the attributes of an indexed property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int, org.mozilla.javascript.Scriptable)">getAttributes</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int)"><CODE>getAttributes(int index)</CODE></A>. The engine always
+ ignored the start argument.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)">getAttributes</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the attributes of a named property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)">getAttributes</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String name)</CODE></A>. The engine always
+ ignored the start argument.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>abstract &nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassName()">getClassName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return the name of the class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getClassPrototype(org.mozilla.javascript.Scriptable, java.lang.String)">getClassPrototype</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;className)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the prototype for the named class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(java.lang.Class)">getDefaultValue</A></B>(java.lang.Class&nbsp;typeHint)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implements the [[DefaultValue]] internal method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getDefaultValue(org.mozilla.javascript.Scriptable, java.lang.Class)">getDefaultValue</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;object,
+ java.lang.Class&nbsp;typeHint)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getFunctionPrototype(org.mozilla.javascript.Scriptable)">getFunctionPrototype</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the Function.prototype property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getGetterOrSetter(java.lang.String, int, boolean)">getGetterOrSetter</A></B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ boolean&nbsp;isSetter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the getter or setter for a given property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getIds()">getIds</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array of ids for the properties of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getObjectPrototype(org.mozilla.javascript.Scriptable)">getObjectPrototype</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the Object.prototype property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getParentScope()">getParentScope</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the parent (enclosing) scope of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)">getProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets an indexed property from an object or any object in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)">getProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets a named property from an object or any object in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPropertyIds(org.mozilla.javascript.Scriptable)">getPropertyIds</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an array of all ids from an object and its prototypes.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getPrototype()">getPrototype</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the prototype of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)">getTopLevelScope</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the global scope.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopScopeValue(org.mozilla.javascript.Scriptable, java.lang.Object)">getTopScopeValue</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;key)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get arbitrary application-specific value associated with the top scope
+ of the given scope.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(int, org.mozilla.javascript.Scriptable)">has</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the property index is defined.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the named property is defined.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasInstance(org.mozilla.javascript.Scriptable)">hasInstance</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;instance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Implements the instanceof operator.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, int)">hasProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns whether an indexed property is defined in an object or any object
+ in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#hasProperty(org.mozilla.javascript.Scriptable, java.lang.String)">hasProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns whether a named property is defined in an object or any object
+ in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isConst(java.lang.String)">isConst</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the named property is defined as a const on this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isGetterOrSetter(java.lang.String, int, boolean)">isGetterOrSetter</A></B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ boolean&nbsp;setter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns whether a property is a getter or a setter</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#isSealed()">isSealed</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return true if this object is sealed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the indexed property, creating it if need be.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the named property, creating it if need be.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConst(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">putConst</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the value of the named const property, creating it if need be.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putConstProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putConstProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Puts a named property in an object or in an object in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)">putProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Puts an indexed property in an object or in an object in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)">putProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ java.lang.Object&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Puts a named property in an object or in an object in its prototype chain.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#redefineProperty(org.mozilla.javascript.Scriptable, java.lang.String, boolean)">redefineProperty</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ boolean&nbsp;isConst)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If hasProperty(obj, name) would return true, then if the property that
+ was found is compatible with the new property, this method just returns.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#sealObject()">sealObject</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Seal this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)">setAttributes</A></B>(int&nbsp;index,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the attributes of an indexed property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, org.mozilla.javascript.Scriptable, int)">setAttributes</A></B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)"><CODE>setAttributes(int index, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)">setAttributes</A></B>(java.lang.String&nbsp;name,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the attributes of a named property.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)">setAttributes</A></B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ int&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String name, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setGetterOrSetter(java.lang.String, int, org.mozilla.javascript.Callable, boolean)">setGetterOrSetter</A></B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;getterOrSeter,
+ boolean&nbsp;isSetter)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XXX: write docs.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;m)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the parent (enclosing) scope of the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;m)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the prototype of the object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="EMPTY"><!-- --></A><H3>
+EMPTY</H3>
+<PRE>
+public static final int <B>EMPTY</B></PRE>
+<DL>
+<DD>The empty property attribute.
+
+ Used by getAttributes() and setAttributes().
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String, int)</CODE></A>,
+<A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.EMPTY">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="READONLY"><!-- --></A><H3>
+READONLY</H3>
+<PRE>
+public static final int <B>READONLY</B></PRE>
+<DL>
+<DD>Property attribute indicating assignment to this property is ignored.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><CODE>#put(String, Scriptable, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String, int)</CODE></A>,
+<A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.READONLY">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="DONTENUM"><!-- --></A><H3>
+DONTENUM</H3>
+<PRE>
+public static final int <B>DONTENUM</B></PRE>
+<DL>
+<DD>Property attribute indicating property is not enumerated.
+
+ Only enumerated properties will be returned by getIds().
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getIds()"><CODE>getIds()</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String, int)</CODE></A>,
+<A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.DONTENUM">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="PERMANENT"><!-- --></A><H3>
+PERMANENT</H3>
+<PRE>
+public static final int <B>PERMANENT</B></PRE>
+<DL>
+<DD>Property attribute indicating property cannot be deleted.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#delete(java.lang.String)"><CODE>delete(String)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String, int)</CODE></A>,
+<A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.PERMANENT">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="UNINITIALIZED_CONST"><!-- --></A><H3>
+UNINITIALIZED_CONST</H3>
+<PRE>
+public static final int <B>UNINITIALIZED_CONST</B></PRE>
+<DL>
+<DD>Property attribute indicating that this is a const property that has not
+ been assigned yet. The first 'const' assignment to the property will
+ clear this bit.
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.UNINITIALIZED_CONST">Constant Field Values</A></DL>
+</DL>
+<HR>
+
+<A NAME="CONST"><!-- --></A><H3>
+CONST</H3>
+<PRE>
+public static final int <B>CONST</B></PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../constant-values.html#org.mozilla.javascript.ScriptableObject.CONST">Constant Field Values</A></DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ScriptableObject()"><!-- --></A><H3>
+ScriptableObject</H3>
+<PRE>
+public <B>ScriptableObject</B>()</PRE>
+<DL>
+</DL>
+<HR>
+
+<A NAME="ScriptableObject(org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+ScriptableObject</H3>
+<PRE>
+public <B>ScriptableObject</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;prototype)</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getClassName()"><!-- --></A><H3>
+getClassName</H3>
+<PRE>
+public abstract java.lang.String <B>getClassName</B>()</PRE>
+<DL>
+<DD>Return the name of the class.
+
+ This is typically the same name as the constructor.
+ Classes extending ScriptableObject must implement this abstract
+ method.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getClassName()">getClassName</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="has(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+has</H3>
+<PRE>
+public boolean <B>has</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Returns true if the named property is defined.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)">has</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>true if and only if the property was found in the object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><CODE>getProperty(Scriptable, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="has(int, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+has</H3>
+<PRE>
+public boolean <B>has</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Returns true if the property index is defined.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)">has</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>true if and only if the property was found in the object<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getProperty(org.mozilla.javascript.Scriptable, int)"><CODE>getProperty(Scriptable, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+public java.lang.Object <B>get</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Returns the value of the named property or NOT_FOUND.
+
+ If the property was created using defineProperty, the
+ appropriate getter method is called.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)">get</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>the value of the property (may be null), or NOT_FOUND<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getUndefinedValue()"><CODE>Context.getUndefinedValue()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(int, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+get</H3>
+<PRE>
+public java.lang.Object <B>get</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD>Returns the value of the indexed property or NOT_FOUND.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)">get</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object in which the lookup began
+<DT><B>Returns:</B><DD>the value of the property (may be null), or NOT_FOUND<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String,Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+put</H3>
+<PRE>
+public void <B>put</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Sets the value of the named property, creating it if need be.
+
+ If the property was created using defineProperty, the
+ appropriate setter method is called. <p>
+
+ If the property's attributes include READONLY, no action is
+ taken.
+ This method will actually set the property in the start
+ object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object whose property is being set<DD><CODE>value</CODE> - value to set the property to<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><CODE>putProperty(Scriptable, String, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>Context.toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="put(int, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+put</H3>
+<PRE>
+public void <B>put</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Sets the value of the indexed property, creating it if need be.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)">put</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>start</CODE> - the object whose property is being set<DD><CODE>value</CODE> - value to set the property to<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(int, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.has(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)"><CODE>putProperty(Scriptable, int, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>Context.toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="delete(java.lang.String)"><!-- --></A><H3>
+delete</H3>
+<PRE>
+public void <B>delete</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Removes a named property from the object.
+
+ If the property is not found, or it has the PERMANENT attribute,
+ no action is taken.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(java.lang.String)">delete</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><CODE>deleteProperty(Scriptable, String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="delete(int)"><!-- --></A><H3>
+delete</H3>
+<PRE>
+public void <B>delete</B>(int&nbsp;index)</PRE>
+<DL>
+<DD>Removes the indexed property from the object.
+
+ If the property is not found, or it has the PERMANENT attribute,
+ no action is taken.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#delete(int)">delete</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#get(int, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(int, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#deleteProperty(org.mozilla.javascript.Scriptable, int)"><CODE>deleteProperty(Scriptable, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putConst(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+putConst</H3>
+<PRE>
+public void <B>putConst</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Sets the value of the named const property, creating it if need be.
+
+ If the property was created using defineProperty, the
+ appropriate setter method is called. <p>
+
+ If the property's attributes include READONLY, no action is
+ taken.
+ This method will actually set the property in the start
+ object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>putConst</CODE> in interface <CODE>org.mozilla.javascript.ConstProperties</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>start</CODE> - the object whose property is being set<DD><CODE>value</CODE> - value to set the property to<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Scriptable.html#get(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.get(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><CODE>putProperty(Scriptable, String, Object)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/Context.html#toObject(java.lang.Object, org.mozilla.javascript.Scriptable)"><CODE>Context.toObject(Object, Scriptable)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineConst(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+defineConst</H3>
+<PRE>
+public void <B>defineConst</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE>org.mozilla.javascript.ConstProperties</CODE></B></DD>
+<DD>Reserves a definition spot for a const. This will set up a definition
+ of the const property, but set its value to undefined. The semantics of
+ the start parameter is the same as for putConst.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>defineConst</CODE> in interface <CODE>org.mozilla.javascript.ConstProperties</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - The name of the property.<DD><CODE>start</CODE> - The object whose property is being reserved.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isConst(java.lang.String)"><!-- --></A><H3>
+isConst</H3>
+<PRE>
+public boolean <B>isConst</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Returns true if the named property is defined as a const on this object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>isConst</CODE> in interface <CODE>org.mozilla.javascript.ConstProperties</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> -
+<DT><B>Returns:</B><DD>true if the named property is defined as a const, false
+ otherwise.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributes(java.lang.String, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getAttributes</H3>
+<PRE>
+public final int <B>getAttributes</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(java.lang.String)"><CODE>getAttributes(String name)</CODE></A>. The engine always
+ ignored the start argument.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributes(int, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getAttributes</H3>
+<PRE>
+public final int <B>getAttributes</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAttributes(int)"><CODE>getAttributes(int index)</CODE></A>. The engine always
+ ignored the start argument.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributes(java.lang.String, org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+setAttributes</H3>
+<PRE>
+public final void <B>setAttributes</B>(java.lang.String&nbsp;name,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(java.lang.String, int)"><CODE>setAttributes(String name, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributes(int, org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+setAttributes</H3>
+<PRE>
+public void <B>setAttributes</B>(int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;start,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#setAttributes(int, int)"><CODE>setAttributes(int index, int attributes)</CODE></A>.
+ The engine always ignored the start argument.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributes(java.lang.String)"><!-- --></A><H3>
+getAttributes</H3>
+<PRE>
+public int <B>getAttributes</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Get the attributes of a named property.
+
+ The property is specified by <code>name</code>
+ as defined for <code>has</code>.<p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the identifier for the property
+<DT><B>Returns:</B><DD>the bitset of attributes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE> - if the named property is not found<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY"><CODE>READONLY</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM"><CODE>DONTENUM</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT"><CODE>PERMANENT</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY"><CODE>EMPTY</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributes(int)"><!-- --></A><H3>
+getAttributes</H3>
+<PRE>
+public int <B>getAttributes</B>(int&nbsp;index)</PRE>
+<DL>
+<DD>Get the attributes of an indexed property.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property
+<DT><B>Returns:</B><DD>the bitset of attributes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE> - if the named property is not found
+ is not found<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY"><CODE>READONLY</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM"><CODE>DONTENUM</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT"><CODE>PERMANENT</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY"><CODE>EMPTY</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributes(java.lang.String, int)"><!-- --></A><H3>
+setAttributes</H3>
+<PRE>
+public void <B>setAttributes</B>(java.lang.String&nbsp;name,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Set the attributes of a named property.
+
+ The property is specified by <code>name</code>
+ as defined for <code>has</code>.<p>
+
+ The possible attributes are READONLY, DONTENUM,
+ and PERMANENT. Combinations of attributes
+ are expressed by the bitwise OR of attributes.
+ EMPTY is the state of no attributes set. Any unused
+ bits are reserved for future use.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - the name of the property<DD><CODE>attributes</CODE> - the bitset of attributes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE> - if the named property is not found<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY"><CODE>READONLY</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM"><CODE>DONTENUM</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT"><CODE>PERMANENT</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY"><CODE>EMPTY</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributes(int, int)"><!-- --></A><H3>
+setAttributes</H3>
+<PRE>
+public void <B>setAttributes</B>(int&nbsp;index,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Set the attributes of an indexed property.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the numeric index for the property<DD><CODE>attributes</CODE> - the bitset of attributes
+<DT><B>Throws:</B>
+<DD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></CODE> - if the named property is not found<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#has(java.lang.String, org.mozilla.javascript.Scriptable)"><CODE>Scriptable.has(String, Scriptable)</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY"><CODE>READONLY</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#DONTENUM"><CODE>DONTENUM</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#PERMANENT"><CODE>PERMANENT</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#EMPTY"><CODE>EMPTY</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setGetterOrSetter(java.lang.String, int, org.mozilla.javascript.Callable, boolean)"><!-- --></A><H3>
+setGetterOrSetter</H3>
+<PRE>
+public void <B>setGetterOrSetter</B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;getterOrSeter,
+ boolean&nbsp;isSetter)</PRE>
+<DL>
+<DD>XXX: write docs.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getGetterOrSetter(java.lang.String, int, boolean)"><!-- --></A><H3>
+getGetterOrSetter</H3>
+<PRE>
+public java.lang.Object <B>getGetterOrSetter</B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ boolean&nbsp;isSetter)</PRE>
+<DL>
+<DD>Get the getter or setter for a given property. Used by __lookupGetter__
+ and __lookupSetter__.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - Name of the object. If nonnull, index must be 0.<DD><CODE>index</CODE> - Index of the object. If nonzero, name must be null.<DD><CODE>isSetter</CODE> - If true, return the setter, otherwise return the getter.
+<DT><B>Returns:</B><DD>Null if the property does not exist. Otherwise returns either
+ the getter or the setter for the property, depending on
+ the value of isSetter (may be undefined if unset).
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if both name and index are nonnull
+ and nonzero respectively.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGetterOrSetter(java.lang.String, int, boolean)"><!-- --></A><H3>
+isGetterOrSetter</H3>
+<PRE>
+protected boolean <B>isGetterOrSetter</B>(java.lang.String&nbsp;name,
+ int&nbsp;index,
+ boolean&nbsp;setter)</PRE>
+<DL>
+<DD>Returns whether a property is a getter or a setter
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - property name<DD><CODE>index</CODE> - property index<DD><CODE>setter</CODE> - true to check for a setter, false for a getter
+<DT><B>Returns:</B><DD>whether the property is a getter or a setter</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPrototype()"><!-- --></A><H3>
+getPrototype</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getPrototype</B>()</PRE>
+<DL>
+<DD>Returns the prototype of the object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getPrototype()">getPrototype</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the prototype</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setPrototype(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+setPrototype</H3>
+<PRE>
+public void <B>setPrototype</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;m)</PRE>
+<DL>
+<DD>Sets the prototype of the object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#setPrototype(org.mozilla.javascript.Scriptable)">setPrototype</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>m</CODE> - the prototype to set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParentScope()"><!-- --></A><H3>
+getParentScope</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getParentScope</B>()</PRE>
+<DL>
+<DD>Returns the parent (enclosing) scope of the object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getParentScope()">getParentScope</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the parent scope</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setParentScope(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+setParentScope</H3>
+<PRE>
+public void <B>setParentScope</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;m)</PRE>
+<DL>
+<DD>Sets the parent (enclosing) scope of the object.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#setParentScope(org.mozilla.javascript.Scriptable)">setParentScope</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>m</CODE> - the parent scope to set</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getIds()"><!-- --></A><H3>
+getIds</H3>
+<PRE>
+public java.lang.Object[] <B>getIds</B>()</PRE>
+<DL>
+<DD>Returns an array of ids for the properties of the object.
+
+ <p>Any properties with the attribute DONTENUM are not listed. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getIds()">getIds</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of java.lang.Objects with an entry for every
+ listed property. Properties accessed via an integer index will
+ have a corresponding
+ Integer entry in the returned array. Properties accessed by
+ a String will have a String entry in the returned array.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAllIds()"><!-- --></A><H3>
+getAllIds</H3>
+<PRE>
+public java.lang.Object[] <B>getAllIds</B>()</PRE>
+<DL>
+<DD>Returns an array of ids for the properties of the object.
+
+ <p>All properties, even those with attribute DONTENUM, are listed. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>getAllIds</CODE> in interface <CODE>org.mozilla.javascript.debug.DebuggableObject</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of java.lang.Objects with an entry for every
+ listed property. Properties accessed via an integer index will
+ have a corresponding
+ Integer entry in the returned array. Properties accessed by
+ a String will have a String entry in the returned array.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultValue(java.lang.Class)"><!-- --></A><H3>
+getDefaultValue</H3>
+<PRE>
+public java.lang.Object <B>getDefaultValue</B>(java.lang.Class&nbsp;typeHint)</PRE>
+<DL>
+<DD>Implements the [[DefaultValue]] internal method.
+
+ <p>Note that the toPrimitive conversion is a no-op for
+ every type other than Object, for which [[DefaultValue]]
+ is called. See ECMA 9.1.<p>
+
+ A <code>hint</code> of null means "no hint".
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#getDefaultValue(java.lang.Class)">getDefaultValue</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>typeHint</CODE> - the type hint
+<DT><B>Returns:</B><DD>the default value for the object
+
+ See ECMA 8.6.2.6.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDefaultValue(org.mozilla.javascript.Scriptable, java.lang.Class)"><!-- --></A><H3>
+getDefaultValue</H3>
+<PRE>
+public static java.lang.Object <B>getDefaultValue</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;object,
+ java.lang.Class&nbsp;typeHint)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasInstance(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+hasInstance</H3>
+<PRE>
+public boolean <B>hasInstance</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;instance)</PRE>
+<DL>
+<DD>Implements the instanceof operator.
+
+ <p>This operator has been proposed to ECMA.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#hasInstance(org.mozilla.javascript.Scriptable)">hasInstance</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instance</CODE> - The value that appeared on the LHS of the instanceof
+ operator
+<DT><B>Returns:</B><DD>true if "this" appears in value's prototype chain</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="avoidObjectDetection()"><!-- --></A><H3>
+avoidObjectDetection</H3>
+<PRE>
+public boolean <B>avoidObjectDetection</B>()</PRE>
+<DL>
+<DD>Emulate the SpiderMonkey (and Firefox) feature of allowing
+ custom objects to avoid detection by normal "object detection"
+ code patterns. This is used to implement document.all.
+ See https://bugzilla.mozilla.org/show_bug.cgi?id=412247.
+ This is an analog to JOF_DETECTING from SpiderMonkey; see
+ https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
+ Other than this special case, embeddings should return false.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if this object should avoid object detection<DT><B>Since:</B></DT>
+ <DD>1.7R1</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="equivalentValues(java.lang.Object)"><!-- --></A><H3>
+equivalentValues</H3>
+<PRE>
+protected java.lang.Object <B>equivalentValues</B>(java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Custom <tt>==</tt> operator.
+ Must return <A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND"><CODE>Scriptable.NOT_FOUND</CODE></A> if this object does not
+ have custom equality operator for the given value,
+ <tt>Boolean.TRUE</tt> if this object is equivalent to <tt>value</tt>,
+ <tt>Boolean.FALSE</tt> if this object is not equivalent to
+ <tt>value</tt>.
+ <p>
+ The default implementation returns Boolean.TRUE
+ if <tt>this == value</tt> or <A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND"><CODE>Scriptable.NOT_FOUND</CODE></A> otherwise.
+ It indicates that by default custom equality is available only if
+ <tt>value</tt> is <tt>this</tt> in which case true is returned.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineClass(org.mozilla.javascript.Scriptable, java.lang.Class)"><!-- --></A><H3>
+defineClass</H3>
+<PRE>
+public static void <B>defineClass</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz)
+ throws java.lang.IllegalAccessException,
+ java.lang.InstantiationException,
+ java.lang.reflect.InvocationTargetException</PRE>
+<DL>
+<DD>Defines JavaScript objects from a Java class that implements Scriptable.
+
+ If the given class has a method
+ <pre>
+ static void init(Context cx, Scriptable scope, boolean sealed);</pre>
+
+ or its compatibility form
+ <pre>
+ static void init(Scriptable scope);</pre>
+
+ then it is invoked and no further initialization is done.<p>
+
+ However, if no such a method is found, then the class's constructors and
+ methods are used to initialize a class in the following manner.<p>
+
+ First, the zero-parameter constructor of the class is called to
+ create the prototype. If no such constructor exists,
+ a <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A> is thrown. <p>
+
+ Next, all methods are scanned for special prefixes that indicate that they
+ have special meaning for defining JavaScript objects.
+ These special prefixes are
+ <ul>
+ <li><code>jsFunction_</code> for a JavaScript function
+ <li><code>jsStaticFunction_</code> for a JavaScript function that
+ is a property of the constructor
+ <li><code>jsGet_</code> for a getter of a JavaScript property
+ <li><code>jsSet_</code> for a setter of a JavaScript property
+ <li><code>jsConstructor</code> for a JavaScript function that
+ is the constructor
+ </ul><p>
+
+ If the method's name begins with "jsFunction_", a JavaScript function
+ is created with a name formed from the rest of the Java method name
+ following "jsFunction_". So a Java method named "jsFunction_foo" will
+ define a JavaScript method "foo". Calling this JavaScript function
+ will cause the Java method to be called. The parameters of the method
+ must be of number and types as defined by the FunctionObject class.
+ The JavaScript function is then added as a property
+ of the prototype. <p>
+
+ If the method's name begins with "jsStaticFunction_", it is handled
+ similarly except that the resulting JavaScript function is added as a
+ property of the constructor object. The Java method must be static.
+
+ If the method's name begins with "jsGet_" or "jsSet_", the method is
+ considered to define a property. Accesses to the defined property
+ will result in calls to these getter and setter methods. If no
+ setter is defined, the property is defined as READONLY.<p>
+
+ If the method's name is "jsConstructor", the method is
+ considered to define the body of the constructor. Only one
+ method of this name may be defined.
+ If no method is found that can serve as constructor, a Java
+ constructor will be selected to serve as the JavaScript
+ constructor in the following manner. If the class has only one
+ Java constructor, that constructor is used to define
+ the JavaScript constructor. If the the class has two constructors,
+ one must be the zero-argument constructor (otherwise an
+ <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A> would have already been thrown
+ when the prototype was to be created). In this case
+ the Java constructor with one or more parameters will be used
+ to define the JavaScript constructor. If the class has three
+ or more constructors, an <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><CODE>EvaluatorException</CODE></A>
+ will be thrown.<p>
+
+ Finally, if there is a method
+ <pre>
+ static void finishInit(Scriptable scope, FunctionObject constructor,
+ Scriptable prototype)</pre>
+
+ it will be called to finish any initialization. The <code>scope</code>
+ argument will be passed, along with the newly created constructor and
+ the newly created prototype.<p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - The scope in which to define the constructor.<DD><CODE>clazz</CODE> - The Java class to use to define the JavaScript objects
+ and properties.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalAccessException</CODE> - if access is not available
+ to a reflected class member
+<DD><CODE>java.lang.InstantiationException</CODE> - if unable to instantiate
+ the named class
+<DD><CODE>java.lang.reflect.InvocationTargetException</CODE> - if an exception is thrown
+ during execution of methods of the named class<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><CODE>Function</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><CODE>FunctionObject</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html#READONLY"><CODE>READONLY</CODE></A>,
+<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><CODE>#defineProperty(String, Class, int)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean)"><!-- --></A><H3>
+defineClass</H3>
+<PRE>
+public static void <B>defineClass</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz,
+ boolean&nbsp;sealed)
+ throws java.lang.IllegalAccessException,
+ java.lang.InstantiationException,
+ java.lang.reflect.InvocationTargetException</PRE>
+<DL>
+<DD>Defines JavaScript objects from a Java class, optionally
+ allowing sealing.
+
+ Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
+ except that sealing is allowed. An object that is sealed cannot have
+ properties added or removed. Note that sealing is not allowed in
+ the current ECMA/ISO language specification, but is likely for
+ the next version.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - The scope in which to define the constructor.<DD><CODE>clazz</CODE> - The Java class to use to define the JavaScript objects
+ and properties. The class must implement Scriptable.<DD><CODE>sealed</CODE> - Whether or not to create sealed standard objects that
+ cannot be modified.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalAccessException</CODE> - if access is not available
+ to a reflected class member
+<DD><CODE>java.lang.InstantiationException</CODE> - if unable to instantiate
+ the named class
+<DD><CODE>java.lang.reflect.InvocationTargetException</CODE> - if an exception is thrown
+ during execution of methods of the named class<DT><B>Since:</B></DT>
+ <DD>1.4R3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineClass(org.mozilla.javascript.Scriptable, java.lang.Class, boolean, boolean)"><!-- --></A><H3>
+defineClass</H3>
+<PRE>
+public static java.lang.String <B>defineClass</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Class&nbsp;clazz,
+ boolean&nbsp;sealed,
+ boolean&nbsp;mapInheritance)
+ throws java.lang.IllegalAccessException,
+ java.lang.InstantiationException,
+ java.lang.reflect.InvocationTargetException</PRE>
+<DL>
+<DD>Defines JavaScript objects from a Java class, optionally
+ allowing sealing and mapping of Java inheritance to JavaScript
+ prototype-based inheritance.
+
+ Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
+ except that sealing and inheritance mapping are allowed. An object
+ that is sealed cannot have properties added or removed. Note that
+ sealing is not allowed in the current ECMA/ISO language specification,
+ but is likely for the next version.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - The scope in which to define the constructor.<DD><CODE>clazz</CODE> - The Java class to use to define the JavaScript objects
+ and properties. The class must implement Scriptable.<DD><CODE>sealed</CODE> - Whether or not to create sealed standard objects that
+ cannot be modified.<DD><CODE>mapInheritance</CODE> - Whether or not to map Java inheritance to
+ JavaScript prototype-based inheritance.
+<DT><B>Returns:</B><DD>the class name for the prototype of the specified class
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalAccessException</CODE> - if access is not available
+ to a reflected class member
+<DD><CODE>java.lang.InstantiationException</CODE> - if unable to instantiate
+ the named class
+<DD><CODE>java.lang.reflect.InvocationTargetException</CODE> - if an exception is thrown
+ during execution of methods of the named class<DT><B>Since:</B></DT>
+ <DD>1.6R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineProperty(java.lang.String, java.lang.Object, int)"><!-- --></A><H3>
+defineProperty</H3>
+<PRE>
+public void <B>defineProperty</B>(java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;value,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Define a JavaScript property.
+
+ Creates the property with an initial value and sets its attributes.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>propertyName</CODE> - the name of the property to define.<DD><CODE>value</CODE> - the initial value of the property<DD><CODE>attributes</CODE> - the attributes of the JavaScript property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>Scriptable.put(String, Scriptable, Object)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object, int)"><!-- --></A><H3>
+defineProperty</H3>
+<PRE>
+public static void <B>defineProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;destination,
+ java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;value,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Utility method to add properties to arbitrary Scriptable object.
+ If destination is instance of ScriptableObject, calls
+ defineProperty there, otherwise calls put in destination
+ ignoring attributes
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineConstProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+defineConstProperty</H3>
+<PRE>
+public static void <B>defineConstProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;destination,
+ java.lang.String&nbsp;propertyName)</PRE>
+<DL>
+<DD>Utility method to add properties to arbitrary Scriptable object.
+ If destination is instance of ScriptableObject, calls
+ defineProperty there, otherwise calls put in destination
+ ignoring attributes
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineProperty(java.lang.String, java.lang.Class, int)"><!-- --></A><H3>
+defineProperty</H3>
+<PRE>
+public void <B>defineProperty</B>(java.lang.String&nbsp;propertyName,
+ java.lang.Class&nbsp;clazz,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Define a JavaScript property with getter and setter side effects.
+
+ If the setter is not found, the attribute READONLY is added to
+ the given attributes. <p>
+
+ The getter must be a method with zero parameters, and the setter, if
+ found, must be a method with one parameter.<p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>propertyName</CODE> - the name of the property to define. This name
+ also affects the name of the setter and getter
+ to search for. If the propertyId is "foo", then
+ <code>clazz</code> will be searched for "getFoo"
+ and "setFoo" methods.<DD><CODE>clazz</CODE> - the Java class to search for the getter and setter<DD><CODE>attributes</CODE> - the attributes of the JavaScript property<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>Scriptable.put(String, Scriptable, Object)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineProperty(java.lang.String, java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, int)"><!-- --></A><H3>
+defineProperty</H3>
+<PRE>
+public void <B>defineProperty</B>(java.lang.String&nbsp;propertyName,
+ java.lang.Object&nbsp;delegateTo,
+ java.lang.reflect.Method&nbsp;getter,
+ java.lang.reflect.Method&nbsp;setter,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Define a JavaScript property.
+
+ Use this method only if you wish to define getters and setters for
+ a given property in a ScriptableObject. To create a property without
+ special getter or setter side effects, use
+ <code>defineProperty(String,int)</code>.
+
+ If <code>setter</code> is null, the attribute READONLY is added to
+ the given attributes.<p>
+
+ Several forms of getters or setters are allowed. In all cases the
+ type of the value parameter can be any one of the following types:
+ Object, String, boolean, Scriptable, byte, short, int, long, float,
+ or double. The runtime will perform appropriate conversions based
+ upon the type of the parameter (see description in FunctionObject).
+ The first forms are nonstatic methods of the class referred to
+ by 'this':
+ <pre>
+ Object getFoo();
+ void setFoo(SomeType value);</pre>
+ Next are static methods that may be of any class; the object whose
+ property is being accessed is passed in as an extra argument:
+ <pre>
+ static Object getFoo(Scriptable obj);
+ static void setFoo(Scriptable obj, SomeType value);</pre>
+ Finally, it is possible to delegate to another object entirely using
+ the <code>delegateTo</code> parameter. In this case the methods are
+ nonstatic methods of the class delegated to, and the object whose
+ property is being accessed is passed in as an extra argument:
+ <pre>
+ Object getFoo(Scriptable obj);
+ void setFoo(Scriptable obj, SomeType value);</pre>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>propertyName</CODE> - the name of the property to define.<DD><CODE>delegateTo</CODE> - an object to call the getter and setter methods on,
+ or null, depending on the form used above.<DD><CODE>getter</CODE> - the method to invoke to get the value of the property<DD><CODE>setter</CODE> - the method to invoke to set the value of the property<DD><CODE>attributes</CODE> - the attributes of the JavaScript property</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="defineFunctionProperties(java.lang.String[], java.lang.Class, int)"><!-- --></A><H3>
+defineFunctionProperties</H3>
+<PRE>
+public void <B>defineFunctionProperties</B>(java.lang.String[]&nbsp;names,
+ java.lang.Class&nbsp;clazz,
+ int&nbsp;attributes)</PRE>
+<DL>
+<DD>Search for names in a class, adding the resulting methods
+ as properties.
+
+ <p> Uses reflection to find the methods of the given names. Then
+ FunctionObjects are constructed from the methods found, and
+ are added to this object as properties with the given names.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>names</CODE> - the names of the Methods to add as function properties<DD><CODE>clazz</CODE> - the class to search for the Methods<DD><CODE>attributes</CODE> - the attributes of the new properties<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><CODE>FunctionObject</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getObjectPrototype(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getObjectPrototype</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getObjectPrototype</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Get the Object.prototype property.
+ See ECMA 15.2.4.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctionPrototype(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getFunctionPrototype</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getFunctionPrototype</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</PRE>
+<DL>
+<DD>Get the Function.prototype property.
+ See ECMA 15.3.4.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getClassPrototype(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+getClassPrototype</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getClassPrototype</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.String&nbsp;className)</PRE>
+<DL>
+<DD>Get the prototype for the named class.
+
+ For example, <code>getClassPrototype(s, "Date")</code> will first
+ walk up the parent chain to find the outermost scope, then will
+ search that scope for the Date constructor, and then will
+ return Date.prototype. If any of the lookups fail, or
+ the prototype is not a JavaScript object, then null will
+ be returned.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - an object in the scope chain<DD><CODE>className</CODE> - the name of the constructor
+<DT><B>Returns:</B><DD>the prototype for the named class, or null if it
+ cannot be found.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTopLevelScope(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getTopLevelScope</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>getTopLevelScope</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</PRE>
+<DL>
+<DD>Get the global scope.
+
+ <p>Walks the parent scope chain to find an object with a null
+ parent scope (the global object).
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object
+<DT><B>Returns:</B><DD>the corresponding global scope</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="sealObject()"><!-- --></A><H3>
+sealObject</H3>
+<PRE>
+public void <B>sealObject</B>()</PRE>
+<DL>
+<DD>Seal this object.
+
+ A sealed object may not have properties added or removed. Once
+ an object is sealed it may not be unsealed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Since:</B></DT>
+ <DD>1.4R3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isSealed()"><!-- --></A><H3>
+isSealed</H3>
+<PRE>
+public final boolean <B>isSealed</B>()</PRE>
+<DL>
+<DD>Return true if this object is sealed.
+
+ It is an error to attempt to add or remove properties to
+ a sealed object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if sealed, false otherwise.<DT><B>Since:</B></DT>
+ <DD>1.4R3</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+getProperty</H3>
+<PRE>
+public static java.lang.Object <B>getProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Gets a named property from an object or any object in its prototype chain.
+ <p>
+ Searches the prototype chain for a property named <code>name</code>.
+ <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>name</CODE> - a property name
+<DT><B>Returns:</B><DD>the value of a property with name <code>name</code> found in
+ <code>obj</code> or any object in its prototype chain, or
+ <code>Scriptable.NOT_FOUND</code> if not found<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProperty(org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+getProperty</H3>
+<PRE>
+public static java.lang.Object <B>getProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</PRE>
+<DL>
+<DD>Gets an indexed property from an object or any object in its prototype chain.
+ <p>
+ Searches the prototype chain for a property with integral index
+ <code>index</code>. Note that if you wish to look for properties with numerical
+ but non-integral indicies, you should use getProperty(Scriptable,String) with
+ the string value of the index.
+ <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>index</CODE> - an integral index
+<DT><B>Returns:</B><DD>the value of a property with index <code>index</code> found in
+ <code>obj</code> or any object in its prototype chain, or
+ <code>Scriptable.NOT_FOUND</code> if not found<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+hasProperty</H3>
+<PRE>
+public static boolean <B>hasProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Returns whether a named property is defined in an object or any object
+ in its prototype chain.
+ <p>
+ Searches the prototype chain for a property named <code>name</code>.
+ <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>name</CODE> - a property name
+<DT><B>Returns:</B><DD>the true if property was found<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="redefineProperty(org.mozilla.javascript.Scriptable, java.lang.String, boolean)"><!-- --></A><H3>
+redefineProperty</H3>
+<PRE>
+public static void <B>redefineProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ boolean&nbsp;isConst)</PRE>
+<DL>
+<DD>If hasProperty(obj, name) would return true, then if the property that
+ was found is compatible with the new property, this method just returns.
+ If the property is not compatible, then an exception is thrown.
+
+ A property redefinition is incompatible if the first definition was a
+ const declaration or if this one is. They are compatible only if neither
+ was const.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasProperty(org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+hasProperty</H3>
+<PRE>
+public static boolean <B>hasProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</PRE>
+<DL>
+<DD>Returns whether an indexed property is defined in an object or any object
+ in its prototype chain.
+ <p>
+ Searches the prototype chain for a property with index <code>index</code>.
+ <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>index</CODE> - a property index
+<DT><B>Returns:</B><DD>the true if property was found<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><!-- --></A><H3>
+putProperty</H3>
+<PRE>
+public static void <B>putProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Puts a named property in an object or in an object in its prototype chain.
+ <p>
+ Searches for the named property in the prototype chain. If it is found,
+ the value of the property in <code>obj</code> is changed through a call
+ to <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>Scriptable.put(String, Scriptable, Object)</CODE></A> on the
+ prototype passing <code>obj</code> as the <code>start</code> argument.
+ This allows the prototype to veto the property setting in case the
+ prototype defines the property with [[ReadOnly]] attribute. If the
+ property is not found, it is added in <code>obj</code>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>name</CODE> - a property name<DD><CODE>value</CODE> - any JavaScript value accepted by Scriptable.put<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putConstProperty(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object)"><!-- --></A><H3>
+putConstProperty</H3>
+<PRE>
+public static void <B>putConstProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Puts a named property in an object or in an object in its prototype chain.
+ <p>
+ Searches for the named property in the prototype chain. If it is found,
+ the value of the property in <code>obj</code> is changed through a call
+ to <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>Scriptable.put(String, Scriptable, Object)</CODE></A> on the
+ prototype passing <code>obj</code> as the <code>start</code> argument.
+ This allows the prototype to veto the property setting in case the
+ prototype defines the property with [[ReadOnly]] attribute. If the
+ property is not found, it is added in <code>obj</code>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>name</CODE> - a property name<DD><CODE>value</CODE> - any JavaScript value accepted by Scriptable.put<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="putProperty(org.mozilla.javascript.Scriptable, int, java.lang.Object)"><!-- --></A><H3>
+putProperty</H3>
+<PRE>
+public static void <B>putProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Puts an indexed property in an object or in an object in its prototype chain.
+ <p>
+ Searches for the indexed property in the prototype chain. If it is found,
+ the value of the property in <code>obj</code> is changed through a call
+ to <A HREF="../../../org/mozilla/javascript/Scriptable.html#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>Scriptable.put(int, Scriptable, Object)</CODE></A> on the prototype
+ passing <code>obj</code> as the <code>start</code> argument. This allows
+ the prototype to veto the property setting in case the prototype defines
+ the property with [[ReadOnly]] attribute. If the property is not found,
+ it is added in <code>obj</code>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>index</CODE> - a property index<DD><CODE>value</CODE> - any JavaScript value accepted by Scriptable.put<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="deleteProperty(org.mozilla.javascript.Scriptable, java.lang.String)"><!-- --></A><H3>
+deleteProperty</H3>
+<PRE>
+public static boolean <B>deleteProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Removes the property from an object or its prototype chain.
+ <p>
+ Searches for a property with <code>name</code> in obj or
+ its prototype chain. If it is found, the object's delete
+ method is called.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>name</CODE> - a property name
+<DT><B>Returns:</B><DD>true if the property doesn't exist or was successfully removed<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="deleteProperty(org.mozilla.javascript.Scriptable, int)"><!-- --></A><H3>
+deleteProperty</H3>
+<PRE>
+public static boolean <B>deleteProperty</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ int&nbsp;index)</PRE>
+<DL>
+<DD>Removes the property from an object or its prototype chain.
+ <p>
+ Searches for a property with <code>index</code> in obj or
+ its prototype chain. If it is found, the object's delete
+ method is called.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object<DD><CODE>index</CODE> - a property index
+<DT><B>Returns:</B><DD>true if the property doesn't exist or was successfully removed<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getPropertyIds(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+getPropertyIds</H3>
+<PRE>
+public static java.lang.Object[] <B>getPropertyIds</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</PRE>
+<DL>
+<DD>Returns an array of all ids from an object and its prototypes.
+ <p>
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - a JavaScript object
+<DT><B>Returns:</B><DD>an array of all ids from all object in the prototype chain.
+ If a given id occurs multiple times in the prototype chain,
+ it will occur only once in this list.<DT><B>Since:</B></DT>
+ <DD>1.5R2</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="callMethod(org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><!-- --></A><H3>
+callMethod</H3>
+<PRE>
+public static java.lang.Object <B>callMethod</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;methodName,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call a method of an object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - the JavaScript object<DD><CODE>methodName</CODE> - the name of the function property<DD><CODE>args</CODE> - the arguments for the call<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#getCurrentContext()"><CODE>Context.getCurrentContext()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="callMethod(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.String, java.lang.Object[])"><!-- --></A><H3>
+callMethod</H3>
+<PRE>
+public static java.lang.Object <B>callMethod</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj,
+ java.lang.String&nbsp;methodName,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call a method of an object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the Context object associated with the current thread.<DD><CODE>obj</CODE> - the JavaScript object<DD><CODE>methodName</CODE> - the name of the function property<DD><CODE>args</CODE> - the arguments for the call</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAssociatedValue(java.lang.Object)"><!-- --></A><H3>
+getAssociatedValue</H3>
+<PRE>
+public final java.lang.Object <B>getAssociatedValue</B>(java.lang.Object&nbsp;key)</PRE>
+<DL>
+<DD>Get arbitrary application-specific value associated with this object.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>key</CODE> - key object to select particular value.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#associateValue(java.lang.Object, java.lang.Object)"><CODE>associateValue(Object key, Object value)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTopScopeValue(org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+getTopScopeValue</H3>
+<PRE>
+public static java.lang.Object <B>getTopScopeValue</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;key)</PRE>
+<DL>
+<DD>Get arbitrary application-specific value associated with the top scope
+ of the given scope.
+ The method first calls <A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getTopLevelScope(org.mozilla.javascript.Scriptable)"><CODE>getTopLevelScope(Scriptable scope)</CODE></A>
+ and then searches the prototype chain of the top scope for the first
+ object containing the associated value with the given key.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>scope</CODE> - the starting scope.<DD><CODE>key</CODE> - key object to select particular value.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)"><CODE>getAssociatedValue(Object key)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="associateValue(java.lang.Object, java.lang.Object)"><!-- --></A><H3>
+associateValue</H3>
+<PRE>
+public final java.lang.Object <B>associateValue</B>(java.lang.Object&nbsp;key,
+ java.lang.Object&nbsp;value)</PRE>
+<DL>
+<DD>Associate arbitrary application-specific value with this object.
+ Value can only be associated with the given object and key only once.
+ The method ignores any subsequent attempts to change the already
+ associated value.
+ <p> The associated values are not serialized.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>key</CODE> - key object to select particular value.<DD><CODE>value</CODE> - the value to associate
+<DT><B>Returns:</B><DD>the passed value if the method is called first time for the
+ given key or old value for any subsequent calls.<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/ScriptableObject.html#getAssociatedValue(java.lang.Object)"><CODE>getAssociatedValue(Object key)</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/ScriptableObject.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableObject.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/SecurityController.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/SecurityController.html
new file mode 100644
index 0000000..92c5c44
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/SecurityController.html
@@ -0,0 +1,507 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+SecurityController (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="SecurityController (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/SecurityController.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="SecurityController.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class SecurityController</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.SecurityController</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public abstract class <B>SecurityController</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+This class describes the support needed to implement security.
+ <p>
+ Three main pieces of functionality are required to implement
+ security for JavaScript. First, it must be possible to define
+ classes with an associated security domain. (This security
+ domain may be any object incorporating notion of access
+ restrictions that has meaning to an embedding; for a client-side
+ JavaScript embedding this would typically be
+ java.security.ProtectionDomain or similar object depending on an
+ origin URL and/or a digital certificate.)
+ Next it must be possible to get a security domain object that
+ allows a particular action only if all security domains
+ associated with code on the current Java stack allows it. And
+ finally, it must be possible to execute script code with
+ associated security domain injected into Java stack.
+ <p>
+ These three pieces of functionality are encapsulated in the
+ SecurityController class.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.5 Release 4</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#setSecurityController(org.mozilla.javascript.SecurityController)"><CODE>Context.setSecurityController(SecurityController)</CODE></A>,
+<CODE>ClassLoader</CODE></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#SecurityController()">SecurityController</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">callWithDomain</A></B>(java.lang.Object&nbsp;securityDomain,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call <A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ of <i>callable</i> under restricted security domain where an action is
+ allowed only if it is allowed according to the Java stack on the
+ moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>abstract &nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#createClassLoader(java.lang.ClassLoader, java.lang.Object)">createClassLoader</A></B>(java.lang.ClassLoader&nbsp;parentLoader,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get class loader-like object that can be used
+ to define classes with the given security context.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#createLoader(java.lang.ClassLoader, java.lang.Object)">createLoader</A></B>(java.lang.ClassLoader&nbsp;parent,
+ java.lang.Object&nbsp;staticDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><CODE>GeneratedClassLoader</CODE></A> with restrictions imposed by
+ staticDomain and all current stack frames.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#execWithDomain(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Script, java.lang.Object)">execWithDomain</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script,
+ java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>The application should not override this method and instead
+ override
+ <A HREF="../../../org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)</CODE></A>.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>abstract &nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#getDynamicSecurityDomain(java.lang.Object)">getDynamicSecurityDomain</A></B>(java.lang.Object&nbsp;securityDomain)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get dynamic security domain that allows an action only if it is allowed
+ by the current Java stack and <i>securityDomain</i>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;java.lang.Class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#getStaticSecurityDomainClass()">getStaticSecurityDomainClass</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#getStaticSecurityDomainClassInternal()">getStaticSecurityDomainClassInternal</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#hasGlobal()">hasGlobal</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check if global <A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><CODE>SecurityController</CODE></A> was already installed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/SecurityController.html#initGlobal(org.mozilla.javascript.SecurityController)">initGlobal</A></B>(<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>&nbsp;controller)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initialize global controller that will be used for all
+ security-related operations.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="SecurityController()"><!-- --></A><H3>
+SecurityController</H3>
+<PRE>
+public <B>SecurityController</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="hasGlobal()"><!-- --></A><H3>
+hasGlobal</H3>
+<PRE>
+public static boolean <B>hasGlobal</B>()</PRE>
+<DL>
+<DD>Check if global <A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><CODE>SecurityController</CODE></A> was already installed.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/SecurityController.html#initGlobal(org.mozilla.javascript.SecurityController)"><CODE>initGlobal(SecurityController controller)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="initGlobal(org.mozilla.javascript.SecurityController)"><!-- --></A><H3>
+initGlobal</H3>
+<PRE>
+public static void <B>initGlobal</B>(<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A>&nbsp;controller)</PRE>
+<DL>
+<DD>Initialize global controller that will be used for all
+ security-related operations. The global controller takes precedence
+ over already installed <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>-specific controllers and cause
+ any subsequent call to
+ <A HREF="../../../org/mozilla/javascript/Context.html#setSecurityController(org.mozilla.javascript.SecurityController)"><CODE>Context.setSecurityController(SecurityController)</CODE></A>
+ to throw an exception.
+ <p>
+ The method can only be called once.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/SecurityController.html#hasGlobal()"><CODE>hasGlobal()</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createClassLoader(java.lang.ClassLoader, java.lang.Object)"><!-- --></A><H3>
+createClassLoader</H3>
+<PRE>
+public abstract <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A> <B>createClassLoader</B>(java.lang.ClassLoader&nbsp;parentLoader,
+ java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD>Get class loader-like object that can be used
+ to define classes with the given security context.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parentLoader</CODE> - parent class loader to delegate search for classes
+ not defined by the class loader itself<DD><CODE>securityDomain</CODE> - some object specifying the security
+ context of the code that is defined by the returned class loader.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="createLoader(java.lang.ClassLoader, java.lang.Object)"><!-- --></A><H3>
+createLoader</H3>
+<PRE>
+public static <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A> <B>createLoader</B>(java.lang.ClassLoader&nbsp;parent,
+ java.lang.Object&nbsp;staticDomain)</PRE>
+<DL>
+<DD>Create <A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><CODE>GeneratedClassLoader</CODE></A> with restrictions imposed by
+ staticDomain and all current stack frames.
+ The method uses the SecurityController instance associated with the
+ current <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> to construct proper dynamic domain and create
+ corresponding class loader.
+ <par>
+ If no SecurityController is associated with the current <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> ,
+ the method calls <A HREF="../../../org/mozilla/javascript/Context.html#createClassLoader(java.lang.ClassLoader)"><CODE>Context.createClassLoader(ClassLoader parent)</CODE></A>.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>parent</CODE> - parent class loader. If null,
+ <A HREF="../../../org/mozilla/javascript/Context.html#getApplicationClassLoader()"><CODE>Context.getApplicationClassLoader()</CODE></A> will be used.<DD><CODE>staticDomain</CODE> - static security domain.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStaticSecurityDomainClass()"><!-- --></A><H3>
+getStaticSecurityDomainClass</H3>
+<PRE>
+public static java.lang.Class <B>getStaticSecurityDomainClass</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStaticSecurityDomainClassInternal()"><!-- --></A><H3>
+getStaticSecurityDomainClassInternal</H3>
+<PRE>
+public java.lang.Class <B>getStaticSecurityDomainClassInternal</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDynamicSecurityDomain(java.lang.Object)"><!-- --></A><H3>
+getDynamicSecurityDomain</H3>
+<PRE>
+public abstract java.lang.Object <B>getDynamicSecurityDomain</B>(java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD>Get dynamic security domain that allows an action only if it is allowed
+ by the current Java stack and <i>securityDomain</i>. If
+ <i>securityDomain</i> is null, return domain representing permissions
+ allowed by the current stack.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+callWithDomain</H3>
+<PRE>
+public java.lang.Object <B>callWithDomain</B>(java.lang.Object&nbsp;securityDomain,
+ <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>&nbsp;callable,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD>Call <A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Callable.call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)</CODE></A>
+ of <i>callable</i> under restricted security domain where an action is
+ allowed only if it is allowed according to the Java stack on the
+ moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.
+ Any call to <A HREF="../../../org/mozilla/javascript/SecurityController.html#getDynamicSecurityDomain(java.lang.Object)"><CODE>getDynamicSecurityDomain(Object)</CODE></A> during
+ execution of <tt>callable.call(cx, scope, thisObj, args)</tt>
+ should return a domain incorporate restrictions imposed by
+ <i>securityDomain</i> and Java stack on the moment of callWithDomain
+ invocation.
+ <p>
+ The method should always be overridden, it is not declared abstract
+ for compatibility reasons.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="execWithDomain(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Script, java.lang.Object)"><!-- --></A><H3>
+execWithDomain</H3>
+<PRE>
+public java.lang.Object <B>execWithDomain</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A>&nbsp;script,
+ java.lang.Object&nbsp;securityDomain)</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>The application should not override this method and instead
+ override
+ <A HREF="../../../org/mozilla/javascript/SecurityController.html#callWithDomain(java.lang.Object, org.mozilla.javascript.Context, org.mozilla.javascript.Callable, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)</CODE></A>.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/SecurityController.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="SecurityController.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Synchronizer.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Synchronizer.html
new file mode 100644
index 0000000..05b8fb4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Synchronizer.html
@@ -0,0 +1,331 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Synchronizer (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Synchronizer (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Synchronizer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Synchronizer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.mozilla.javascript.Delegator">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class Synchronizer</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">org.mozilla.javascript.Delegator
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.Synchronizer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>, <A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>, <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>Synchronizer</B><DT>extends org.mozilla.javascript.Delegator</DL>
+</PRE>
+
+<P>
+This class provides support for implementing Java-style synchronized
+ methods in Javascript.
+
+ Synchronized functions are created from ordinary Javascript
+ functions by the <code>Synchronizer</code> constructor, e.g.
+ <code>new Packages.org.mozilla.javascript.Synchronizer(fun)</code>.
+ The resulting object is a function that establishes an exclusive
+ lock on the <code>this</code> object of its invocation.
+
+ The Rhino shell provides a short-cut for the creation of
+ synchronized methods: <code>sync(fun)</code> has the same effect as
+ calling the above constructor.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Matthias Radestock</DD>
+<DT><B>See Also:</B><DD><CODE>Delegator</CODE></DL>
+<HR>
+
+<P>
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Delegator"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from class org.mozilla.javascript.Delegator</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>obj</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_org.mozilla.javascript.Scriptable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/Scriptable.html#NOT_FOUND">NOT_FOUND</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Synchronizer.html#Synchronizer(org.mozilla.javascript.Scriptable)">Synchronizer</A></B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a new synchronized function from an existing one.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Synchronizer.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call the function.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.Delegator"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.Delegator</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>construct, delete, delete, get, get, getClassName, getDefaultValue, getDelegee, getIds, getParentScope, getPrototype, has, has, hasInstance, newInstance, put, put, setDelegee, setParentScope, setPrototype</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="Synchronizer(org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+Synchronizer</H3>
+<PRE>
+public <B>Synchronizer</B>(<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;obj)</PRE>
+<DL>
+<DD>Create a new synchronized function from an existing one.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>obj</CODE> - the existing function</DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><!-- --></A><H3>
+call</H3>
+<PRE>
+public java.lang.Object <B>call</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;thisObj,
+ java.lang.Object[]&nbsp;args)</PRE>
+<DL>
+<DD><B>Description copied from interface: <CODE><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">Function</A></CODE></B></DD>
+<DD>Call the function.
+
+ Note that the array of arguments is not guaranteed to have
+ length greater than 0.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Callable.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></CODE><DT><B>Specified by:</B><DD><CODE><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])">call</A></CODE> in interface <CODE><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A></CODE><DT><B>Overrides:</B><DD><CODE>call</CODE> in class <CODE>org.mozilla.javascript.Delegator</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope to execute the function relative to. This is
+ set to the value returned by getParentScope() except
+ when the function is called from a closure.<DD><CODE>thisObj</CODE> - the JavaScript <code>this</code> object<DD><CODE>args</CODE> - the array of arguments
+<DT><B>Returns:</B><DD>the result of the call<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Function.html#call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])"><CODE>Function.call(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, org.mozilla.javascript.Scriptable, java.lang.Object[])</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Synchronizer.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Synchronizer.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_org.mozilla.javascript.Delegator">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrapFactory.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrapFactory.html
new file mode 100644
index 0000000..675c456
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrapFactory.html
@@ -0,0 +1,400 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+WrapFactory (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="WrapFactory (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/WrapFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WrapFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class WrapFactory</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.WrapFactory</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>WrapFactory</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Embeddings that wish to provide their own custom wrappings for Java
+ objects may extend this class and call
+ <A HREF="../../../org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)"><CODE>Context.setWrapFactory(WrapFactory)</CODE></A>
+ Once an instance of this class or an extension of this class is enabled
+ for a given context (by calling setWrapFactory on that context), Rhino
+ will call the methods of this class whenever it needs to wrap a value
+ resulting from a call to a Java method or an access to a Java field.
+<P>
+
+<P>
+<DL>
+<DT><B>Since:</B></DT>
+ <DD>1.5 Release 4</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)"><CODE>Context.setWrapFactory(WrapFactory)</CODE></A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#WrapFactory()">WrapFactory</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#isJavaPrimitiveWrap()">isJavaPrimitiveWrap</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return <code>false</code> if result of Java method, which is instance of
+ <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ <code>Character</code>, should be used directly as JavaScript primitive
+ type.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#setJavaPrimitiveWrap(boolean)">setJavaPrimitiveWrap</A></B>(boolean&nbsp;value)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrap(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)">wrap</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;obj,
+ java.lang.Class&nbsp;staticType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wrap the object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrapAsJavaObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)">wrapAsJavaObject</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;javaObject,
+ java.lang.Class&nbsp;staticType)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wrap Java object as Scriptable instance to allow full access to its
+ methods and fields from JavaScript.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrapNewObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object)">wrapNewObject</A></B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wrap an object newly created by a constructor call.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="WrapFactory()"><!-- --></A><H3>
+WrapFactory</H3>
+<PRE>
+public <B>WrapFactory</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="wrap(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><!-- --></A><H3>
+wrap</H3>
+<PRE>
+public java.lang.Object <B>wrap</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;obj,
+ java.lang.Class&nbsp;staticType)</PRE>
+<DL>
+<DD>Wrap the object.
+ <p>
+ The value returned must be one of
+ <UL>
+ <LI>java.lang.Boolean</LI>
+ <LI>java.lang.String</LI>
+ <LI>java.lang.Number</LI>
+ <LI>org.mozilla.javascript.Scriptable objects</LI>
+ <LI>The value returned by Context.getUndefinedValue()</LI>
+ <LI>null</LI>
+ </UL>
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope of the executing script<DD><CODE>obj</CODE> - the object to be wrapped. Note it can be null.<DD><CODE>staticType</CODE> - type hint. If security restrictions prevent to wrap
+ object based on its class, staticType will be used instead.
+<DT><B>Returns:</B><DD>the wrapped value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="wrapNewObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object)"><!-- --></A><H3>
+wrapNewObject</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>wrapNewObject</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;obj)</PRE>
+<DL>
+<DD>Wrap an object newly created by a constructor call.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope of the executing script<DD><CODE>obj</CODE> - the object to be wrapped
+<DT><B>Returns:</B><DD>the wrapped value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="wrapAsJavaObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><!-- --></A><H3>
+wrapAsJavaObject</H3>
+<PRE>
+public <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>wrapAsJavaObject</B>(<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A>&nbsp;cx,
+ <A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope,
+ java.lang.Object&nbsp;javaObject,
+ java.lang.Class&nbsp;staticType)</PRE>
+<DL>
+<DD>Wrap Java object as Scriptable instance to allow full access to its
+ methods and fields from JavaScript.
+ <p>
+ <A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrap(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object, java.lang.Class)"><CODE>wrap(Context, Scriptable, Object, Class)</CODE></A> and
+ <A HREF="../../../org/mozilla/javascript/WrapFactory.html#wrapNewObject(org.mozilla.javascript.Context, org.mozilla.javascript.Scriptable, java.lang.Object)"><CODE>wrapNewObject(Context, Scriptable, Object)</CODE></A> call this method
+ when they can not convert <tt>javaObject</tt> to JavaScript primitive
+ value or JavaScript array.
+ <p>
+ Subclasses can override the method to provide custom wrappers
+ for Java objects.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>cx</CODE> - the current Context for this thread<DD><CODE>scope</CODE> - the scope of the executing script<DD><CODE>javaObject</CODE> - the object to be wrapped<DD><CODE>staticType</CODE> - type hint. If security restrictions prevent to wrap
+ object based on its class, staticType will be used instead.
+<DT><B>Returns:</B><DD>the wrapped value which shall not be null</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isJavaPrimitiveWrap()"><!-- --></A><H3>
+isJavaPrimitiveWrap</H3>
+<PRE>
+public final boolean <B>isJavaPrimitiveWrap</B>()</PRE>
+<DL>
+<DD>Return <code>false</code> if result of Java method, which is instance of
+ <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ <code>Character</code>, should be used directly as JavaScript primitive
+ type.
+ By default the method returns true to indicate that instances of
+ <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ <code>Character</code> should be wrapped as any other Java object and
+ scripts can access any Java method available in these objects.
+ Use <A HREF="../../../org/mozilla/javascript/WrapFactory.html#setJavaPrimitiveWrap(boolean)"><CODE>setJavaPrimitiveWrap(boolean)</CODE></A> to change this.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setJavaPrimitiveWrap(boolean)"><!-- --></A><H3>
+setJavaPrimitiveWrap</H3>
+<PRE>
+public final void <B>setJavaPrimitiveWrap</B>(boolean&nbsp;value)</PRE>
+<DL>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/WrapFactory.html#isJavaPrimitiveWrap()"><CODE>isJavaPrimitiveWrap()</CODE></A></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/WrapFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WrapFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrappedException.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrappedException.html
new file mode 100644
index 0000000..1109997
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/WrappedException.html
@@ -0,0 +1,323 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+WrappedException (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="WrappedException (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/WrappedException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WrappedException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Class WrappedException</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Throwable
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.Exception
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by ">java.lang.RuntimeException
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.RhinoException</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.EvaluatorException</A>
+ <IMG SRC="../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.WrappedException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>WrappedException</B><DT>extends <A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></DL>
+</PRE>
+
+<P>
+A wrapper for runtime exceptions.
+
+ Used by the JavaScript runtime to wrap and propagate exceptions that occur
+ during runtime.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+<DT><B>See Also:</B><DD><A HREF="../../../serialized-form.html#org.mozilla.javascript.WrappedException">Serialized Form</A></DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrappedException.html#WrappedException(java.lang.Throwable)">WrappedException</A></B>(java.lang.Throwable&nbsp;exception)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Throwable</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrappedException.html#getWrappedException()">getWrappedException</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the wrapped exception.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/WrappedException.html#unwrap()">unwrap</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/WrappedException.html#getWrappedException()"><CODE>getWrappedException()</CODE></A> instead.</I></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.EvaluatorException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getColumnNumber()">getColumnNumber</A>, <A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getLineNumber()">getLineNumber</A>, <A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getLineSource()">getLineSource</A>, <A HREF="../../../org/mozilla/javascript/EvaluatorException.html#getSourceName()">getSourceName</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_org.mozilla.javascript.RhinoException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../../org/mozilla/javascript/RhinoException.html#columnNumber()">columnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#details()">details</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getMessage()">getMessage</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace()">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#getScriptStackTrace(java.io.FilenameFilter)">getScriptStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initColumnNumber(int)">initColumnNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineNumber(int)">initLineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initLineSource(java.lang.String)">initLineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#initSourceName(java.lang.String)">initSourceName</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineNumber()">lineNumber</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#lineSource()">lineSource</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintStream)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#printStackTrace(java.io.PrintWriter)">printStackTrace</A>, <A HREF="../../../org/mozilla/javascript/RhinoException.html#sourceName()">sourceName</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Throwable</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getCause, getLocalizedMessage, getStackTrace, initCause, printStackTrace, setStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="WrappedException(java.lang.Throwable)"><!-- --></A><H3>
+WrappedException</H3>
+<PRE>
+public <B>WrappedException</B>(java.lang.Throwable&nbsp;exception)</PRE>
+<DL>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="../../../org/mozilla/javascript/Context.html#throwAsScriptRuntimeEx(java.lang.Throwable)"><CODE>Context.throwAsScriptRuntimeEx(Throwable e)</CODE></A></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="getWrappedException()"><!-- --></A><H3>
+getWrappedException</H3>
+<PRE>
+public java.lang.Throwable <B>getWrappedException</B>()</PRE>
+<DL>
+<DD>Get the wrapped exception.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the exception that was presented as a argument to the
+ constructor when this object was created</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="unwrap()"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+public java.lang.Object <B>unwrap</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B>&nbsp;<I>Use <A HREF="../../../org/mozilla/javascript/WrappedException.html#getWrappedException()"><CODE>getWrappedException()</CODE></A> instead.</I>
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/WrappedException.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="WrappedException.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Wrapper.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Wrapper.html
new file mode 100644
index 0000000..0d05fdc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/Wrapper.html
@@ -0,0 +1,214 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Wrapper (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Wrapper (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Wrapper.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Wrapper.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript</FONT>
+<BR>
+Interface Wrapper</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>Wrapper</B></DL>
+</PRE>
+
+<P>
+Objects that can wrap other values for reflection in the JS environment
+ will implement Wrapper.
+
+ Wrapper defines a single method that can be called to unwrap the object.
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../org/mozilla/javascript/Wrapper.html#unwrap()">unwrap</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Unwrap the object by returning the wrapped value.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="unwrap()"><!-- --></A><H3>
+unwrap</H3>
+<PRE>
+java.lang.Object <B>unwrap</B>()</PRE>
+<DL>
+<DD>Unwrap the object by returning the wrapped value.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a wrapped value</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/Wrapper.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="Wrapper.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/DebuggableScript.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/DebuggableScript.html
new file mode 100644
index 0000000..1159738
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/DebuggableScript.html
@@ -0,0 +1,455 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+DebuggableScript (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="DebuggableScript (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/DebuggableScript.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="DebuggableScript.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript.debug</FONT>
+<BR>
+Interface DebuggableScript</H2>
+<HR>
+<DL>
+<DT><PRE>public interface <B>DebuggableScript</B></DL>
+</PRE>
+
+<P>
+This interface exposes debugging information from executable
+ code (either functions or top-level scripts).
+<P>
+
+<P>
+<HR>
+
+<P>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getFunction(int)">getFunction</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getFunctionCount()">getFunctionCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getFunctionName()">getFunctionName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get name of the function described by this script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getLineNumbers()">getLineNumbers</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get array containing the line numbers that
+ that can be passed to <code>DebugFrame.onLineChange()<code>.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamAndVarCount()">getParamAndVarCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get number of declared parameters and local variables.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamCount()">getParamCount</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get number of declared parameters in the function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamOrVarName(int)">getParamOrVarName</A></B>(int&nbsp;index)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get name of a declared parameter or local variable.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParent()">getParent</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getSourceName()">getSourceName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the name of the source (usually filename or URL)
+ of the script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#isFunction()">isFunction</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this is a function, false if it is a script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#isGeneratedScript()">isGeneratedScript</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if this script or function were runtime-generated
+ from JavaScript using <tt>eval</tt> function or <tt>Function</tt>
+ or <tt>Script</tt> constructors.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#isTopLevel()">isTopLevel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="isTopLevel()"><!-- --></A><H3>
+isTopLevel</H3>
+<PRE>
+boolean <B>isTopLevel</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isFunction()"><!-- --></A><H3>
+isFunction</H3>
+<PRE>
+boolean <B>isFunction</B>()</PRE>
+<DL>
+<DD>Returns true if this is a function, false if it is a script.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctionName()"><!-- --></A><H3>
+getFunctionName</H3>
+<PRE>
+java.lang.String <B>getFunctionName</B>()</PRE>
+<DL>
+<DD>Get name of the function described by this script.
+ Return null or an empty string if this script is not a function.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParamCount()"><!-- --></A><H3>
+getParamCount</H3>
+<PRE>
+int <B>getParamCount</B>()</PRE>
+<DL>
+<DD>Get number of declared parameters in the function.
+ Return 0 if this script is not a function.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamAndVarCount()"><CODE>getParamAndVarCount()</CODE></A>,
+<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamOrVarName(int)"><CODE>getParamOrVarName(int index)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParamAndVarCount()"><!-- --></A><H3>
+getParamAndVarCount</H3>
+<PRE>
+int <B>getParamAndVarCount</B>()</PRE>
+<DL>
+<DD>Get number of declared parameters and local variables.
+ Return number of declared global variables if this script is not a
+ function.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamCount()"><CODE>getParamCount()</CODE></A>,
+<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamOrVarName(int)"><CODE>getParamOrVarName(int index)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParamOrVarName(int)"><!-- --></A><H3>
+getParamOrVarName</H3>
+<PRE>
+java.lang.String <B>getParamOrVarName</B>(int&nbsp;index)</PRE>
+<DL>
+<DD>Get name of a declared parameter or local variable.
+ <tt>index</tt> should be less then <A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamAndVarCount()"><CODE>getParamAndVarCount()</CODE></A>.
+ If <tt>index&nbsp;&lt;&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html#getParamCount()"><CODE>getParamCount()</CODE></A></tt>, return
+ the name of the corresponding parameter, otherwise return the name
+ of variable.
+ If this script is not function, return the name of the declared
+ global variable.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSourceName()"><!-- --></A><H3>
+getSourceName</H3>
+<PRE>
+java.lang.String <B>getSourceName</B>()</PRE>
+<DL>
+<DD>Get the name of the source (usually filename or URL)
+ of the script.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isGeneratedScript()"><!-- --></A><H3>
+isGeneratedScript</H3>
+<PRE>
+boolean <B>isGeneratedScript</B>()</PRE>
+<DL>
+<DD>Returns true if this script or function were runtime-generated
+ from JavaScript using <tt>eval</tt> function or <tt>Function</tt>
+ or <tt>Script</tt> constructors.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineNumbers()"><!-- --></A><H3>
+getLineNumbers</H3>
+<PRE>
+int[] <B>getLineNumbers</B>()</PRE>
+<DL>
+<DD>Get array containing the line numbers that
+ that can be passed to <code>DebugFrame.onLineChange()<code>.
+ Note that line order in the resulting array is arbitrary
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunctionCount()"><!-- --></A><H3>
+getFunctionCount</H3>
+<PRE>
+int <B>getFunctionCount</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getFunction(int)"><!-- --></A><H3>
+getFunction</H3>
+<PRE>
+<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A> <B>getFunction</B>(int&nbsp;index)</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getParent()"><!-- --></A><H3>
+getParent</H3>
+<PRE>
+<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A> <B>getParent</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/DebuggableScript.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="DebuggableScript.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-frame.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-frame.html
new file mode 100644
index 0000000..28878a0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-frame.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.debug (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../org/mozilla/javascript/debug/package-summary.html" target="classFrame">org.mozilla.javascript.debug</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="DebuggableScript.html" title="interface in org.mozilla.javascript.debug" target="classFrame"><I>DebuggableScript</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-summary.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-summary.html
new file mode 100644
index 0000000..1a50d7f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-summary.html
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.debug (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.debug (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.mozilla.javascript.debug
+</H2>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug">DebuggableScript</A></B></TD>
+<TD>This interface exposes debugging information from executable
+ code (either functions or top-level scripts).</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-tree.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-tree.html
new file mode 100644
index 0000000..d32bdf5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/debug/package-tree.html
@@ -0,0 +1,149 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.debug Class Hierarchy (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.debug Class Hierarchy (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.mozilla.javascript.debug
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.debug.<A HREF="../../../../org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug"><B>DebuggableScript</B></A></UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/debug/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/ClassCompiler.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/ClassCompiler.html
new file mode 100644
index 0000000..bdce431
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/ClassCompiler.html
@@ -0,0 +1,461 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+ClassCompiler (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ClassCompiler (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/ClassCompiler.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassCompiler.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript.optimizer</FONT>
+<BR>
+Class ClassCompiler</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.optimizer.ClassCompiler</B>
+</PRE>
+<HR>
+<DL>
+<DT><PRE>public class <B>ClassCompiler</B><DT>extends java.lang.Object</DL>
+</PRE>
+
+<P>
+Generates class files from script sources.
+
+ since 1.5 Release 5
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Igor Bukanov</DD>
+</DL>
+<HR>
+
+<P>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#ClassCompiler(org.mozilla.javascript.CompilerEnvirons)">ClassCompiler</A></B>(<A HREF="../../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>&nbsp;compilerEnv)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Construct ClassCompiler that uses the specified compiler environment
+ when generating classes.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Object[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#compileToClassFiles(java.lang.String, java.lang.String, int, java.lang.String)">compileToClassFiles</A></B>(java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceLocation,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;mainClassName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Compile JavaScript source into one or more Java class files.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;<A HREF="../../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getCompilerEnv()">getCompilerEnv</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the compiler environment the compiler uses.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getMainMethodClass()">getMainMethodClass</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the name of the class for main method implementation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetExtends()">getTargetExtends</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the class that the generated target will extend.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.Class[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetImplements()">getTargetImplements</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the interfaces that the generated target will implement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#makeAuxiliaryClassName(java.lang.String, java.lang.String)">makeAuxiliaryClassName</A></B>(java.lang.String&nbsp;mainClassName,
+ java.lang.String&nbsp;auxMarker)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Build class name for a auxiliary class generated by compiler.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#setMainMethodClass(java.lang.String)">setMainMethodClass</A></B>(java.lang.String&nbsp;className)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the class name to use for main method implementation.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#setTargetExtends(java.lang.Class)">setTargetExtends</A></B>(java.lang.Class&nbsp;extendsClass)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the class that the generated target will extend.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#setTargetImplements(java.lang.Class[])">setTargetImplements</A></B>(java.lang.Class[]&nbsp;implementsClasses)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the interfaces that the generated target will implement.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ClassCompiler(org.mozilla.javascript.CompilerEnvirons)"><!-- --></A><H3>
+ClassCompiler</H3>
+<PRE>
+public <B>ClassCompiler</B>(<A HREF="../../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A>&nbsp;compilerEnv)</PRE>
+<DL>
+<DD>Construct ClassCompiler that uses the specified compiler environment
+ when generating classes.
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="setMainMethodClass(java.lang.String)"><!-- --></A><H3>
+setMainMethodClass</H3>
+<PRE>
+public void <B>setMainMethodClass</B>(java.lang.String&nbsp;className)</PRE>
+<DL>
+<DD>Set the class name to use for main method implementation.
+ The class must have a method matching
+ <tt>public static void main(Script sc, String[] args)</tt>, it will be
+ called when <tt>main(String[] args)</tt> is called in the generated
+ class. The class name should be fully qulified name and include the
+ package name like in <tt>org.foo.Bar<tt>.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMainMethodClass()"><!-- --></A><H3>
+getMainMethodClass</H3>
+<PRE>
+public java.lang.String <B>getMainMethodClass</B>()</PRE>
+<DL>
+<DD>Get the name of the class for main method implementation.
+<P>
+<DD><DL>
+<DT><B>See Also:</B><DD><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#setMainMethodClass(java.lang.String)"><CODE>setMainMethodClass(String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getCompilerEnv()"><!-- --></A><H3>
+getCompilerEnv</H3>
+<PRE>
+public <A HREF="../../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A> <B>getCompilerEnv</B>()</PRE>
+<DL>
+<DD>Get the compiler environment the compiler uses.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTargetExtends()"><!-- --></A><H3>
+getTargetExtends</H3>
+<PRE>
+public java.lang.Class <B>getTargetExtends</B>()</PRE>
+<DL>
+<DD>Get the class that the generated target will extend.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTargetExtends(java.lang.Class)"><!-- --></A><H3>
+setTargetExtends</H3>
+<PRE>
+public void <B>setTargetExtends</B>(java.lang.Class&nbsp;extendsClass)</PRE>
+<DL>
+<DD>Set the class that the generated target will extend.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>extendsClass</CODE> - the class it extends</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getTargetImplements()"><!-- --></A><H3>
+getTargetImplements</H3>
+<PRE>
+public java.lang.Class[] <B>getTargetImplements</B>()</PRE>
+<DL>
+<DD>Get the interfaces that the generated target will implement.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setTargetImplements(java.lang.Class[])"><!-- --></A><H3>
+setTargetImplements</H3>
+<PRE>
+public void <B>setTargetImplements</B>(java.lang.Class[]&nbsp;implementsClasses)</PRE>
+<DL>
+<DD>Set the interfaces that the generated target will implement.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>implementsClasses</CODE> - an array of Class objects, one for each
+ interface the target will extend</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="makeAuxiliaryClassName(java.lang.String, java.lang.String)"><!-- --></A><H3>
+makeAuxiliaryClassName</H3>
+<PRE>
+protected java.lang.String <B>makeAuxiliaryClassName</B>(java.lang.String&nbsp;mainClassName,
+ java.lang.String&nbsp;auxMarker)</PRE>
+<DL>
+<DD>Build class name for a auxiliary class generated by compiler.
+ If the compiler needs to generate extra classes beyond the main class,
+ it will call this function to build the auxiliary class name.
+ The default implementation simply appends auxMarker to mainClassName
+ but this can be overridden.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="compileToClassFiles(java.lang.String, java.lang.String, int, java.lang.String)"><!-- --></A><H3>
+compileToClassFiles</H3>
+<PRE>
+public java.lang.Object[] <B>compileToClassFiles</B>(java.lang.String&nbsp;source,
+ java.lang.String&nbsp;sourceLocation,
+ int&nbsp;lineno,
+ java.lang.String&nbsp;mainClassName)</PRE>
+<DL>
+<DD>Compile JavaScript source into one or more Java class files.
+ The first compiled class will have name mainClassName.
+ If the results of <A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetExtends()"><CODE>getTargetExtends()</CODE></A> or
+ <A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html#getTargetImplements()"><CODE>getTargetImplements()</CODE></A> are not null, then the first compiled
+ class will extend the specified super class and implement
+ specified interfaces.
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>array where elements with even indexes specifies class name
+ and the following odd index gives class file body as byte[]
+ array. The initial element of the array always holds
+ mainClassName and array[1] holds its byte code.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/ClassCompiler.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ClassCompiler.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-frame.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-frame.html
new file mode 100644
index 0000000..1dc284b
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-frame.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.optimizer (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../org/mozilla/javascript/optimizer/package-summary.html" target="classFrame">org.mozilla.javascript.optimizer</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ClassCompiler.html" title="class in org.mozilla.javascript.optimizer" target="classFrame">ClassCompiler</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-summary.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-summary.html
new file mode 100644
index 0000000..8b86a40
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-summary.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.optimizer (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.optimizer (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.mozilla.javascript.optimizer
+</H2>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer">ClassCompiler</A></B></TD>
+<TD>Generates class files from script sources.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-tree.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-tree.html
new file mode 100644
index 0000000..55e23d0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/optimizer/package-tree.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.optimizer Class Hierarchy (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.optimizer Class Hierarchy (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.mozilla.javascript.optimizer
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">org.mozilla.javascript.optimizer.<A HREF="../../../../org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer"><B>ClassCompiler</B></A></UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/debug/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/optimizer/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-frame.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-frame.html
new file mode 100644
index 0000000..f40351c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-frame.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+org.mozilla.javascript (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../org/mozilla/javascript/package-summary.html" target="classFrame">org.mozilla.javascript</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Callable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Callable</I></A>
+<BR>
+<A HREF="ClassShutter.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ClassShutter</I></A>
+<BR>
+<A HREF="ContextAction.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ContextAction</I></A>
+<BR>
+<A HREF="ContextFactory.Listener.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ContextFactory.Listener</I></A>
+<BR>
+<A HREF="ErrorReporter.html" title="interface in org.mozilla.javascript" target="classFrame"><I>ErrorReporter</I></A>
+<BR>
+<A HREF="Function.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Function</I></A>
+<BR>
+<A HREF="GeneratedClassLoader.html" title="interface in org.mozilla.javascript" target="classFrame"><I>GeneratedClassLoader</I></A>
+<BR>
+<A HREF="RefCallable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>RefCallable</I></A>
+<BR>
+<A HREF="Script.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Script</I></A>
+<BR>
+<A HREF="Scriptable.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Scriptable</I></A>
+<BR>
+<A HREF="Wrapper.html" title="interface in org.mozilla.javascript" target="classFrame"><I>Wrapper</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ClassCache.html" title="class in org.mozilla.javascript" target="classFrame">ClassCache</A>
+<BR>
+<A HREF="CompilerEnvirons.html" title="class in org.mozilla.javascript" target="classFrame">CompilerEnvirons</A>
+<BR>
+<A HREF="Context.html" title="class in org.mozilla.javascript" target="classFrame">Context</A>
+<BR>
+<A HREF="ContextFactory.html" title="class in org.mozilla.javascript" target="classFrame">ContextFactory</A>
+<BR>
+<A HREF="FunctionObject.html" title="class in org.mozilla.javascript" target="classFrame">FunctionObject</A>
+<BR>
+<A HREF="ImporterTopLevel.html" title="class in org.mozilla.javascript" target="classFrame">ImporterTopLevel</A>
+<BR>
+<A HREF="ScriptableObject.html" title="class in org.mozilla.javascript" target="classFrame">ScriptableObject</A>
+<BR>
+<A HREF="SecurityController.html" title="class in org.mozilla.javascript" target="classFrame">SecurityController</A>
+<BR>
+<A HREF="Synchronizer.html" title="class in org.mozilla.javascript" target="classFrame">Synchronizer</A>
+<BR>
+<A HREF="WrapFactory.html" title="class in org.mozilla.javascript" target="classFrame">WrapFactory</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Exceptions</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="EcmaError.html" title="class in org.mozilla.javascript" target="classFrame">EcmaError</A>
+<BR>
+<A HREF="EvaluatorException.html" title="class in org.mozilla.javascript" target="classFrame">EvaluatorException</A>
+<BR>
+<A HREF="JavaScriptException.html" title="class in org.mozilla.javascript" target="classFrame">JavaScriptException</A>
+<BR>
+<A HREF="RhinoException.html" title="class in org.mozilla.javascript" target="classFrame">RhinoException</A>
+<BR>
+<A HREF="WrappedException.html" title="class in org.mozilla.javascript" target="classFrame">WrappedException</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-summary.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-summary.html
new file mode 100644
index 0000000..c15d3c1
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-summary.html
@@ -0,0 +1,294 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/debug/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.mozilla.javascript
+</H2>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A></B></TD>
+<TD>Generic notion of callable object that can execute some script-related code
+ upon request with specified values for script scope and this objects.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript">ClassShutter</A></B></TD>
+<TD>Embeddings that wish to filter Java classes that are visible to scripts
+through the LiveConnect, should implement this interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript">ContextAction</A></B></TD>
+<TD>Interface to represent arbitrary action that requires to have Context
+ object associated with the current thread for its execution.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript">ContextFactory.Listener</A></B></TD>
+<TD>Listener of <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A> creation and release events.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript">ErrorReporter</A></B></TD>
+<TD>This is interface defines a protocol for the reporting of
+ errors during JavaScript translation or execution.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A></B></TD>
+<TD>This is interface that all functions in JavaScript must implement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript">GeneratedClassLoader</A></B></TD>
+<TD>Interface to define classes from generated byte code.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript">RefCallable</A></B></TD>
+<TD>Object that can allows assignments to the result of function calls.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript">Script</A></B></TD>
+<TD>All compiled scripts implement this interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A></B></TD>
+<TD>This is interface that all objects in JavaScript must implement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript">Wrapper</A></B></TD>
+<TD>Objects that can wrap other values for reflection in the JS environment
+ will implement Wrapper.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript">ClassCache</A></B></TD>
+<TD>Cache of generated classes and data structures to access Java runtime
+ from JavaScript.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript">CompilerEnvirons</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript">Context</A></B></TD>
+<TD>This class represents the runtime context of an executing script.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript">ContextFactory</A></B></TD>
+<TD>Factory class that Rhino runtime uses to create new <A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><CODE>Context</CODE></A>
+ instances.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">FunctionObject</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">ImporterTopLevel</A></B></TD>
+<TD>Class ImporterTopLevel
+
+ This class defines a ScriptableObject that can be instantiated
+ as a top-level ("global") object to provide functionality similar
+ to Java's "import" statement.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A></B></TD>
+<TD>This is the default implementation of the Scriptable interface.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript">SecurityController</A></B></TD>
+<TD>This class describes the support needed to implement security.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript">Synchronizer</A></B></TD>
+<TD>This class provides support for implementing Java-style synchronized
+ methods in Javascript.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript">WrapFactory</A></B></TD>
+<TD>Embeddings that wish to provide their own custom wrappings for Java
+ objects may extend this class and call
+ <A HREF="../../../org/mozilla/javascript/Context.html#setWrapFactory(org.mozilla.javascript.WrapFactory)"><CODE>Context.setWrapFactory(WrapFactory)</CODE></A>
+ Once an instance of this class or an extension of this class is enabled
+ for a given context (by calling setWrapFactory on that context), Rhino
+ will call the methods of this class whenever it needs to wrap a value
+ resulting from a call to a Java method or an access to a Java field.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Exception Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">EcmaError</A></B></TD>
+<TD>The class of exceptions raised by the engine as described in
+ ECMA edition 3.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A></B></TD>
+<TD>The class of exceptions thrown by the JavaScript engine.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">JavaScriptException</A></B></TD>
+<TD>Java reflection of JavaScript exceptions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A></B></TD>
+<TD>The class of exceptions thrown by the JavaScript engine.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">WrappedException</A></B></TD>
+<TD>A wrapper for runtime exceptions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV PACKAGE&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/debug/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-tree.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-tree.html
new file mode 100644
index 0000000..030f3e0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/package-tree.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript Class Hierarchy (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript Class Hierarchy (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/debug/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.mozilla.javascript
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>ClassCache</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>CompilerEnvirons</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>Context</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>ContextFactory</B></A><LI TYPE="circle">org.mozilla.javascript.Delegator (implements org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>Synchronizer</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>ScriptableObject</B></A> (implements org.mozilla.javascript.ConstProperties, org.mozilla.javascript.debug.DebuggableObject, org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>, java.io.Serializable)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.IdScriptableObject (implements org.mozilla.javascript.IdFunctionCall)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.BaseFunction (implements org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>FunctionObject</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>ImporterTopLevel</B></A></UL>
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>SecurityController</B></A><LI TYPE="circle">java.lang.Throwable (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">java.lang.Exception<UL>
+<LI TYPE="circle">java.lang.RuntimeException<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>RhinoException</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>EcmaError</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>EvaluatorException</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>WrappedException</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>JavaScriptException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>WrapFactory</B></A></UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><B>Callable</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>Function</B></A> (also extends org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>)
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>RefCallable</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>ClassShutter</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>ContextAction</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>ContextFactory.Listener</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>ErrorReporter</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>GeneratedClassLoader</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>Script</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>Scriptable</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>Function</B></A> (also extends org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>)
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="../../../org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><B>Wrapper</B></A></UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;<A HREF="../../../org/mozilla/javascript/debug/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html?org/mozilla/javascript/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableInputStream.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableInputStream.html
new file mode 100644
index 0000000..f0d178f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableInputStream.html
@@ -0,0 +1,373 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+ScriptableInputStream (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ScriptableInputStream (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/ScriptableInputStream.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableInputStream.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_classes_inherited_from_class_java.io.ObjectInputStream">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript.serialize</FONT>
+<BR>
+Class ScriptableInputStream</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by ">java.io.InputStream
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by ">java.io.ObjectInputStream
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.serialize.ScriptableInputStream</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Closeable, java.io.DataInput, java.io.ObjectInput, java.io.ObjectStreamConstants</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>ScriptableInputStream</B><DT>extends java.io.ObjectInputStream</DL>
+</PRE>
+
+<P>
+Class ScriptableInputStream is used to read in a JavaScript
+ object or function previously serialized with a ScriptableOutputStream.
+ References to names in the exclusion list
+ replaced with references to the top-level scope specified during
+ creation of the ScriptableInputStream.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="nested_classes_inherited_from_class_java.io.ObjectInputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Nested classes/interfaces inherited from class java.io.ObjectInputStream</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>java.io.ObjectInputStream.GetField</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.io.ObjectStreamConstants"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.io.ObjectStreamConstants</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, STREAM_MAGIC, STREAM_VERSION, SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION, TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS, TC_CLASSDESC, TC_ENDBLOCKDATA, TC_ENUM, TC_EXCEPTION, TC_LONGSTRING, TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE, TC_RESET, TC_STRING</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html#ScriptableInputStream(java.io.InputStream, org.mozilla.javascript.Scriptable)">ScriptableInputStream</A></B>(java.io.InputStream&nbsp;in,
+ <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Create a ScriptableInputStream.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.Class</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html#resolveClass(java.io.ObjectStreamClass)">resolveClass</A></B>(java.io.ObjectStreamClass&nbsp;desc)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html#resolveObject(java.lang.Object)">resolveObject</A></B>(java.lang.Object&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.ObjectInputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.io.ObjectInputStream</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>available, close, defaultReadObject, enableResolveObject, read, read, readBoolean, readByte, readChar, readClassDescriptor, readDouble, readFields, readFloat, readFully, readFully, readInt, readLine, readLong, readObject, readObjectOverride, readShort, readStreamHeader, readUnshared, readUnsignedByte, readUnsignedShort, readUTF, registerValidation, resolveProxyClass, skipBytes</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.InputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.io.InputStream</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>mark, markSupported, read, reset, skip</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.ObjectInput"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from interface java.io.ObjectInput</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>read, skip</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ScriptableInputStream(java.io.InputStream, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+ScriptableInputStream</H3>
+<PRE>
+public <B>ScriptableInputStream</B>(java.io.InputStream&nbsp;in,
+ <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>Create a ScriptableInputStream.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>in</CODE> - the InputStream to read from.<DD><CODE>scope</CODE> - the top-level scope to create the object in.
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="resolveClass(java.io.ObjectStreamClass)"><!-- --></A><H3>
+resolveClass</H3>
+<PRE>
+protected java.lang.Class <B>resolveClass</B>(java.io.ObjectStreamClass&nbsp;desc)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>resolveClass</CODE> in class <CODE>java.io.ObjectInputStream</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="resolveObject(java.lang.Object)"><!-- --></A><H3>
+resolveObject</H3>
+<PRE>
+protected java.lang.Object <B>resolveObject</B>(java.lang.Object&nbsp;obj)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>resolveObject</CODE> in class <CODE>java.io.ObjectInputStream</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/ScriptableInputStream.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableInputStream.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_classes_inherited_from_class_java.io.ObjectInputStream">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableOutputStream.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableOutputStream.html
new file mode 100644
index 0000000..fb6d1ba
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/ScriptableOutputStream.html
@@ -0,0 +1,458 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:14 EST 2008 -->
+<TITLE>
+ScriptableOutputStream (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ScriptableOutputStream (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/ScriptableOutputStream.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableOutputStream.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_classes_inherited_from_class_java.io.ObjectOutputStream">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+org.mozilla.javascript.serialize</FONT>
+<BR>
+Class ScriptableOutputStream</H2>
+<PRE>
+java.lang.Object
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by ">java.io.OutputStream
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by ">java.io.ObjectOutputStream
+ <IMG SRC="../../../../resources/inherit.gif" ALT="extended by "><B>org.mozilla.javascript.serialize.ScriptableOutputStream</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Closeable, java.io.DataOutput, java.io.Flushable, java.io.ObjectOutput, java.io.ObjectStreamConstants</DD>
+</DL>
+<HR>
+<DL>
+<DT><PRE>public class <B>ScriptableOutputStream</B><DT>extends java.io.ObjectOutputStream</DL>
+</PRE>
+
+<P>
+Class ScriptableOutputStream is an ObjectOutputStream used
+ to serialize JavaScript objects and functions. Note that
+ compiled functions currently cannot be serialized, only
+ interpreted functions. The top-level scope containing the
+ object is not written out, but is instead replaced with
+ another top-level object when the ScriptableInputStream
+ reads in this object. Also, object corresponding to names
+ added to the exclude list are not written out but instead
+ are looked up during deserialization. This approach avoids
+ the creation of duplicate copies of standard objects
+ during deserialization.
+<P>
+
+<P>
+<DL>
+<DT><B>Author:</B></DT>
+ <DD>Norris Boyd</DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+<A NAME="nested_class_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Nested Class Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="nested_classes_inherited_from_class_java.io.ObjectOutputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Nested classes/interfaces inherited from class java.io.ObjectOutputStream</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>java.io.ObjectOutputStream.PutField</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TH>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_java.io.ObjectStreamConstants"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Fields inherited from interface java.io.ObjectStreamConstants</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, STREAM_MAGIC, STREAM_VERSION, SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION, TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS, TC_CLASSDESC, TC_ENDBLOCKDATA, TC_ENUM, TC_EXCEPTION, TC_LONGSTRING, TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE, TC_RESET, TC_STRING</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#ScriptableOutputStream(java.io.OutputStream, org.mozilla.javascript.Scriptable)">ScriptableOutputStream</A></B>(java.io.OutputStream&nbsp;out,
+ <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScriptableOutputStream constructor.</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#addExcludedName(java.lang.String)">addExcludedName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adds a qualified name to the list of object to be excluded from
+ serialization.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#addOptionalExcludedName(java.lang.String)">addOptionalExcludedName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adds a qualified name to the list of object to be excluded from
+ serialization.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#excludeStandardObjectNames()">excludeStandardObjectNames</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adds the names of the standard objects and their
+ prototypes to the list of excluded names.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#hasExcludedName(java.lang.String)">hasExcludedName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the name is excluded from serialization.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#removeExcludedName(java.lang.String)">removeExcludedName</A></B>(java.lang.String&nbsp;name)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Removes a name from the list of names to exclude.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html#replaceObject(java.lang.Object)">replaceObject</A></B>(java.lang.Object&nbsp;obj)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.io.ObjectOutputStream"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.io.ObjectOutputStream</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>annotateClass, annotateProxyClass, close, defaultWriteObject, drain, enableReplaceObject, flush, putFields, reset, useProtocolVersion, write, write, write, writeBoolean, writeByte, writeBytes, writeChar, writeChars, writeClassDescriptor, writeDouble, writeFields, writeFloat, writeInt, writeLong, writeObject, writeObjectOverride, writeShort, writeStreamHeader, writeUnshared, writeUTF</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left"><B>Methods inherited from class java.lang.Object</B></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="ScriptableOutputStream(java.io.OutputStream, org.mozilla.javascript.Scriptable)"><!-- --></A><H3>
+ScriptableOutputStream</H3>
+<PRE>
+public <B>ScriptableOutputStream</B>(java.io.OutputStream&nbsp;out,
+ <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>&nbsp;scope)
+ throws java.io.IOException</PRE>
+<DL>
+<DD>ScriptableOutputStream constructor.
+ Creates a ScriptableOutputStream for use in serializing
+ JavaScript objects. Calls excludeStandardObjectNames.
+<P>
+<DL>
+<DT><B>Parameters:</B><DD><CODE>out</CODE> - the OutputStream to write to.<DD><CODE>scope</CODE> - the scope containing the object.
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TH>
+</TR>
+</TABLE>
+
+<A NAME="addOptionalExcludedName(java.lang.String)"><!-- --></A><H3>
+addOptionalExcludedName</H3>
+<PRE>
+public void <B>addOptionalExcludedName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Adds a qualified name to the list of object to be excluded from
+ serialization. Names excluded from serialization are looked up
+ in the new scope and replaced upon deserialization.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - a fully qualified name (of the form "a.b.c", where
+ "a" must be a property of the top-level object). The object
+ need not exist, in which case the name is ignored.
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if the object is not a
+ <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="addExcludedName(java.lang.String)"><!-- --></A><H3>
+addExcludedName</H3>
+<PRE>
+public void <B>addExcludedName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Adds a qualified name to the list of object to be excluded from
+ serialization. Names excluded from serialization are looked up
+ in the new scope and replaced upon deserialization.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>name</CODE> - a fully qualified name (of the form "a.b.c", where
+ "a" must be a property of the top-level object)
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.IllegalArgumentException</CODE> - if the object is not found or is not
+ a <A HREF="../../../../org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><CODE>Scriptable</CODE></A>.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasExcludedName(java.lang.String)"><!-- --></A><H3>
+hasExcludedName</H3>
+<PRE>
+public boolean <B>hasExcludedName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Returns true if the name is excluded from serialization.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="removeExcludedName(java.lang.String)"><!-- --></A><H3>
+removeExcludedName</H3>
+<PRE>
+public void <B>removeExcludedName</B>(java.lang.String&nbsp;name)</PRE>
+<DL>
+<DD>Removes a name from the list of names to exclude.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="excludeStandardObjectNames()"><!-- --></A><H3>
+excludeStandardObjectNames</H3>
+<PRE>
+public void <B>excludeStandardObjectNames</B>()</PRE>
+<DL>
+<DD>Adds the names of the standard objects and their
+ prototypes to the list of excluded names.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="replaceObject(java.lang.Object)"><!-- --></A><H3>
+replaceObject</H3>
+<PRE>
+protected java.lang.Object <B>replaceObject</B>(java.lang.Object&nbsp;obj)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>replaceObject</CODE> in class <CODE>java.io.ObjectOutputStream</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/ScriptableOutputStream.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="ScriptableOutputStream.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY:&nbsp;<A HREF="#nested_classes_inherited_from_class_java.io.ObjectOutputStream">NESTED</A>&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-frame.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-frame.html
new file mode 100644
index 0000000..39d85e2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-frame.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.serialize (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../../org/mozilla/javascript/serialize/package-summary.html" target="classFrame">org.mozilla.javascript.serialize</A></FONT>
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>&nbsp;
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize" target="classFrame">ScriptableInputStream</A>
+<BR>
+<A HREF="ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize" target="classFrame">ScriptableOutputStream</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-summary.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-summary.html
new file mode 100644
index 0000000..568f562
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-summary.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.serialize (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.serialize (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<H2>
+Package org.mozilla.javascript.serialize
+</H2>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableInputStream</A></B></TD>
+<TD>Class ScriptableInputStream is used to read in a JavaScript
+ object or function previously serialized with a ScriptableOutputStream.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize">ScriptableOutputStream</A></B></TD>
+<TD>Class ScriptableOutputStream is an ObjectOutputStream used
+ to serialize JavaScript objects and functions.</TD>
+</TR>
+</TABLE>
+&nbsp;
+
+<P>
+<DL>
+</DL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-summary.html"><B>PREV PACKAGE</B></A>&nbsp;
+&nbsp;NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/package-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-tree.html b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-tree.html
new file mode 100644
index 0000000..e672261
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/org/mozilla/javascript/serialize/package-tree.html
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+org.mozilla.javascript.serialize Class Hierarchy (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="org.mozilla.javascript.serialize Class Hierarchy (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package org.mozilla.javascript.serialize
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="../../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">java.io.InputStream (implements java.io.Closeable)
+<UL>
+<LI TYPE="circle">java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.serialize.<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableInputStream</B></A></UL>
+</UL>
+<LI TYPE="circle">java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)
+<UL>
+<LI TYPE="circle">java.io.ObjectOutputStream (implements java.io.ObjectOutput, java.io.ObjectStreamConstants)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.serialize.<A HREF="../../../../org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableOutputStream</B></A></UL>
+</UL>
+</UL>
+</UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="../../../../org/mozilla/javascript/optimizer/package-tree.html"><B>PREV</B></A>&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../../index.html?org/mozilla/javascript/serialize/package-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="package-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="../../../../allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/overview-frame.html b/infrastructure/rhino1_7R1/javadoc/overview-frame.html
new file mode 100644
index 0000000..10e9be0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/overview-frame.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:15 EST 2008 -->
+<TITLE>
+Overview List (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+
+</HEAD>
+
+<BODY BGCOLOR="white">
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TH ALIGN="left" NOWRAP><FONT size="+1" CLASS="FrameTitleFont">
+<B></B></FONT></TH>
+</TR>
+</TABLE>
+
+<TABLE BORDER="0" WIDTH="100%" SUMMARY="">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="allclasses-frame.html" target="packageFrame">All Classes</A></FONT>
+<P>
+<FONT size="+1" CLASS="FrameHeadingFont">
+Packages</FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/package-frame.html" target="packageFrame">org.mozilla.javascript</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/debug/package-frame.html" target="packageFrame">org.mozilla.javascript.debug</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/optimizer/package-frame.html" target="packageFrame">org.mozilla.javascript.optimizer</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="org/mozilla/javascript/serialize/package-frame.html" target="packageFrame">org.mozilla.javascript.serialize</A></FONT>
+<BR>
+</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/overview-summary.html b/infrastructure/rhino1_7R1/javadoc/overview-summary.html
new file mode 100644
index 0000000..043bb30
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/overview-summary.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Overview (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Overview (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Packages</B></FONT></TH>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/mozilla/javascript/package-summary.html">org.mozilla.javascript</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/mozilla/javascript/debug/package-summary.html">org.mozilla.javascript.debug</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/mozilla/javascript/optimizer/package-summary.html">org.mozilla.javascript.optimizer</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="org/mozilla/javascript/serialize/package-summary.html">org.mozilla.javascript.serialize</A></B></TD>
+<TD>&nbsp;</TD>
+</TR>
+</TABLE>
+
+<P>
+&nbsp;<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?overview-summary.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-summary.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/overview-tree.html b/infrastructure/rhino1_7R1/javadoc/overview-tree.html
new file mode 100644
index 0000000..9c5398c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/overview-tree.html
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Class Hierarchy (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Class Hierarchy (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For All Packages</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies:</B><DD><A HREF="org/mozilla/javascript/package-tree.html">org.mozilla.javascript</A>, <A HREF="org/mozilla/javascript/debug/package-tree.html">org.mozilla.javascript.debug</A>, <A HREF="org/mozilla/javascript/optimizer/package-tree.html">org.mozilla.javascript.optimizer</A>, <A HREF="org/mozilla/javascript/serialize/package-tree.html">org.mozilla.javascript.serialize</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">java.lang.Object<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ClassCache.html" title="class in org.mozilla.javascript"><B>ClassCache</B></A><LI TYPE="circle">org.mozilla.javascript.optimizer.<A HREF="org/mozilla/javascript/optimizer/ClassCompiler.html" title="class in org.mozilla.javascript.optimizer"><B>ClassCompiler</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/CompilerEnvirons.html" title="class in org.mozilla.javascript"><B>CompilerEnvirons</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Context.html" title="class in org.mozilla.javascript"><B>Context</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ContextFactory.html" title="class in org.mozilla.javascript"><B>ContextFactory</B></A><LI TYPE="circle">org.mozilla.javascript.Delegator (implements org.mozilla.javascript.<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Synchronizer.html" title="class in org.mozilla.javascript"><B>Synchronizer</B></A></UL>
+<LI TYPE="circle">java.io.InputStream (implements java.io.Closeable)
+<UL>
+<LI TYPE="circle">java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.serialize.<A HREF="org/mozilla/javascript/serialize/ScriptableInputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableInputStream</B></A></UL>
+</UL>
+<LI TYPE="circle">java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)
+<UL>
+<LI TYPE="circle">java.io.ObjectOutputStream (implements java.io.ObjectOutput, java.io.ObjectStreamConstants)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.serialize.<A HREF="org/mozilla/javascript/serialize/ScriptableOutputStream.html" title="class in org.mozilla.javascript.serialize"><B>ScriptableOutputStream</B></A></UL>
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript"><B>ScriptableObject</B></A> (implements org.mozilla.javascript.ConstProperties, org.mozilla.javascript.debug.DebuggableObject, org.mozilla.javascript.<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>, java.io.Serializable)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.IdScriptableObject (implements org.mozilla.javascript.IdFunctionCall)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.BaseFunction (implements org.mozilla.javascript.<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript">Function</A>)
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript"><B>FunctionObject</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript"><B>ImporterTopLevel</B></A></UL>
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/SecurityController.html" title="class in org.mozilla.javascript"><B>SecurityController</B></A><LI TYPE="circle">java.lang.Throwable (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">java.lang.Exception<UL>
+<LI TYPE="circle">java.lang.RuntimeException<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript"><B>RhinoException</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript"><B>EcmaError</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript"><B>EvaluatorException</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript"><B>WrappedException</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript"><B>JavaScriptException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/WrapFactory.html" title="class in org.mozilla.javascript"><B>WrapFactory</B></A></UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript"><B>Callable</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>Function</B></A> (also extends org.mozilla.javascript.<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A>)
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/RefCallable.html" title="interface in org.mozilla.javascript"><B>RefCallable</B></A></UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ClassShutter.html" title="interface in org.mozilla.javascript"><B>ClassShutter</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ContextAction.html" title="interface in org.mozilla.javascript"><B>ContextAction</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ContextFactory.Listener.html" title="interface in org.mozilla.javascript"><B>ContextFactory.Listener</B></A><LI TYPE="circle">org.mozilla.javascript.debug.<A HREF="org/mozilla/javascript/debug/DebuggableScript.html" title="interface in org.mozilla.javascript.debug"><B>DebuggableScript</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/ErrorReporter.html" title="interface in org.mozilla.javascript"><B>ErrorReporter</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/GeneratedClassLoader.html" title="interface in org.mozilla.javascript"><B>GeneratedClassLoader</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Script.html" title="interface in org.mozilla.javascript"><B>Script</B></A><LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript"><B>Scriptable</B></A><UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Function.html" title="interface in org.mozilla.javascript"><B>Function</B></A> (also extends org.mozilla.javascript.<A HREF="org/mozilla/javascript/Callable.html" title="interface in org.mozilla.javascript">Callable</A>)
+</UL>
+<LI TYPE="circle">org.mozilla.javascript.<A HREF="org/mozilla/javascript/Wrapper.html" title="interface in org.mozilla.javascript"><B>Wrapper</B></A></UL>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?overview-tree.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="overview-tree.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/package-list b/infrastructure/rhino1_7R1/javadoc/package-list
new file mode 100644
index 0000000..62fc06b
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/package-list
@@ -0,0 +1,4 @@
+org.mozilla.javascript
+org.mozilla.javascript.debug
+org.mozilla.javascript.optimizer
+org.mozilla.javascript.serialize
diff --git a/infrastructure/rhino1_7R1/javadoc/resources/inherit.gif b/infrastructure/rhino1_7R1/javadoc/resources/inherit.gif
new file mode 100644
index 0000000..c814867
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/resources/inherit.gif
Binary files differ
diff --git a/infrastructure/rhino1_7R1/javadoc/serialized-form.html b/infrastructure/rhino1_7R1/javadoc/serialized-form.html
new file mode 100644
index 0000000..c022624
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/serialized-form.html
@@ -0,0 +1,1652 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc (build 1.6.0) on Thu Mar 06 17:19:16 EST 2008 -->
+<TITLE>
+Serialized Form (Rhino)
+</TITLE>
+
+<META NAME="date" CONTENT="2008-03-06">
+
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+
+<SCRIPT type="text/javascript">
+function windowTitle()
+{
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Serialized Form (Rhino)";
+ }
+}
+</SCRIPT>
+<NOSCRIPT>
+</NOSCRIPT>
+
+</HEAD>
+
+<BODY BGCOLOR="white" onload="windowTitle();">
+<HR>
+
+
+<!-- ========= START OF TOP NAVBAR ======= -->
+<A NAME="navbar_top"><!-- --></A>
+<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?serialized-form.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="serialized-form.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_top"></A>
+<!-- ========= END OF TOP NAVBAR ========= -->
+
+<HR>
+<CENTER>
+<H1>
+Serialized Form</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>org.mozilla.javascript</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="org.mozilla.javascript.BaseFunction"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.BaseFunction extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>5311394446546053859L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+prototypeProperty</H3>
+<PRE>
+java.lang.Object <B>prototypeProperty</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+prototypePropertyAttributes</H3>
+<PRE>
+int <B>prototypePropertyAttributes</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.EcmaError"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/EcmaError.html" title="class in org.mozilla.javascript">org.mozilla.javascript.EcmaError</A> extends <A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-6261226256957286699L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+errorName</H3>
+<PRE>
+java.lang.String <B>errorName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+errorMessage</H3>
+<PRE>
+java.lang.String <B>errorMessage</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.EvaluatorException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.EvaluatorException</A> extends <A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-8743165779676009808L
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.FunctionObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/FunctionObject.html" title="class in org.mozilla.javascript">org.mozilla.javascript.FunctionObject</A> extends org.mozilla.javascript.BaseFunction implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-5332312783643935019L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;in)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+member</H3>
+<PRE>
+org.mozilla.javascript.MemberBox <B>member</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+functionName</H3>
+<PRE>
+java.lang.String <B>functionName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+parmsLength</H3>
+<PRE>
+int <B>parmsLength</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+isStatic</H3>
+<PRE>
+boolean <B>isStatic</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.IdFunctionObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.IdFunctionObject extends org.mozilla.javascript.BaseFunction implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-5332312783643935019L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+idcall</H3>
+<PRE>
+org.mozilla.javascript.IdFunctionCall <B>idcall</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+tag</H3>
+<PRE>
+java.lang.Object <B>tag</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+methodId</H3>
+<PRE>
+int <B>methodId</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+arity</H3>
+<PRE>
+int <B>arity</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+useCallAsConstructor</H3>
+<PRE>
+boolean <B>useCallAsConstructor</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+functionName</H3>
+<PRE>
+java.lang.String <B>functionName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.IdScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.IdScriptableObject extends <A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;stream)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;stream)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.ImporterTopLevel"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/ImporterTopLevel.html" title="class in org.mozilla.javascript">org.mozilla.javascript.ImporterTopLevel</A> extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-9095380847465315412L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+importedPackages</H3>
+<PRE>
+org.mozilla.javascript.ObjArray <B>importedPackages</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+topScopeFlag</H3>
+<PRE>
+boolean <B>topScopeFlag</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.JavaScriptException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/JavaScriptException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.JavaScriptException</A> extends <A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">RhinoException</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-7666130513694669293L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+value</H3>
+<PRE>
+java.lang.Object <B>value</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.LazilyLoadedCtor"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.LazilyLoadedCtor extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>1L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+scope</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A> <B>scope</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+propertyName</H3>
+<PRE>
+java.lang.String <B>propertyName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+className</H3>
+<PRE>
+java.lang.String <B>className</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sealed</H3>
+<PRE>
+boolean <B>sealed</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+initializedValue</H3>
+<PRE>
+java.lang.Object <B>initializedValue</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+state</H3>
+<PRE>
+int <B>state</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeArray"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeArray extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>7331366857676127338L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+length</H3>
+<PRE>
+long <B>length</B></PRE>
+<DL>
+<DD>Internal representation of the JavaScript array's length property.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+dense</H3>
+<PRE>
+java.lang.Object[] <B>dense</B></PRE>
+<DL>
+<DD>Fast storage for dense arrays. Sparse arrays will use the superclass's
+ hashtable storage scheme.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+denseOnly</H3>
+<PRE>
+boolean <B>denseOnly</B></PRE>
+<DL>
+<DD>True if all numeric properties are stored in <code>dense</code>.
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeCall"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeCall extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-7471457301304454454L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+function</H3>
+<PRE>
+org.mozilla.javascript.NativeFunction <B>function</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+originalArgs</H3>
+<PRE>
+java.lang.Object[] <B>originalArgs</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeFunction"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeFunction extends org.mozilla.javascript.BaseFunction implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeGenerator"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeGenerator extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+function</H3>
+<PRE>
+org.mozilla.javascript.NativeFunction <B>function</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+savedState</H3>
+<PRE>
+java.lang.Object <B>savedState</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lineSource</H3>
+<PRE>
+java.lang.String <B>lineSource</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lineNumber</H3>
+<PRE>
+int <B>lineNumber</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+firstTime</H3>
+<PRE>
+boolean <B>firstTime</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+locked</H3>
+<PRE>
+boolean <B>locked</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeGenerator.GeneratorClosedException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeGenerator.GeneratorClosedException extends java.lang.RuntimeException implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeGlobal"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeGlobal extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>6080442165748707530L
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeIterator"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeIterator extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+objectIterator</H3>
+<PRE>
+java.lang.Object <B>objectIterator</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaArray"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaArray extends org.mozilla.javascript.NativeJavaObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-924022554283675333L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+array</H3>
+<PRE>
+java.lang.Object <B>array</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+length</H3>
+<PRE>
+int <B>length</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+cls</H3>
+<PRE>
+java.lang.Class&lt;T&gt; <B>cls</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaClass"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaClass extends org.mozilla.javascript.NativeJavaObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-6460763940409461664L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+staticFieldAndMethods</H3>
+<PRE>
+java.util.Hashtable&lt;K,V&gt; <B>staticFieldAndMethods</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaConstructor"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaConstructor extends org.mozilla.javascript.BaseFunction implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-8149253217482668463L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+ctor</H3>
+<PRE>
+org.mozilla.javascript.MemberBox <B>ctor</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaMethod"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaMethod extends org.mozilla.javascript.BaseFunction implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-3440381785576412928L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+methods</H3>
+<PRE>
+org.mozilla.javascript.MemberBox[] <B>methods</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+functionName</H3>
+<PRE>
+java.lang.String <B>functionName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaObject extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-6948590651130498591L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;in)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;out)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+prototype</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>prototype</B></PRE>
+<DL>
+<DD>The prototype of this object.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+parent</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>parent</B></PRE>
+<DL>
+<DD>The parent scope of this object.
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaPackage"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaPackage extends <A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">ScriptableObject</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>7445054382212031523L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+packageName</H3>
+<PRE>
+java.lang.String <B>packageName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+classLoader</H3>
+<PRE>
+java.lang.ClassLoader <B>classLoader</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeJavaTopPackage"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeJavaTopPackage extends org.mozilla.javascript.NativeJavaPackage implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-1455787259477709999L
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeObject extends org.mozilla.javascript.IdScriptableObject implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-6345305608474346996L
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.NativeWith"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.NativeWith extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>1L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+prototype</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>prototype</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+parent</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>parent</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.ObjArray"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.ObjArray extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>4174889037736658296L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;is)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;os)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+size</H3>
+<PRE>
+int <B>size</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+sealed</H3>
+<PRE>
+boolean <B>sealed</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.ObjToIntMap"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.ObjToIntMap extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-1542220580748809402L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;in)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;out)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+power</H3>
+<PRE>
+int <B>power</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+keyCount</H3>
+<PRE>
+int <B>keyCount</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.Ref"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.Ref extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<A NAME="org.mozilla.javascript.RhinoException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/RhinoException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.RhinoException</A> extends java.lang.RuntimeException implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+sourceName</H3>
+<PRE>
+java.lang.String <B>sourceName</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lineNumber</H3>
+<PRE>
+int <B>lineNumber</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+lineSource</H3>
+<PRE>
+java.lang.String <B>lineSource</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+columnNumber</H3>
+<PRE>
+int <B>columnNumber</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+interpreterStackInfo</H3>
+<PRE>
+java.lang.Object <B>interpreterStackInfo</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+interpreterLineData</H3>
+<PRE>
+int[] <B>interpreterLineData</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.ScriptableObject"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/ScriptableObject.html" title="class in org.mozilla.javascript">org.mozilla.javascript.ScriptableObject</A> extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;in)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;out)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+prototypeObject</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>prototypeObject</B></PRE>
+<DL>
+<DD>The prototype of this object.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+parentScopeObject</H3>
+<PRE>
+<A HREF="org/mozilla/javascript/Scriptable.html" title="interface in org.mozilla.javascript">Scriptable</A> <B>parentScopeObject</B></PRE>
+<DL>
+<DD>The parent scope of this object.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+count</H3>
+<PRE>
+int <B>count</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.UintMap"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.UintMap extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>4242698212885848444L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readObject(java.io.ObjectInputStream)"><!-- --></A><H3>
+readObject</H3>
+<PRE>
+private void <B>readObject</B>(java.io.ObjectInputStream&nbsp;in)
+ throws java.io.IOException,
+ java.lang.ClassNotFoundException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE>
+<DD><CODE>java.lang.ClassNotFoundException</CODE></DD>
+</DL>
+</DL>
+<HR>
+<A NAME="writeObject(java.io.ObjectOutputStream)"><!-- --></A><H3>
+writeObject</H3>
+<PRE>
+private void <B>writeObject</B>(java.io.ObjectOutputStream&nbsp;out)
+ throws java.io.IOException</PRE>
+<DL>
+<DD><DL>
+
+<DT><B>Throws:</B>
+<DD><CODE>java.io.IOException</CODE></DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+power</H3>
+<PRE>
+int <B>power</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+<H3>
+keyCount</H3>
+<PRE>
+int <B>keyCount</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.Undefined"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.Undefined extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>9195680630202616767L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readResolve()"><!-- --></A><H3>
+readResolve</H3>
+<PRE>
+public java.lang.Object <B>readResolve</B>()</PRE>
+<DL>
+<DD><DL>
+</DD>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.UniqueTag"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class org.mozilla.javascript.UniqueTag extends java.lang.Object implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-4320556826714577259L
+
+<P>
+<A NAME="serialized_methods"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialization Methods</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="readResolve()"><!-- --></A><H3>
+readResolve</H3>
+<PRE>
+public java.lang.Object <B>readResolve</B>()</PRE>
+<DL>
+<DD><DL>
+</DD>
+</DL>
+</DL>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+tagId</H3>
+<PRE>
+int <B>tagId</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<A NAME="org.mozilla.javascript.WrappedException"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
+<B>Class <A HREF="org/mozilla/javascript/WrappedException.html" title="class in org.mozilla.javascript">org.mozilla.javascript.WrappedException</A> extends <A HREF="org/mozilla/javascript/EvaluatorException.html" title="class in org.mozilla.javascript">EvaluatorException</A> implements Serializable</B></FONT></TH>
+</TR>
+</TABLE>
+
+<P>
+<B>serialVersionUID:&nbsp;</B>-1551979216966520648L
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TH>
+</TR>
+</TABLE>
+
+<H3>
+exception</H3>
+<PRE>
+java.lang.Throwable <B>exception</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR>
+
+
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html?serialized-form.html" target="_top"><B>FRAMES</B></A> &nbsp;
+&nbsp;<A HREF="serialized-form.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
+&nbsp;<SCRIPT type="text/javascript">
+ <!--
+ if(window==top) {
+ document.writeln('<A HREF="allclasses-noframe.html"><B>All Classes</B></A>');
+ }
+ //-->
+</SCRIPT>
+<NOSCRIPT>
+ <A HREF="allclasses-noframe.html"><B>All Classes</B></A>
+</NOSCRIPT>
+
+
+</FONT></TD>
+</TR>
+</TABLE>
+<A NAME="skip-navbar_bottom"></A>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+
+<HR>
+
+</BODY>
+</HTML>
diff --git a/infrastructure/rhino1_7R1/javadoc/stylesheet.css b/infrastructure/rhino1_7R1/javadoc/stylesheet.css
new file mode 100644
index 0000000..6ea9e51
--- /dev/null
+++ b/infrastructure/rhino1_7R1/javadoc/stylesheet.css
@@ -0,0 +1,29 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color */
+body { background-color: #FFFFFF; color:#000000 }
+
+/* Headings */
+h1 { font-size: 145% }
+
+/* Table colors */
+.TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */
+.TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */
+.TableRowColor { background: #FFFFFF; color:#000000 } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
+.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
+.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
+
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */
+.NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */
+.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;}
+
+.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
+.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
+
diff --git a/infrastructure/rhino1_7R1/lib/jsr173_1.0_api.jar b/infrastructure/rhino1_7R1/lib/jsr173_1.0_api.jar
new file mode 100644
index 0000000..fef9a9c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/lib/jsr173_1.0_api.jar
Binary files differ
diff --git a/infrastructure/rhino1_7R1/lib/xbean.jar b/infrastructure/rhino1_7R1/lib/xbean.jar
new file mode 100644
index 0000000..8a4dff4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/lib/xbean.jar
Binary files differ
diff --git a/infrastructure/rhino1_7R1/src/build.xml b/infrastructure/rhino1_7R1/src/build.xml
new file mode 100644
index 0000000..a0a1e13
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/build.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<!--
+Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
+Requires Ant version 1.2
+-->
+<project name="src" default="compile" basedir="..">
+
+ <property file="build.properties"/>
+
+ <available property="jdk15"
+ classname="java.lang.reflect.ParameterizedType" />
+
+ <target name="compile" depends="compile-most,compile-jdk15">
+ </target>
+
+ <target name="compile-most">
+ <javac srcdir="src"
+ destdir="${classes}"
+ includes="org/**/*.java"
+ excludes="org/**/jdk15/*.java"
+ deprecation="on"
+ debug="${debug}"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ </javac>
+ <copy todir="${classes}">
+ <fileset dir="src" includes="org/**/*.properties" />
+ <filterset>
+ <filter token="IMPLEMENTATION.VERSION"
+ value="${implementation.version}"/>
+ </filterset>
+ </copy>
+ </target>
+
+ <target name="compile-jdk15" if="jdk15">
+ <javac srcdir="src"
+ destdir="${classes}"
+ includes="org/**/jdk15/*.java"
+ deprecation="on"
+ debug="${debug}"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ </javac>
+ </target>
+
+ <target name="copy-source">
+ <mkdir dir="${dist.dir}/src"/>
+ <copy todir="${dist.dir}/src">
+ <fileset dir="src"
+ includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
+ </copy>
+ </target>
+
+ <target name="clean">
+ <delete includeEmptyDirs="true">
+ <fileset dir="${classes}"
+ excludes="org/mozilla/javascript/tools/**"/>
+ </delete>
+ </target>
+
+</project>
diff --git a/infrastructure/rhino1_7R1/src/manifest b/infrastructure/rhino1_7R1/src/manifest
new file mode 100644
index 0000000..b7d0c06
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/manifest
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: org.mozilla.javascript.tools.shell.Main
+Class-Path: xbean.jar
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java b/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java
new file mode 100644
index 0000000..fa4713e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ByteCode.java
@@ -0,0 +1,274 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.classfile;
+
+/**
+ * This class provides opcode values expected by the JVM in Java class files.
+ *
+ * It also provides tables for internal use by the ClassFileWriter.
+ *
+ * @author Roger Lawrence
+ */
+public class ByteCode {
+
+ /**
+ * The byte opcodes defined by the Java Virtual Machine.
+ */
+ public static final int
+ NOP = 0x00,
+ ACONST_NULL = 0x01,
+ ICONST_M1 = 0x02,
+ ICONST_0 = 0x03,
+ ICONST_1 = 0x04,
+ ICONST_2 = 0x05,
+ ICONST_3 = 0x06,
+ ICONST_4 = 0x07,
+ ICONST_5 = 0x08,
+ LCONST_0 = 0x09,
+ LCONST_1 = 0x0A,
+ FCONST_0 = 0x0B,
+ FCONST_1 = 0x0C,
+ FCONST_2 = 0x0D,
+ DCONST_0 = 0x0E,
+ DCONST_1 = 0x0F,
+ BIPUSH = 0x10,
+ SIPUSH = 0x11,
+ LDC = 0x12,
+ LDC_W = 0x13,
+ LDC2_W = 0x14,
+ ILOAD = 0x15,
+ LLOAD = 0x16,
+ FLOAD = 0x17,
+ DLOAD = 0x18,
+ ALOAD = 0x19,
+ ILOAD_0 = 0x1A,
+ ILOAD_1 = 0x1B,
+ ILOAD_2 = 0x1C,
+ ILOAD_3 = 0x1D,
+ LLOAD_0 = 0x1E,
+ LLOAD_1 = 0x1F,
+ LLOAD_2 = 0x20,
+ LLOAD_3 = 0x21,
+ FLOAD_0 = 0x22,
+ FLOAD_1 = 0x23,
+ FLOAD_2 = 0x24,
+ FLOAD_3 = 0x25,
+ DLOAD_0 = 0x26,
+ DLOAD_1 = 0x27,
+ DLOAD_2 = 0x28,
+ DLOAD_3 = 0x29,
+ ALOAD_0 = 0x2A,
+ ALOAD_1 = 0x2B,
+ ALOAD_2 = 0x2C,
+ ALOAD_3 = 0x2D,
+ IALOAD = 0x2E,
+ LALOAD = 0x2F,
+ FALOAD = 0x30,
+ DALOAD = 0x31,
+ AALOAD = 0x32,
+ BALOAD = 0x33,
+ CALOAD = 0x34,
+ SALOAD = 0x35,
+ ISTORE = 0x36,
+ LSTORE = 0x37,
+ FSTORE = 0x38,
+ DSTORE = 0x39,
+ ASTORE = 0x3A,
+ ISTORE_0 = 0x3B,
+ ISTORE_1 = 0x3C,
+ ISTORE_2 = 0x3D,
+ ISTORE_3 = 0x3E,
+ LSTORE_0 = 0x3F,
+ LSTORE_1 = 0x40,
+ LSTORE_2 = 0x41,
+ LSTORE_3 = 0x42,
+ FSTORE_0 = 0x43,
+ FSTORE_1 = 0x44,
+ FSTORE_2 = 0x45,
+ FSTORE_3 = 0x46,
+ DSTORE_0 = 0x47,
+ DSTORE_1 = 0x48,
+ DSTORE_2 = 0x49,
+ DSTORE_3 = 0x4A,
+ ASTORE_0 = 0x4B,
+ ASTORE_1 = 0x4C,
+ ASTORE_2 = 0x4D,
+ ASTORE_3 = 0x4E,
+ IASTORE = 0x4F,
+ LASTORE = 0x50,
+ FASTORE = 0x51,
+ DASTORE = 0x52,
+ AASTORE = 0x53,
+ BASTORE = 0x54,
+ CASTORE = 0x55,
+ SASTORE = 0x56,
+ POP = 0x57,
+ POP2 = 0x58,
+ DUP = 0x59,
+ DUP_X1 = 0x5A,
+ DUP_X2 = 0x5B,
+ DUP2 = 0x5C,
+ DUP2_X1 = 0x5D,
+ DUP2_X2 = 0x5E,
+ SWAP = 0x5F,
+ IADD = 0x60,
+ LADD = 0x61,
+ FADD = 0x62,
+ DADD = 0x63,
+ ISUB = 0x64,
+ LSUB = 0x65,
+ FSUB = 0x66,
+ DSUB = 0x67,
+ IMUL = 0x68,
+ LMUL = 0x69,
+ FMUL = 0x6A,
+ DMUL = 0x6B,
+ IDIV = 0x6C,
+ LDIV = 0x6D,
+ FDIV = 0x6E,
+ DDIV = 0x6F,
+ IREM = 0x70,
+ LREM = 0x71,
+ FREM = 0x72,
+ DREM = 0x73,
+ INEG = 0x74,
+ LNEG = 0x75,
+ FNEG = 0x76,
+ DNEG = 0x77,
+ ISHL = 0x78,
+ LSHL = 0x79,
+ ISHR = 0x7A,
+ LSHR = 0x7B,
+ IUSHR = 0x7C,
+ LUSHR = 0x7D,
+ IAND = 0x7E,
+ LAND = 0x7F,
+ IOR = 0x80,
+ LOR = 0x81,
+ IXOR = 0x82,
+ LXOR = 0x83,
+ IINC = 0x84,
+ I2L = 0x85,
+ I2F = 0x86,
+ I2D = 0x87,
+ L2I = 0x88,
+ L2F = 0x89,
+ L2D = 0x8A,
+ F2I = 0x8B,
+ F2L = 0x8C,
+ F2D = 0x8D,
+ D2I = 0x8E,
+ D2L = 0x8F,
+ D2F = 0x90,
+ I2B = 0x91,
+ I2C = 0x92,
+ I2S = 0x93,
+ LCMP = 0x94,
+ FCMPL = 0x95,
+ FCMPG = 0x96,
+ DCMPL = 0x97,
+ DCMPG = 0x98,
+ IFEQ = 0x99,
+ IFNE = 0x9A,
+ IFLT = 0x9B,
+ IFGE = 0x9C,
+ IFGT = 0x9D,
+ IFLE = 0x9E,
+ IF_ICMPEQ = 0x9F,
+ IF_ICMPNE = 0xA0,
+ IF_ICMPLT = 0xA1,
+ IF_ICMPGE = 0xA2,
+ IF_ICMPGT = 0xA3,
+ IF_ICMPLE = 0xA4,
+ IF_ACMPEQ = 0xA5,
+ IF_ACMPNE = 0xA6,
+ GOTO = 0xA7,
+ JSR = 0xA8,
+ RET = 0xA9,
+ TABLESWITCH = 0xAA,
+ LOOKUPSWITCH = 0xAB,
+ IRETURN = 0xAC,
+ LRETURN = 0xAD,
+ FRETURN = 0xAE,
+ DRETURN = 0xAF,
+ ARETURN = 0xB0,
+ RETURN = 0xB1,
+ GETSTATIC = 0xB2,
+ PUTSTATIC = 0xB3,
+ GETFIELD = 0xB4,
+ PUTFIELD = 0xB5,
+ INVOKEVIRTUAL = 0xB6,
+ INVOKESPECIAL = 0xB7,
+ INVOKESTATIC = 0xB8,
+ INVOKEINTERFACE = 0xB9,
+ NEW = 0xBB,
+ NEWARRAY = 0xBC,
+ ANEWARRAY = 0xBD,
+ ARRAYLENGTH = 0xBE,
+ ATHROW = 0xBF,
+ CHECKCAST = 0xC0,
+ INSTANCEOF = 0xC1,
+ MONITORENTER = 0xC2,
+ MONITOREXIT = 0xC3,
+ WIDE = 0xC4,
+ MULTIANEWARRAY = 0xC5,
+ IFNULL = 0xC6,
+ IFNONNULL = 0xC7,
+ GOTO_W = 0xC8,
+ JSR_W = 0xC9,
+ BREAKPOINT = 0xCA,
+
+ IMPDEP1 = 0xFE,
+ IMPDEP2 = 0xFF;
+
+ /**
+ * Types for the NEWARRAY opcode.
+ */
+ public static final byte
+ T_BOOLEAN = 4,
+ T_CHAR = 5,
+ T_FLOAT = 6,
+ T_DOUBLE = 7,
+ T_BYTE = 8,
+ T_SHORT = 9,
+ T_INT = 10,
+ T_LONG = 11;
+
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java b/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java
new file mode 100644
index 0000000..b9c6c96
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/classfile/ClassFileWriter.java
@@ -0,0 +1,3038 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.classfile;
+
+import org.mozilla.javascript.ObjToIntMap;
+import org.mozilla.javascript.ObjArray;
+import org.mozilla.javascript.UintMap;
+
+import java.io.*;
+
+/**
+ * ClassFileWriter
+ *
+ * A ClassFileWriter is used to write a Java class file. Methods are
+ * provided to create fields and methods, and within methods to write
+ * Java bytecodes.
+ *
+ * @author Roger Lawrence
+ */
+public class ClassFileWriter {
+
+ /**
+ * Thrown for cases where the error in generating the class file is
+ * due to a program size constraints rather than a likely bug in the
+ * compiler.
+ */
+ public static class ClassFileFormatException extends RuntimeException {
+ ClassFileFormatException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Construct a ClassFileWriter for a class.
+ *
+ * @param className the name of the class to write, including
+ * full package qualification.
+ * @param superClassName the name of the superclass of the class
+ * to write, including full package qualification.
+ * @param sourceFileName the name of the source file to use for
+ * producing debug information, or null if debug information
+ * is not desired
+ */
+ public ClassFileWriter(String className, String superClassName,
+ String sourceFileName)
+ {
+ generatedClassName = className;
+ itsConstantPool = new ConstantPool(this);
+ itsThisClassIndex = itsConstantPool.addClass(className);
+ itsSuperClassIndex = itsConstantPool.addClass(superClassName);
+ if (sourceFileName != null)
+ itsSourceFileNameIndex = itsConstantPool.addUtf8(sourceFileName);
+ itsFlags = ACC_PUBLIC;
+ }
+
+ public final String getClassName()
+ {
+ return generatedClassName;
+ }
+
+ /**
+ * Add an interface implemented by this class.
+ *
+ * This method may be called multiple times for classes that
+ * implement multiple interfaces.
+ *
+ * @param interfaceName a name of an interface implemented
+ * by the class being written, including full package
+ * qualification.
+ */
+ public void addInterface(String interfaceName) {
+ short interfaceIndex = itsConstantPool.addClass(interfaceName);
+ itsInterfaces.add(new Short(interfaceIndex));
+ }
+
+ public static final short
+ ACC_PUBLIC = 0x0001,
+ ACC_PRIVATE = 0x0002,
+ ACC_PROTECTED = 0x0004,
+ ACC_STATIC = 0x0008,
+ ACC_FINAL = 0x0010,
+ ACC_SYNCHRONIZED = 0x0020,
+ ACC_VOLATILE = 0x0040,
+ ACC_TRANSIENT = 0x0080,
+ ACC_NATIVE = 0x0100,
+ ACC_ABSTRACT = 0x0400;
+
+ /**
+ * Set the class's flags.
+ *
+ * Flags must be a set of the following flags, bitwise or'd
+ * together:
+ * ACC_PUBLIC
+ * ACC_PRIVATE
+ * ACC_PROTECTED
+ * ACC_FINAL
+ * ACC_ABSTRACT
+ * TODO: check that this is the appropriate set
+ * @param flags the set of class flags to set
+ */
+ public void setFlags(short flags) {
+ itsFlags = flags;
+ }
+
+ static String getSlashedForm(String name)
+ {
+ return name.replace('.', '/');
+ }
+
+ /**
+ * Convert Java class name in dot notation into
+ * "Lname-with-dots-replaced-by-slashes;" form suitable for use as
+ * JVM type signatures.
+ */
+ public static String classNameToSignature(String name)
+ {
+ int nameLength = name.length();
+ int colonPos = 1 + nameLength;
+ char[] buf = new char[colonPos + 1];
+ buf[0] = 'L';
+ buf[colonPos] = ';';
+ name.getChars(0, nameLength, buf, 1);
+ for (int i = 1; i != colonPos; ++i) {
+ if (buf[i] == '.') {
+ buf[i] = '/';
+ }
+ }
+ return new String(buf, 0, colonPos + 1);
+ }
+
+ /**
+ * Add a field to the class.
+ *
+ * @param fieldName the name of the field
+ * @param type the type of the field using ...
+ * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
+ * bitwise or'd together
+ */
+ public void addField(String fieldName, String type, short flags) {
+ short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
+ short typeIndex = itsConstantPool.addUtf8(type);
+ itsFields.add(new ClassFileField(fieldNameIndex, typeIndex, flags));
+ }
+
+ /**
+ * Add a field to the class.
+ *
+ * @param fieldName the name of the field
+ * @param type the type of the field using ...
+ * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
+ * bitwise or'd together
+ * @param value an initial integral value
+ */
+ public void addField(String fieldName, String type, short flags,
+ int value)
+ {
+ short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
+ short typeIndex = itsConstantPool.addUtf8(type);
+ ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
+ flags);
+ field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
+ (short)0,
+ (short)0,
+ itsConstantPool.addConstant(value));
+ itsFields.add(field);
+ }
+
+ /**
+ * Add a field to the class.
+ *
+ * @param fieldName the name of the field
+ * @param type the type of the field using ...
+ * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
+ * bitwise or'd together
+ * @param value an initial long value
+ */
+ public void addField(String fieldName, String type, short flags,
+ long value)
+ {
+ short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
+ short typeIndex = itsConstantPool.addUtf8(type);
+ ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
+ flags);
+ field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
+ (short)0,
+ (short)2,
+ itsConstantPool.addConstant(value));
+ itsFields.add(field);
+ }
+
+ /**
+ * Add a field to the class.
+ *
+ * @param fieldName the name of the field
+ * @param type the type of the field using ...
+ * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
+ * bitwise or'd together
+ * @param value an initial double value
+ */
+ public void addField(String fieldName, String type, short flags,
+ double value)
+ {
+ short fieldNameIndex = itsConstantPool.addUtf8(fieldName);
+ short typeIndex = itsConstantPool.addUtf8(type);
+ ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,
+ flags);
+ field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),
+ (short)0,
+ (short)2,
+ itsConstantPool.addConstant(value));
+ itsFields.add(field);
+ }
+
+ /**
+ * Add Information about java variable to use when generating the local
+ * variable table.
+ *
+ * @param name variable name.
+ * @param type variable type as bytecode descriptor string.
+ * @param startPC the starting bytecode PC where this variable is live,
+ * or -1 if it does not have a Java register.
+ * @param register the Java register number of variable
+ * or -1 if it does not have a Java register.
+ */
+ public void addVariableDescriptor(String name, String type, int startPC, int register)
+ {
+ int nameIndex = itsConstantPool.addUtf8(name);
+ int descriptorIndex = itsConstantPool.addUtf8(type);
+ int [] chunk = { nameIndex, descriptorIndex, startPC, register };
+ if (itsVarDescriptors == null) {
+ itsVarDescriptors = new ObjArray();
+ }
+ itsVarDescriptors.add(chunk);
+ }
+
+ /**
+ * Add a method and begin adding code.
+ *
+ * This method must be called before other methods for adding code,
+ * exception tables, etc. can be invoked.
+ *
+ * @param methodName the name of the method
+ * @param type a string representing the type
+ * @param flags the attributes of the field, such as ACC_PUBLIC, etc.
+ * bitwise or'd together
+ */
+ public void startMethod(String methodName, String type, short flags) {
+ short methodNameIndex = itsConstantPool.addUtf8(methodName);
+ short typeIndex = itsConstantPool.addUtf8(type);
+ itsCurrentMethod = new ClassFileMethod(methodNameIndex, typeIndex,
+ flags);
+ itsMethods.add(itsCurrentMethod);
+ }
+
+ /**
+ * Complete generation of the method.
+ *
+ * After this method is called, no more code can be added to the
+ * method begun with <code>startMethod</code>.
+ *
+ * @param maxLocals the maximum number of local variable slots
+ * (a.k.a. Java registers) used by the method
+ */
+ public void stopMethod(short maxLocals) {
+ if (itsCurrentMethod == null)
+ throw new IllegalStateException("No method to stop");
+
+ fixLabelGotos();
+
+ itsMaxLocals = maxLocals;
+
+ int lineNumberTableLength = 0;
+ if (itsLineNumberTable != null) {
+ // 6 bytes for the attribute header
+ // 2 bytes for the line number count
+ // 4 bytes for each entry
+ lineNumberTableLength = 6 + 2 + (itsLineNumberTableTop * 4);
+ }
+
+ int variableTableLength = 0;
+ if (itsVarDescriptors != null) {
+ // 6 bytes for the attribute header
+ // 2 bytes for the variable count
+ // 10 bytes for each entry
+ variableTableLength = 6 + 2 + (itsVarDescriptors.size() * 10);
+ }
+
+ int attrLength = 2 + // attribute_name_index
+ 4 + // attribute_length
+ 2 + // max_stack
+ 2 + // max_locals
+ 4 + // code_length
+ itsCodeBufferTop +
+ 2 + // exception_table_length
+ (itsExceptionTableTop * 8) +
+ 2 + // attributes_count
+ lineNumberTableLength +
+ variableTableLength;
+
+ if (attrLength > 65536) {
+ // See http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html,
+ // section 4.10, "The amount of code per non-native, non-abstract
+ // method is limited to 65536 bytes...
+ throw new ClassFileFormatException(
+ "generated bytecode for method exceeds 64K limit.");
+ }
+ byte[] codeAttribute = new byte[attrLength];
+ int index = 0;
+ int codeAttrIndex = itsConstantPool.addUtf8("Code");
+ index = putInt16(codeAttrIndex, codeAttribute, index);
+ attrLength -= 6; // discount the attribute header
+ index = putInt32(attrLength, codeAttribute, index);
+ index = putInt16(itsMaxStack, codeAttribute, index);
+ index = putInt16(itsMaxLocals, codeAttribute, index);
+ index = putInt32(itsCodeBufferTop, codeAttribute, index);
+ System.arraycopy(itsCodeBuffer, 0, codeAttribute, index,
+ itsCodeBufferTop);
+ index += itsCodeBufferTop;
+
+ if (itsExceptionTableTop > 0) {
+ index = putInt16(itsExceptionTableTop, codeAttribute, index);
+ for (int i = 0; i < itsExceptionTableTop; i++) {
+ ExceptionTableEntry ete = itsExceptionTable[i];
+ short startPC = (short)getLabelPC(ete.itsStartLabel);
+ short endPC = (short)getLabelPC(ete.itsEndLabel);
+ short handlerPC = (short)getLabelPC(ete.itsHandlerLabel);
+ short catchType = ete.itsCatchType;
+ if (startPC == -1)
+ throw new IllegalStateException("start label not defined");
+ if (endPC == -1)
+ throw new IllegalStateException("end label not defined");
+ if (handlerPC == -1)
+ throw new IllegalStateException(
+ "handler label not defined");
+
+ index = putInt16(startPC, codeAttribute, index);
+ index = putInt16(endPC, codeAttribute, index);
+ index = putInt16(handlerPC, codeAttribute, index);
+ index = putInt16(catchType, codeAttribute, index);
+ }
+ }
+ else {
+ // write 0 as exception table length
+ index = putInt16(0, codeAttribute, index);
+ }
+
+ int attributeCount = 0;
+ if (itsLineNumberTable != null)
+ attributeCount++;
+ if (itsVarDescriptors != null)
+ attributeCount++;
+ index = putInt16(attributeCount, codeAttribute, index);
+
+ if (itsLineNumberTable != null) {
+ int lineNumberTableAttrIndex
+ = itsConstantPool.addUtf8("LineNumberTable");
+ index = putInt16(lineNumberTableAttrIndex, codeAttribute, index);
+ int tableAttrLength = 2 + (itsLineNumberTableTop * 4);
+ index = putInt32(tableAttrLength, codeAttribute, index);
+ index = putInt16(itsLineNumberTableTop, codeAttribute, index);
+ for (int i = 0; i < itsLineNumberTableTop; i++) {
+ index = putInt32(itsLineNumberTable[i], codeAttribute, index);
+ }
+ }
+
+ if (itsVarDescriptors != null) {
+ int variableTableAttrIndex
+ = itsConstantPool.addUtf8("LocalVariableTable");
+ index = putInt16(variableTableAttrIndex, codeAttribute, index);
+ int varCount = itsVarDescriptors.size();
+ int tableAttrLength = 2 + (varCount * 10);
+ index = putInt32(tableAttrLength, codeAttribute, index);
+ index = putInt16(varCount, codeAttribute, index);
+ for (int i = 0; i < varCount; i++) {
+ int[] chunk = (int[])itsVarDescriptors.get(i);
+ int nameIndex = chunk[0];
+ int descriptorIndex = chunk[1];
+ int startPC = chunk[2];
+ int register = chunk[3];
+ int length = itsCodeBufferTop - startPC;
+
+ index = putInt16(startPC, codeAttribute, index);
+ index = putInt16(length, codeAttribute, index);
+ index = putInt16(nameIndex, codeAttribute, index);
+ index = putInt16(descriptorIndex, codeAttribute, index);
+ index = putInt16(register, codeAttribute, index);
+ }
+ }
+
+ itsCurrentMethod.setCodeAttribute(codeAttribute);
+
+ itsExceptionTable = null;
+ itsExceptionTableTop = 0;
+ itsLineNumberTableTop = 0;
+ itsCodeBufferTop = 0;
+ itsCurrentMethod = null;
+ itsMaxStack = 0;
+ itsStackTop = 0;
+ itsLabelTableTop = 0;
+ itsFixupTableTop = 0;
+ itsVarDescriptors = null;
+ }
+
+ /**
+ * Add the single-byte opcode to the current method.
+ *
+ * @param theOpCode the opcode of the bytecode
+ */
+ public void add(int theOpCode) {
+ if (opcodeCount(theOpCode) != 0)
+ throw new IllegalArgumentException("Unexpected operands");
+ int newStack = itsStackTop + stackChange(theOpCode);
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+ if (DEBUGCODE)
+ System.out.println("Add " + bytecodeStr(theOpCode));
+ addToCodeBuffer(theOpCode);
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+ }
+
+ /**
+ * Add a single-operand opcode to the current method.
+ *
+ * @param theOpCode the opcode of the bytecode
+ * @param theOperand the operand of the bytecode
+ */
+ public void add(int theOpCode, int theOperand) {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(theOpCode)
+ +", "+Integer.toHexString(theOperand));
+ }
+ int newStack = itsStackTop + stackChange(theOpCode);
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+
+ switch (theOpCode) {
+ case ByteCode.GOTO :
+ // fallthru...
+ case ByteCode.IFEQ :
+ case ByteCode.IFNE :
+ case ByteCode.IFLT :
+ case ByteCode.IFGE :
+ case ByteCode.IFGT :
+ case ByteCode.IFLE :
+ case ByteCode.IF_ICMPEQ :
+ case ByteCode.IF_ICMPNE :
+ case ByteCode.IF_ICMPLT :
+ case ByteCode.IF_ICMPGE :
+ case ByteCode.IF_ICMPGT :
+ case ByteCode.IF_ICMPLE :
+ case ByteCode.IF_ACMPEQ :
+ case ByteCode.IF_ACMPNE :
+ case ByteCode.JSR :
+ case ByteCode.IFNULL :
+ case ByteCode.IFNONNULL : {
+ if ((theOperand & 0x80000000) != 0x80000000) {
+ if ((theOperand < 0) || (theOperand > 65535))
+ throw new IllegalArgumentException(
+ "Bad label for branch");
+ }
+ int branchPC = itsCodeBufferTop;
+ addToCodeBuffer(theOpCode);
+ if ((theOperand & 0x80000000) != 0x80000000) {
+ // hard displacement
+ addToCodeInt16(theOperand);
+ }
+ else { // a label
+ int targetPC = getLabelPC(theOperand);
+ if (DEBUGLABELS) {
+ int theLabel = theOperand & 0x7FFFFFFF;
+ System.out.println("Fixing branch to " +
+ theLabel + " at " + targetPC +
+ " from " + branchPC);
+ }
+ if (targetPC != -1) {
+ int offset = targetPC - branchPC;
+ addToCodeInt16(offset);
+ }
+ else {
+ addLabelFixup(theOperand, branchPC + 1);
+ addToCodeInt16(0);
+ }
+ }
+ }
+ break;
+
+ case ByteCode.BIPUSH :
+ if ((byte)theOperand != theOperand)
+ throw new IllegalArgumentException("out of range byte");
+ addToCodeBuffer(theOpCode);
+ addToCodeBuffer((byte)theOperand);
+ break;
+
+ case ByteCode.SIPUSH :
+ if ((short)theOperand != theOperand)
+ throw new IllegalArgumentException("out of range short");
+ addToCodeBuffer(theOpCode);
+ addToCodeInt16(theOperand);
+ break;
+
+ case ByteCode.NEWARRAY :
+ if (!(0 <= theOperand && theOperand < 256))
+ throw new IllegalArgumentException("out of range index");
+ addToCodeBuffer(theOpCode);
+ addToCodeBuffer(theOperand);
+ break;
+
+ case ByteCode.GETFIELD :
+ case ByteCode.PUTFIELD :
+ if (!(0 <= theOperand && theOperand < 65536))
+ throw new IllegalArgumentException("out of range field");
+ addToCodeBuffer(theOpCode);
+ addToCodeInt16(theOperand);
+ break;
+
+ case ByteCode.LDC :
+ case ByteCode.LDC_W :
+ case ByteCode.LDC2_W :
+ if (!(0 <= theOperand && theOperand < 65536))
+ throw new IllegalArgumentException("out of range index");
+ if (theOperand >= 256
+ || theOpCode == ByteCode.LDC_W
+ || theOpCode == ByteCode.LDC2_W)
+ {
+ if (theOpCode == ByteCode.LDC) {
+ addToCodeBuffer(ByteCode.LDC_W);
+ } else {
+ addToCodeBuffer(theOpCode);
+ }
+ addToCodeInt16(theOperand);
+ } else {
+ addToCodeBuffer(theOpCode);
+ addToCodeBuffer(theOperand);
+ }
+ break;
+
+ case ByteCode.RET :
+ case ByteCode.ILOAD :
+ case ByteCode.LLOAD :
+ case ByteCode.FLOAD :
+ case ByteCode.DLOAD :
+ case ByteCode.ALOAD :
+ case ByteCode.ISTORE :
+ case ByteCode.LSTORE :
+ case ByteCode.FSTORE :
+ case ByteCode.DSTORE :
+ case ByteCode.ASTORE :
+ if (!(0 <= theOperand && theOperand < 65536))
+ throw new ClassFileFormatException("out of range variable");
+ if (theOperand >= 256) {
+ addToCodeBuffer(ByteCode.WIDE);
+ addToCodeBuffer(theOpCode);
+ addToCodeInt16(theOperand);
+ }
+ else {
+ addToCodeBuffer(theOpCode);
+ addToCodeBuffer(theOperand);
+ }
+ break;
+
+ default :
+ throw new IllegalArgumentException(
+ "Unexpected opcode for 1 operand");
+ }
+
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+ }
+
+ /**
+ * Generate the load constant bytecode for the given integer.
+ *
+ * @param k the constant
+ */
+ public void addLoadConstant(int k) {
+ switch (k) {
+ case 0: add(ByteCode.ICONST_0); break;
+ case 1: add(ByteCode.ICONST_1); break;
+ case 2: add(ByteCode.ICONST_2); break;
+ case 3: add(ByteCode.ICONST_3); break;
+ case 4: add(ByteCode.ICONST_4); break;
+ case 5: add(ByteCode.ICONST_5); break;
+ default:
+ add(ByteCode.LDC, itsConstantPool.addConstant(k));
+ break;
+ }
+ }
+
+ /**
+ * Generate the load constant bytecode for the given long.
+ *
+ * @param k the constant
+ */
+ public void addLoadConstant(long k) {
+ add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));
+ }
+
+ /**
+ * Generate the load constant bytecode for the given float.
+ *
+ * @param k the constant
+ */
+ public void addLoadConstant(float k) {
+ add(ByteCode.LDC, itsConstantPool.addConstant(k));
+ }
+
+ /**
+ * Generate the load constant bytecode for the given double.
+ *
+ * @param k the constant
+ */
+ public void addLoadConstant(double k) {
+ add(ByteCode.LDC2_W, itsConstantPool.addConstant(k));
+ }
+
+ /**
+ * Generate the load constant bytecode for the given string.
+ *
+ * @param k the constant
+ */
+ public void addLoadConstant(String k) {
+ add(ByteCode.LDC, itsConstantPool.addConstant(k));
+ }
+
+ /**
+ * Add the given two-operand bytecode to the current method.
+ *
+ * @param theOpCode the opcode of the bytecode
+ * @param theOperand1 the first operand of the bytecode
+ * @param theOperand2 the second operand of the bytecode
+ */
+ public void add(int theOpCode, int theOperand1, int theOperand2) {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(theOpCode)
+ +", "+Integer.toHexString(theOperand1)
+ +", "+Integer.toHexString(theOperand2));
+ }
+ int newStack = itsStackTop + stackChange(theOpCode);
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+
+ if (theOpCode == ByteCode.IINC) {
+ if (!(0 <= theOperand1 && theOperand1 < 65536))
+ throw new ClassFileFormatException("out of range variable");
+ if (!(0 <= theOperand2 && theOperand2 < 65536))
+ throw new ClassFileFormatException("out of range increment");
+
+ if (theOperand1 > 255 || theOperand2 < -128 || theOperand2 > 127) {
+ addToCodeBuffer(ByteCode.WIDE);
+ addToCodeBuffer(ByteCode.IINC);
+ addToCodeInt16(theOperand1);
+ addToCodeInt16(theOperand2);
+ }
+ else {
+ addToCodeBuffer(ByteCode.WIDE);
+ addToCodeBuffer(ByteCode.IINC);
+ addToCodeBuffer(theOperand1);
+ addToCodeBuffer(theOperand2);
+ }
+ }
+ else if (theOpCode == ByteCode.MULTIANEWARRAY) {
+ if (!(0 <= theOperand1 && theOperand1 < 65536))
+ throw new IllegalArgumentException("out of range index");
+ if (!(0 <= theOperand2 && theOperand2 < 256))
+ throw new IllegalArgumentException("out of range dimensions");
+
+ addToCodeBuffer(ByteCode.MULTIANEWARRAY);
+ addToCodeInt16(theOperand1);
+ addToCodeBuffer(theOperand2);
+ }
+ else {
+ throw new IllegalArgumentException(
+ "Unexpected opcode for 2 operands");
+ }
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+
+ }
+
+ public void add(int theOpCode, String className) {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(theOpCode)
+ +", "+className);
+ }
+ int newStack = itsStackTop + stackChange(theOpCode);
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+ switch (theOpCode) {
+ case ByteCode.NEW :
+ case ByteCode.ANEWARRAY :
+ case ByteCode.CHECKCAST :
+ case ByteCode.INSTANCEOF : {
+ short classIndex = itsConstantPool.addClass(className);
+ addToCodeBuffer(theOpCode);
+ addToCodeInt16(classIndex);
+ }
+ break;
+
+ default :
+ throw new IllegalArgumentException(
+ "bad opcode for class reference");
+ }
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+ }
+
+
+ public void add(int theOpCode, String className, String fieldName,
+ String fieldType)
+ {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(theOpCode)
+ +", "+className+", "+fieldName+", "+fieldType);
+ }
+ int newStack = itsStackTop + stackChange(theOpCode);
+ char fieldTypeChar = fieldType.charAt(0);
+ int fieldSize = (fieldTypeChar == 'J' || fieldTypeChar == 'D')
+ ? 2 : 1;
+ switch (theOpCode) {
+ case ByteCode.GETFIELD :
+ case ByteCode.GETSTATIC :
+ newStack += fieldSize;
+ break;
+ case ByteCode.PUTSTATIC :
+ case ByteCode.PUTFIELD :
+ newStack -= fieldSize;
+ break;
+ default :
+ throw new IllegalArgumentException(
+ "bad opcode for field reference");
+ }
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+ short fieldRefIndex = itsConstantPool.addFieldRef(className,
+ fieldName, fieldType);
+ addToCodeBuffer(theOpCode);
+ addToCodeInt16(fieldRefIndex);
+
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+ }
+
+ public void addInvoke(int theOpCode, String className, String methodName,
+ String methodType)
+ {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(theOpCode)
+ +", "+className+", "+methodName+", "
+ +methodType);
+ }
+ int parameterInfo = sizeOfParameters(methodType);
+ int parameterCount = parameterInfo >>> 16;
+ int stackDiff = (short)parameterInfo;
+
+ int newStack = itsStackTop + stackDiff;
+ newStack += stackChange(theOpCode); // adjusts for 'this'
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+
+ switch (theOpCode) {
+ case ByteCode.INVOKEVIRTUAL :
+ case ByteCode.INVOKESPECIAL :
+ case ByteCode.INVOKESTATIC :
+ case ByteCode.INVOKEINTERFACE : {
+ addToCodeBuffer(theOpCode);
+ if (theOpCode == ByteCode.INVOKEINTERFACE) {
+ short ifMethodRefIndex
+ = itsConstantPool.addInterfaceMethodRef(
+ className, methodName,
+ methodType);
+ addToCodeInt16(ifMethodRefIndex);
+ addToCodeBuffer(parameterCount + 1);
+ addToCodeBuffer(0);
+ }
+ else {
+ short methodRefIndex = itsConstantPool.addMethodRef(
+ className, methodName,
+ methodType);
+ addToCodeInt16(methodRefIndex);
+ }
+ }
+ break;
+
+ default :
+ throw new IllegalArgumentException(
+ "bad opcode for method reference");
+ }
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(theOpCode)
+ +" stack = "+itsStackTop);
+ }
+ }
+
+ /**
+ * Generate code to load the given integer on stack.
+ *
+ * @param k the constant
+ */
+ public void addPush(int k)
+ {
+ if ((byte)k == k) {
+ if (k == -1) {
+ add(ByteCode.ICONST_M1);
+ } else if (0 <= k && k <= 5) {
+ add((byte)(ByteCode.ICONST_0 + k));
+ } else {
+ add(ByteCode.BIPUSH, (byte)k);
+ }
+ } else if ((short)k == k) {
+ add(ByteCode.SIPUSH, (short)k);
+ } else {
+ addLoadConstant(k);
+ }
+ }
+
+ public void addPush(boolean k)
+ {
+ add(k ? ByteCode.ICONST_1 : ByteCode.ICONST_0);
+ }
+
+ /**
+ * Generate code to load the given long on stack.
+ *
+ * @param k the constant
+ */
+ public void addPush(long k)
+ {
+ int ik = (int)k;
+ if (ik == k) {
+ addPush(ik);
+ add(ByteCode.I2L);
+ } else {
+ addLoadConstant(k);
+ }
+ }
+
+ /**
+ * Generate code to load the given double on stack.
+ *
+ * @param k the constant
+ */
+ public void addPush(double k)
+ {
+ if (k == 0.0) {
+ // zero
+ add(ByteCode.DCONST_0);
+ if (1.0 / k < 0) {
+ // Negative zero
+ add(ByteCode.DNEG);
+ }
+ } else if (k == 1.0 || k == -1.0) {
+ add(ByteCode.DCONST_1);
+ if (k < 0) {
+ add(ByteCode.DNEG);
+ }
+ } else {
+ addLoadConstant(k);
+ }
+ }
+
+ /**
+ * Generate the code to leave on stack the given string even if the
+ * string encoding exeeds the class file limit for single string constant
+ *
+ * @param k the constant
+ */
+ public void addPush(String k) {
+ int length = k.length();
+ int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length);
+ if (limit == length) {
+ addLoadConstant(k);
+ return;
+ }
+ // Split string into picies fitting the UTF limit and generate code for
+ // StringBuffer sb = new StringBuffer(length);
+ // sb.append(loadConstant(piece_1));
+ // ...
+ // sb.append(loadConstant(piece_N));
+ // sb.toString();
+ final String SB = "java/lang/StringBuffer";
+ add(ByteCode.NEW, SB);
+ add(ByteCode.DUP);
+ addPush(length);
+ addInvoke(ByteCode.INVOKESPECIAL, SB, "<init>", "(I)V");
+ int cursor = 0;
+ for (;;) {
+ add(ByteCode.DUP);
+ String s = k.substring(cursor, limit);
+ addLoadConstant(s);
+ addInvoke(ByteCode.INVOKEVIRTUAL, SB, "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+ add(ByteCode.POP);
+ if (limit == length) {
+ break;
+ }
+ cursor = limit;
+ limit = itsConstantPool.getUtfEncodingLimit(k, limit, length);
+ }
+ addInvoke(ByteCode.INVOKEVIRTUAL, SB, "toString",
+ "()Ljava/lang/String;");
+ }
+
+ /**
+ * Check if k fits limit on string constant size imposed by class file
+ * format.
+ *
+ * @param k the string constant
+ */
+ public boolean isUnderStringSizeLimit(String k)
+ {
+ return itsConstantPool.isUnderUtfEncodingLimit(k);
+ }
+
+ /**
+ * Store integer from stack top into the given local.
+ *
+ * @param local number of local register
+ */
+ public void addIStore(int local)
+ {
+ xop(ByteCode.ISTORE_0, ByteCode.ISTORE, local);
+ }
+
+ /**
+ * Store long from stack top into the given local.
+ *
+ * @param local number of local register
+ */
+ public void addLStore(int local)
+ {
+ xop(ByteCode.LSTORE_0, ByteCode.LSTORE, local);
+ }
+
+ /**
+ * Store float from stack top into the given local.
+ *
+ * @param local number of local register
+ */
+ public void addFStore(int local)
+ {
+ xop(ByteCode.FSTORE_0, ByteCode.FSTORE, local);
+ }
+
+ /**
+ * Store double from stack top into the given local.
+ *
+ * @param local number of local register
+ */
+ public void addDStore(int local)
+ {
+ xop(ByteCode.DSTORE_0, ByteCode.DSTORE, local);
+ }
+
+ /**
+ * Store object from stack top into the given local.
+ *
+ * @param local number of local register
+ */
+ public void addAStore(int local)
+ {
+ xop(ByteCode.ASTORE_0, ByteCode.ASTORE, local);
+ }
+
+ /**
+ * Load integer from the given local into stack.
+ *
+ * @param local number of local register
+ */
+ public void addILoad(int local)
+ {
+ xop(ByteCode.ILOAD_0, ByteCode.ILOAD, local);
+ }
+
+ /**
+ * Load long from the given local into stack.
+ *
+ * @param local number of local register
+ */
+ public void addLLoad(int local)
+ {
+ xop(ByteCode.LLOAD_0, ByteCode.LLOAD, local);
+ }
+
+ /**
+ * Load float from the given local into stack.
+ *
+ * @param local number of local register
+ */
+ public void addFLoad(int local)
+ {
+ xop(ByteCode.FLOAD_0, ByteCode.FLOAD, local);
+ }
+
+ /**
+ * Load double from the given local into stack.
+ *
+ * @param local number of local register
+ */
+ public void addDLoad(int local)
+ {
+ xop(ByteCode.DLOAD_0, ByteCode.DLOAD, local);
+ }
+
+ /**
+ * Load object from the given local into stack.
+ *
+ * @param local number of local register
+ */
+ public void addALoad(int local)
+ {
+ xop(ByteCode.ALOAD_0, ByteCode.ALOAD, local);
+ }
+
+ /**
+ * Load "this" into stack.
+ */
+ public void addLoadThis()
+ {
+ add(ByteCode.ALOAD_0);
+ }
+
+ private void xop(int shortOp, int op, int local)
+ {
+ switch (local) {
+ case 0:
+ add(shortOp);
+ break;
+ case 1:
+ add(shortOp + 1);
+ break;
+ case 2:
+ add(shortOp + 2);
+ break;
+ case 3:
+ add(shortOp + 3);
+ break;
+ default:
+ add(op, local);
+ }
+ }
+
+ public int addTableSwitch(int low, int high)
+ {
+ if (DEBUGCODE) {
+ System.out.println("Add "+bytecodeStr(ByteCode.TABLESWITCH)
+ +" "+low+" "+high);
+ }
+ if (low > high)
+ throw new ClassFileFormatException("Bad bounds: "+low+' '+ high);
+
+ int newStack = itsStackTop + stackChange(ByteCode.TABLESWITCH);
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+
+ int entryCount = high - low + 1;
+ int padSize = 3 & ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4
+
+ int N = addReservedCodeSpace(1 + padSize + 4 * (1 + 2 + entryCount));
+ int switchStart = N;
+ itsCodeBuffer[N++] = (byte)ByteCode.TABLESWITCH;
+ while (padSize != 0) {
+ itsCodeBuffer[N++] = 0;
+ --padSize;
+ }
+ N += 4; // skip default offset
+ N = putInt32(low, itsCodeBuffer, N);
+ putInt32(high, itsCodeBuffer, N);
+
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+bytecodeStr(ByteCode.TABLESWITCH)
+ +" stack = "+itsStackTop);
+ }
+
+ return switchStart;
+ }
+
+ public final void markTableSwitchDefault(int switchStart)
+ {
+ setTableSwitchJump(switchStart, -1, itsCodeBufferTop);
+ }
+
+ public final void markTableSwitchCase(int switchStart, int caseIndex)
+ {
+ setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);
+ }
+
+ public final void markTableSwitchCase(int switchStart, int caseIndex,
+ int stackTop)
+ {
+ if (!(0 <= stackTop && stackTop <= itsMaxStack))
+ throw new IllegalArgumentException("Bad stack index: "+stackTop);
+ itsStackTop = (short)stackTop;
+ setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);
+ }
+
+ public void setTableSwitchJump(int switchStart, int caseIndex,
+ int jumpTarget)
+ {
+ if (!(0 <= jumpTarget && jumpTarget <= itsCodeBufferTop))
+ throw new IllegalArgumentException("Bad jump target: "+jumpTarget);
+ if (!(caseIndex >= -1))
+ throw new IllegalArgumentException("Bad case index: "+caseIndex);
+
+ int padSize = 3 & ~switchStart; // == 3 - switchStart % 4
+ int caseOffset;
+ if (caseIndex < 0) {
+ // default label
+ caseOffset = switchStart + 1 + padSize;
+ } else {
+ caseOffset = switchStart + 1 + padSize + 4 * (3 + caseIndex);
+ }
+ if (!(0 <= switchStart
+ && switchStart <= itsCodeBufferTop - 4 * 4 - padSize - 1))
+ {
+ throw new IllegalArgumentException(
+ switchStart+" is outside a possible range of tableswitch"
+ +" in already generated code");
+ }
+ if ((0xFF & itsCodeBuffer[switchStart]) != ByteCode.TABLESWITCH) {
+ throw new IllegalArgumentException(
+ switchStart+" is not offset of tableswitch statement");
+ }
+ if (!(0 <= caseOffset && caseOffset + 4 <= itsCodeBufferTop)) {
+ // caseIndex >= -1 does not guarantee that caseOffset >= 0 due
+ // to a possible overflow.
+ throw new ClassFileFormatException(
+ "Too big case index: "+caseIndex);
+ }
+ // ALERT: perhaps check against case bounds?
+ putInt32(jumpTarget - switchStart, itsCodeBuffer, caseOffset);
+ }
+
+ public int acquireLabel()
+ {
+ int top = itsLabelTableTop;
+ if (itsLabelTable == null || top == itsLabelTable.length) {
+ if (itsLabelTable == null) {
+ itsLabelTable = new int[MIN_LABEL_TABLE_SIZE];
+ }else {
+ int[] tmp = new int[itsLabelTable.length * 2];
+ System.arraycopy(itsLabelTable, 0, tmp, 0, top);
+ itsLabelTable = tmp;
+ }
+ }
+ itsLabelTableTop = top + 1;
+ itsLabelTable[top] = -1;
+ return top | 0x80000000;
+ }
+
+ public void markLabel(int label)
+ {
+ if (!(label < 0))
+ throw new IllegalArgumentException("Bad label, no biscuit");
+
+ label &= 0x7FFFFFFF;
+ if (label > itsLabelTableTop)
+ throw new IllegalArgumentException("Bad label");
+
+ if (itsLabelTable[label] != -1) {
+ throw new IllegalStateException("Can only mark label once");
+ }
+
+ itsLabelTable[label] = itsCodeBufferTop;
+ }
+
+ public void markLabel(int label, short stackTop)
+ {
+ markLabel(label);
+ itsStackTop = stackTop;
+ }
+
+ public void markHandler(int theLabel) {
+ itsStackTop = 1;
+ markLabel(theLabel);
+ }
+
+ private int getLabelPC(int label)
+ {
+ if (!(label < 0))
+ throw new IllegalArgumentException("Bad label, no biscuit");
+ label &= 0x7FFFFFFF;
+ if (!(label < itsLabelTableTop))
+ throw new IllegalArgumentException("Bad label");
+ return itsLabelTable[label];
+ }
+
+ private void addLabelFixup(int label, int fixupSite)
+ {
+ if (!(label < 0))
+ throw new IllegalArgumentException("Bad label, no biscuit");
+ label &= 0x7FFFFFFF;
+ if (!(label < itsLabelTableTop))
+ throw new IllegalArgumentException("Bad label");
+ int top = itsFixupTableTop;
+ if (itsFixupTable == null || top == itsFixupTable.length) {
+ if (itsFixupTable == null) {
+ itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE];
+ }else {
+ long[] tmp = new long[itsFixupTable.length * 2];
+ System.arraycopy(itsFixupTable, 0, tmp, 0, top);
+ itsFixupTable = tmp;
+ }
+ }
+ itsFixupTableTop = top + 1;
+ itsFixupTable[top] = ((long)label << 32) | fixupSite;
+ }
+
+ private void fixLabelGotos()
+ {
+ byte[] codeBuffer = itsCodeBuffer;
+ for (int i = 0; i < itsFixupTableTop; i++) {
+ long fixup = itsFixupTable[i];
+ int label = (int)(fixup >> 32);
+ int fixupSite = (int)fixup;
+ int pc = itsLabelTable[label];
+ if (pc == -1) {
+ // Unlocated label
+ throw new RuntimeException();
+ }
+ // -1 to get delta from instruction start
+ int offset = pc - (fixupSite - 1);
+ if ((short)offset != offset) {
+ throw new ClassFileFormatException
+ ("Program too complex: too big jump offset");
+ }
+ codeBuffer[fixupSite] = (byte)(offset >> 8);
+ codeBuffer[fixupSite + 1] = (byte)offset;
+ }
+ itsFixupTableTop = 0;
+ }
+
+ /**
+ * Get the current offset into the code of the current method.
+ *
+ * @return an integer representing the offset
+ */
+ public int getCurrentCodeOffset() {
+ return itsCodeBufferTop;
+ }
+
+ public short getStackTop() {
+ return itsStackTop;
+ }
+
+ public void setStackTop(short n) {
+ itsStackTop = n;
+ }
+
+ public void adjustStackTop(int delta) {
+ int newStack = itsStackTop + delta;
+ if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);
+ itsStackTop = (short)newStack;
+ if (newStack > itsMaxStack) itsMaxStack = (short)newStack;
+ if (DEBUGSTACK) {
+ System.out.println("After "+"adjustStackTop("+delta+")"
+ +" stack = "+itsStackTop);
+ }
+ }
+
+ private void addToCodeBuffer(int b)
+ {
+ int N = addReservedCodeSpace(1);
+ itsCodeBuffer[N] = (byte)b;
+ }
+
+ private void addToCodeInt16(int value)
+ {
+ int N = addReservedCodeSpace(2);
+ putInt16(value, itsCodeBuffer, N);
+ }
+
+ private int addReservedCodeSpace(int size)
+ {
+ if (itsCurrentMethod == null)
+ throw new IllegalArgumentException("No method to add to");
+ int oldTop = itsCodeBufferTop;
+ int newTop = oldTop + size;
+ if (newTop > itsCodeBuffer.length) {
+ int newSize = itsCodeBuffer.length * 2;
+ if (newTop > newSize) { newSize = newTop; }
+ byte[] tmp = new byte[newSize];
+ System.arraycopy(itsCodeBuffer, 0, tmp, 0, oldTop);
+ itsCodeBuffer = tmp;
+ }
+ itsCodeBufferTop = newTop;
+ return oldTop;
+ }
+
+ public void addExceptionHandler(int startLabel, int endLabel,
+ int handlerLabel, String catchClassName)
+ {
+ if ((startLabel & 0x80000000) != 0x80000000)
+ throw new IllegalArgumentException("Bad startLabel");
+ if ((endLabel & 0x80000000) != 0x80000000)
+ throw new IllegalArgumentException("Bad endLabel");
+ if ((handlerLabel & 0x80000000) != 0x80000000)
+ throw new IllegalArgumentException("Bad handlerLabel");
+
+ /*
+ * If catchClassName is null, use 0 for the catch_type_index; which
+ * means catch everything. (Even when the verifier has let you throw
+ * something other than a Throwable.)
+ */
+ short catch_type_index = (catchClassName == null)
+ ? 0
+ : itsConstantPool.addClass(catchClassName);
+ ExceptionTableEntry newEntry = new ExceptionTableEntry(
+ startLabel,
+ endLabel,
+ handlerLabel,
+ catch_type_index);
+ int N = itsExceptionTableTop;
+ if (N == 0) {
+ itsExceptionTable = new ExceptionTableEntry[ExceptionTableSize];
+ } else if (N == itsExceptionTable.length) {
+ ExceptionTableEntry[] tmp = new ExceptionTableEntry[N * 2];
+ System.arraycopy(itsExceptionTable, 0, tmp, 0, N);
+ itsExceptionTable = tmp;
+ }
+ itsExceptionTable[N] = newEntry;
+ itsExceptionTableTop = N + 1;
+
+ }
+
+ public void addLineNumberEntry(short lineNumber) {
+ if (itsCurrentMethod == null)
+ throw new IllegalArgumentException("No method to stop");
+ int N = itsLineNumberTableTop;
+ if (N == 0) {
+ itsLineNumberTable = new int[LineNumberTableSize];
+ } else if (N == itsLineNumberTable.length) {
+ int[] tmp = new int[N * 2];
+ System.arraycopy(itsLineNumberTable, 0, tmp, 0, N);
+ itsLineNumberTable = tmp;
+ }
+ itsLineNumberTable[N] = (itsCodeBufferTop << 16) + lineNumber;
+ itsLineNumberTableTop = N + 1;
+ }
+
+ /**
+ * Write the class file to the OutputStream.
+ *
+ * @param oStream the stream to write to
+ * @throws IOException if writing to the stream produces an exception
+ */
+ public void write(OutputStream oStream)
+ throws IOException
+ {
+ byte[] array = toByteArray();
+ oStream.write(array);
+ }
+
+ private int getWriteSize()
+ {
+ int size = 0;
+
+ if (itsSourceFileNameIndex != 0) {
+ itsConstantPool.addUtf8("SourceFile");
+ }
+
+ size += 8; //writeLong(FileHeaderConstant);
+ size += itsConstantPool.getWriteSize();
+ size += 2; //writeShort(itsFlags);
+ size += 2; //writeShort(itsThisClassIndex);
+ size += 2; //writeShort(itsSuperClassIndex);
+ size += 2; //writeShort(itsInterfaces.size());
+ size += 2 * itsInterfaces.size();
+
+ size += 2; //writeShort(itsFields.size());
+ for (int i = 0; i < itsFields.size(); i++) {
+ size += ((ClassFileField)(itsFields.get(i))).getWriteSize();
+ }
+
+ size += 2; //writeShort(itsMethods.size());
+ for (int i = 0; i < itsMethods.size(); i++) {
+ size += ((ClassFileMethod)(itsMethods.get(i))).getWriteSize();
+ }
+
+ if (itsSourceFileNameIndex != 0) {
+ size += 2; //writeShort(1); attributes count
+ size += 2; //writeShort(sourceFileAttributeNameIndex);
+ size += 4; //writeInt(2);
+ size += 2; //writeShort(itsSourceFileNameIndex);
+ }else {
+ size += 2; //out.writeShort(0); no attributes
+ }
+
+ return size;
+ }
+
+ /**
+ * Get the class file as array of bytesto the OutputStream.
+ */
+ public byte[] toByteArray()
+ {
+ int dataSize = getWriteSize();
+ byte[] data = new byte[dataSize];
+ int offset = 0;
+
+ short sourceFileAttributeNameIndex = 0;
+ if (itsSourceFileNameIndex != 0) {
+ sourceFileAttributeNameIndex = itsConstantPool.addUtf8(
+ "SourceFile");
+ }
+
+ offset = putInt64(FileHeaderConstant, data, offset);
+ offset = itsConstantPool.write(data, offset);
+ offset = putInt16(itsFlags, data, offset);
+ offset = putInt16(itsThisClassIndex, data, offset);
+ offset = putInt16(itsSuperClassIndex, data, offset);
+ offset = putInt16(itsInterfaces.size(), data, offset);
+ for (int i = 0; i < itsInterfaces.size(); i++) {
+ int interfaceIndex = ((Short)(itsInterfaces.get(i))).shortValue();
+ offset = putInt16(interfaceIndex, data, offset);
+ }
+ offset = putInt16(itsFields.size(), data, offset);
+ for (int i = 0; i < itsFields.size(); i++) {
+ ClassFileField field = (ClassFileField)itsFields.get(i);
+ offset = field.write(data, offset);
+ }
+ offset = putInt16(itsMethods.size(), data, offset);
+ for (int i = 0; i < itsMethods.size(); i++) {
+ ClassFileMethod method = (ClassFileMethod)itsMethods.get(i);
+ offset = method.write(data, offset);
+ }
+ if (itsSourceFileNameIndex != 0) {
+ offset = putInt16(1, data, offset); // attributes count
+ offset = putInt16(sourceFileAttributeNameIndex, data, offset);
+ offset = putInt32(2, data, offset);
+ offset = putInt16(itsSourceFileNameIndex, data, offset);
+ } else {
+ offset = putInt16(0, data, offset); // no attributes
+ }
+
+ if (offset != dataSize) {
+ // Check getWriteSize is consistent with write!
+ throw new RuntimeException();
+ }
+
+ return data;
+ }
+
+ static int putInt64(long value, byte[] array, int offset)
+ {
+ offset = putInt32((int)(value >>> 32), array, offset);
+ return putInt32((int)value, array, offset);
+ }
+
+ private static void badStack(int value)
+ {
+ String s;
+ if (value < 0) { s = "Stack underflow: "+value; }
+ else { s = "Too big stack: "+value; }
+ throw new IllegalStateException(s);
+ }
+
+ /*
+ Really weird. Returns an int with # parameters in hi 16 bits, and
+ stack difference removal of parameters from stack and pushing the
+ result (it does not take into account removal of this in case of
+ non-static methods).
+ If Java really supported references we wouldn't have to be this
+ perverted.
+ */
+ private static int sizeOfParameters(String pString)
+ {
+ int length = pString.length();
+ int rightParenthesis = pString.lastIndexOf(')');
+ if (3 <= length /* minimal signature takes at least 3 chars: ()V */
+ && pString.charAt(0) == '('
+ && 1 <= rightParenthesis && rightParenthesis + 1 < length)
+ {
+ boolean ok = true;
+ int index = 1;
+ int stackDiff = 0;
+ int count = 0;
+ stringLoop:
+ while (index != rightParenthesis) {
+ switch (pString.charAt(index)) {
+ default:
+ ok = false;
+ break stringLoop;
+ case 'J' :
+ case 'D' :
+ --stackDiff;
+ // fall thru
+ case 'B' :
+ case 'S' :
+ case 'C' :
+ case 'I' :
+ case 'Z' :
+ case 'F' :
+ --stackDiff;
+ ++count;
+ ++index;
+ continue;
+ case '[' :
+ ++index;
+ int c = pString.charAt(index);
+ while (c == '[') {
+ ++index;
+ c = pString.charAt(index);
+ }
+ switch (c) {
+ default:
+ ok = false;
+ break stringLoop;
+ case 'J' :
+ case 'D' :
+ case 'B' :
+ case 'S' :
+ case 'C' :
+ case 'I' :
+ case 'Z' :
+ case 'F' :
+ --stackDiff;
+ ++count;
+ ++index;
+ continue;
+ case 'L':
+ // fall thru
+ }
+ // fall thru
+ case 'L' : {
+ --stackDiff;
+ ++count;
+ ++index;
+ int semicolon = pString.indexOf(';', index);
+ if (!(index + 1 <= semicolon
+ && semicolon < rightParenthesis))
+ {
+ ok = false;
+ break stringLoop;
+ }
+ index = semicolon + 1;
+ continue;
+ }
+ }
+ }
+ if (ok) {
+ switch (pString.charAt(rightParenthesis + 1)) {
+ default:
+ ok = false;
+ break;
+ case 'J' :
+ case 'D' :
+ ++stackDiff;
+ // fall thru
+ case 'B' :
+ case 'S' :
+ case 'C' :
+ case 'I' :
+ case 'Z' :
+ case 'F' :
+ case 'L' :
+ case '[' :
+ ++stackDiff;
+ // fall thru
+ case 'V' :
+ break;
+ }
+ if (ok) {
+ return ((count << 16) | (0xFFFF & stackDiff));
+ }
+ }
+ }
+ throw new IllegalArgumentException(
+ "Bad parameter signature: "+pString);
+ }
+
+ static int putInt16(int value, byte[] array, int offset)
+ {
+ array[offset + 0] = (byte)(value >>> 8);
+ array[offset + 1] = (byte)value;
+ return offset + 2;
+ }
+
+ static int putInt32(int value, byte[] array, int offset)
+ {
+ array[offset + 0] = (byte)(value >>> 24);
+ array[offset + 1] = (byte)(value >>> 16);
+ array[offset + 2] = (byte)(value >>> 8);
+ array[offset + 3] = (byte)value;
+ return offset + 4;
+ }
+
+ /**
+ * Number of operands accompanying the opcode.
+ */
+ static int opcodeCount(int opcode)
+ {
+ switch (opcode) {
+ case ByteCode.AALOAD:
+ case ByteCode.AASTORE:
+ case ByteCode.ACONST_NULL:
+ case ByteCode.ALOAD_0:
+ case ByteCode.ALOAD_1:
+ case ByteCode.ALOAD_2:
+ case ByteCode.ALOAD_3:
+ case ByteCode.ARETURN:
+ case ByteCode.ARRAYLENGTH:
+ case ByteCode.ASTORE_0:
+ case ByteCode.ASTORE_1:
+ case ByteCode.ASTORE_2:
+ case ByteCode.ASTORE_3:
+ case ByteCode.ATHROW:
+ case ByteCode.BALOAD:
+ case ByteCode.BASTORE:
+ case ByteCode.BREAKPOINT:
+ case ByteCode.CALOAD:
+ case ByteCode.CASTORE:
+ case ByteCode.D2F:
+ case ByteCode.D2I:
+ case ByteCode.D2L:
+ case ByteCode.DADD:
+ case ByteCode.DALOAD:
+ case ByteCode.DASTORE:
+ case ByteCode.DCMPG:
+ case ByteCode.DCMPL:
+ case ByteCode.DCONST_0:
+ case ByteCode.DCONST_1:
+ case ByteCode.DDIV:
+ case ByteCode.DLOAD_0:
+ case ByteCode.DLOAD_1:
+ case ByteCode.DLOAD_2:
+ case ByteCode.DLOAD_3:
+ case ByteCode.DMUL:
+ case ByteCode.DNEG:
+ case ByteCode.DREM:
+ case ByteCode.DRETURN:
+ case ByteCode.DSTORE_0:
+ case ByteCode.DSTORE_1:
+ case ByteCode.DSTORE_2:
+ case ByteCode.DSTORE_3:
+ case ByteCode.DSUB:
+ case ByteCode.DUP:
+ case ByteCode.DUP2:
+ case ByteCode.DUP2_X1:
+ case ByteCode.DUP2_X2:
+ case ByteCode.DUP_X1:
+ case ByteCode.DUP_X2:
+ case ByteCode.F2D:
+ case ByteCode.F2I:
+ case ByteCode.F2L:
+ case ByteCode.FADD:
+ case ByteCode.FALOAD:
+ case ByteCode.FASTORE:
+ case ByteCode.FCMPG:
+ case ByteCode.FCMPL:
+ case ByteCode.FCONST_0:
+ case ByteCode.FCONST_1:
+ case ByteCode.FCONST_2:
+ case ByteCode.FDIV:
+ case ByteCode.FLOAD_0:
+ case ByteCode.FLOAD_1:
+ case ByteCode.FLOAD_2:
+ case ByteCode.FLOAD_3:
+ case ByteCode.FMUL:
+ case ByteCode.FNEG:
+ case ByteCode.FREM:
+ case ByteCode.FRETURN:
+ case ByteCode.FSTORE_0:
+ case ByteCode.FSTORE_1:
+ case ByteCode.FSTORE_2:
+ case ByteCode.FSTORE_3:
+ case ByteCode.FSUB:
+ case ByteCode.I2B:
+ case ByteCode.I2C:
+ case ByteCode.I2D:
+ case ByteCode.I2F:
+ case ByteCode.I2L:
+ case ByteCode.I2S:
+ case ByteCode.IADD:
+ case ByteCode.IALOAD:
+ case ByteCode.IAND:
+ case ByteCode.IASTORE:
+ case ByteCode.ICONST_0:
+ case ByteCode.ICONST_1:
+ case ByteCode.ICONST_2:
+ case ByteCode.ICONST_3:
+ case ByteCode.ICONST_4:
+ case ByteCode.ICONST_5:
+ case ByteCode.ICONST_M1:
+ case ByteCode.IDIV:
+ case ByteCode.ILOAD_0:
+ case ByteCode.ILOAD_1:
+ case ByteCode.ILOAD_2:
+ case ByteCode.ILOAD_3:
+ case ByteCode.IMPDEP1:
+ case ByteCode.IMPDEP2:
+ case ByteCode.IMUL:
+ case ByteCode.INEG:
+ case ByteCode.IOR:
+ case ByteCode.IREM:
+ case ByteCode.IRETURN:
+ case ByteCode.ISHL:
+ case ByteCode.ISHR:
+ case ByteCode.ISTORE_0:
+ case ByteCode.ISTORE_1:
+ case ByteCode.ISTORE_2:
+ case ByteCode.ISTORE_3:
+ case ByteCode.ISUB:
+ case ByteCode.IUSHR:
+ case ByteCode.IXOR:
+ case ByteCode.L2D:
+ case ByteCode.L2F:
+ case ByteCode.L2I:
+ case ByteCode.LADD:
+ case ByteCode.LALOAD:
+ case ByteCode.LAND:
+ case ByteCode.LASTORE:
+ case ByteCode.LCMP:
+ case ByteCode.LCONST_0:
+ case ByteCode.LCONST_1:
+ case ByteCode.LDIV:
+ case ByteCode.LLOAD_0:
+ case ByteCode.LLOAD_1:
+ case ByteCode.LLOAD_2:
+ case ByteCode.LLOAD_3:
+ case ByteCode.LMUL:
+ case ByteCode.LNEG:
+ case ByteCode.LOR:
+ case ByteCode.LREM:
+ case ByteCode.LRETURN:
+ case ByteCode.LSHL:
+ case ByteCode.LSHR:
+ case ByteCode.LSTORE_0:
+ case ByteCode.LSTORE_1:
+ case ByteCode.LSTORE_2:
+ case ByteCode.LSTORE_3:
+ case ByteCode.LSUB:
+ case ByteCode.LUSHR:
+ case ByteCode.LXOR:
+ case ByteCode.MONITORENTER:
+ case ByteCode.MONITOREXIT:
+ case ByteCode.NOP:
+ case ByteCode.POP:
+ case ByteCode.POP2:
+ case ByteCode.RETURN:
+ case ByteCode.SALOAD:
+ case ByteCode.SASTORE:
+ case ByteCode.SWAP:
+ case ByteCode.WIDE:
+ return 0;
+ case ByteCode.ALOAD:
+ case ByteCode.ANEWARRAY:
+ case ByteCode.ASTORE:
+ case ByteCode.BIPUSH:
+ case ByteCode.CHECKCAST:
+ case ByteCode.DLOAD:
+ case ByteCode.DSTORE:
+ case ByteCode.FLOAD:
+ case ByteCode.FSTORE:
+ case ByteCode.GETFIELD:
+ case ByteCode.GETSTATIC:
+ case ByteCode.GOTO:
+ case ByteCode.GOTO_W:
+ case ByteCode.IFEQ:
+ case ByteCode.IFGE:
+ case ByteCode.IFGT:
+ case ByteCode.IFLE:
+ case ByteCode.IFLT:
+ case ByteCode.IFNE:
+ case ByteCode.IFNONNULL:
+ case ByteCode.IFNULL:
+ case ByteCode.IF_ACMPEQ:
+ case ByteCode.IF_ACMPNE:
+ case ByteCode.IF_ICMPEQ:
+ case ByteCode.IF_ICMPGE:
+ case ByteCode.IF_ICMPGT:
+ case ByteCode.IF_ICMPLE:
+ case ByteCode.IF_ICMPLT:
+ case ByteCode.IF_ICMPNE:
+ case ByteCode.ILOAD:
+ case ByteCode.INSTANCEOF:
+ case ByteCode.INVOKEINTERFACE:
+ case ByteCode.INVOKESPECIAL:
+ case ByteCode.INVOKESTATIC:
+ case ByteCode.INVOKEVIRTUAL:
+ case ByteCode.ISTORE:
+ case ByteCode.JSR:
+ case ByteCode.JSR_W:
+ case ByteCode.LDC:
+ case ByteCode.LDC2_W:
+ case ByteCode.LDC_W:
+ case ByteCode.LLOAD:
+ case ByteCode.LSTORE:
+ case ByteCode.NEW:
+ case ByteCode.NEWARRAY:
+ case ByteCode.PUTFIELD:
+ case ByteCode.PUTSTATIC:
+ case ByteCode.RET:
+ case ByteCode.SIPUSH:
+ return 1;
+
+ case ByteCode.IINC:
+ case ByteCode.MULTIANEWARRAY:
+ return 2;
+
+ case ByteCode.LOOKUPSWITCH:
+ case ByteCode.TABLESWITCH:
+ return -1;
+ }
+ throw new IllegalArgumentException("Bad opcode: "+opcode);
+ }
+
+ /**
+ * The effect on the operand stack of a given opcode.
+ */
+ static int stackChange(int opcode)
+ {
+ // For INVOKE... accounts only for popping this (unless static),
+ // ignoring parameters and return type
+ switch (opcode) {
+ case ByteCode.DASTORE:
+ case ByteCode.LASTORE:
+ return -4;
+
+ case ByteCode.AASTORE:
+ case ByteCode.BASTORE:
+ case ByteCode.CASTORE:
+ case ByteCode.DCMPG:
+ case ByteCode.DCMPL:
+ case ByteCode.FASTORE:
+ case ByteCode.IASTORE:
+ case ByteCode.LCMP:
+ case ByteCode.SASTORE:
+ return -3;
+
+ case ByteCode.DADD:
+ case ByteCode.DDIV:
+ case ByteCode.DMUL:
+ case ByteCode.DREM:
+ case ByteCode.DRETURN:
+ case ByteCode.DSTORE:
+ case ByteCode.DSTORE_0:
+ case ByteCode.DSTORE_1:
+ case ByteCode.DSTORE_2:
+ case ByteCode.DSTORE_3:
+ case ByteCode.DSUB:
+ case ByteCode.IF_ACMPEQ:
+ case ByteCode.IF_ACMPNE:
+ case ByteCode.IF_ICMPEQ:
+ case ByteCode.IF_ICMPGE:
+ case ByteCode.IF_ICMPGT:
+ case ByteCode.IF_ICMPLE:
+ case ByteCode.IF_ICMPLT:
+ case ByteCode.IF_ICMPNE:
+ case ByteCode.LADD:
+ case ByteCode.LAND:
+ case ByteCode.LDIV:
+ case ByteCode.LMUL:
+ case ByteCode.LOR:
+ case ByteCode.LREM:
+ case ByteCode.LRETURN:
+ case ByteCode.LSTORE:
+ case ByteCode.LSTORE_0:
+ case ByteCode.LSTORE_1:
+ case ByteCode.LSTORE_2:
+ case ByteCode.LSTORE_3:
+ case ByteCode.LSUB:
+ case ByteCode.LXOR:
+ case ByteCode.POP2:
+ return -2;
+
+ case ByteCode.AALOAD:
+ case ByteCode.ARETURN:
+ case ByteCode.ASTORE:
+ case ByteCode.ASTORE_0:
+ case ByteCode.ASTORE_1:
+ case ByteCode.ASTORE_2:
+ case ByteCode.ASTORE_3:
+ case ByteCode.ATHROW:
+ case ByteCode.BALOAD:
+ case ByteCode.CALOAD:
+ case ByteCode.D2F:
+ case ByteCode.D2I:
+ case ByteCode.FADD:
+ case ByteCode.FALOAD:
+ case ByteCode.FCMPG:
+ case ByteCode.FCMPL:
+ case ByteCode.FDIV:
+ case ByteCode.FMUL:
+ case ByteCode.FREM:
+ case ByteCode.FRETURN:
+ case ByteCode.FSTORE:
+ case ByteCode.FSTORE_0:
+ case ByteCode.FSTORE_1:
+ case ByteCode.FSTORE_2:
+ case ByteCode.FSTORE_3:
+ case ByteCode.FSUB:
+ case ByteCode.GETFIELD:
+ case ByteCode.IADD:
+ case ByteCode.IALOAD:
+ case ByteCode.IAND:
+ case ByteCode.IDIV:
+ case ByteCode.IFEQ:
+ case ByteCode.IFGE:
+ case ByteCode.IFGT:
+ case ByteCode.IFLE:
+ case ByteCode.IFLT:
+ case ByteCode.IFNE:
+ case ByteCode.IFNONNULL:
+ case ByteCode.IFNULL:
+ case ByteCode.IMUL:
+ case ByteCode.INVOKEINTERFACE: //
+ case ByteCode.INVOKESPECIAL: // but needs to account for
+ case ByteCode.INVOKEVIRTUAL: // pops 'this' (unless static)
+ case ByteCode.IOR:
+ case ByteCode.IREM:
+ case ByteCode.IRETURN:
+ case ByteCode.ISHL:
+ case ByteCode.ISHR:
+ case ByteCode.ISTORE:
+ case ByteCode.ISTORE_0:
+ case ByteCode.ISTORE_1:
+ case ByteCode.ISTORE_2:
+ case ByteCode.ISTORE_3:
+ case ByteCode.ISUB:
+ case ByteCode.IUSHR:
+ case ByteCode.IXOR:
+ case ByteCode.L2F:
+ case ByteCode.L2I:
+ case ByteCode.LOOKUPSWITCH:
+ case ByteCode.LSHL:
+ case ByteCode.LSHR:
+ case ByteCode.LUSHR:
+ case ByteCode.MONITORENTER:
+ case ByteCode.MONITOREXIT:
+ case ByteCode.POP:
+ case ByteCode.PUTFIELD:
+ case ByteCode.SALOAD:
+ case ByteCode.TABLESWITCH:
+ return -1;
+
+ case ByteCode.ANEWARRAY:
+ case ByteCode.ARRAYLENGTH:
+ case ByteCode.BREAKPOINT:
+ case ByteCode.CHECKCAST:
+ case ByteCode.D2L:
+ case ByteCode.DALOAD:
+ case ByteCode.DNEG:
+ case ByteCode.F2I:
+ case ByteCode.FNEG:
+ case ByteCode.GETSTATIC:
+ case ByteCode.GOTO:
+ case ByteCode.GOTO_W:
+ case ByteCode.I2B:
+ case ByteCode.I2C:
+ case ByteCode.I2F:
+ case ByteCode.I2S:
+ case ByteCode.IINC:
+ case ByteCode.IMPDEP1:
+ case ByteCode.IMPDEP2:
+ case ByteCode.INEG:
+ case ByteCode.INSTANCEOF:
+ case ByteCode.INVOKESTATIC:
+ case ByteCode.L2D:
+ case ByteCode.LALOAD:
+ case ByteCode.LNEG:
+ case ByteCode.NEWARRAY:
+ case ByteCode.NOP:
+ case ByteCode.PUTSTATIC:
+ case ByteCode.RET:
+ case ByteCode.RETURN:
+ case ByteCode.SWAP:
+ case ByteCode.WIDE:
+ return 0;
+
+ case ByteCode.ACONST_NULL:
+ case ByteCode.ALOAD:
+ case ByteCode.ALOAD_0:
+ case ByteCode.ALOAD_1:
+ case ByteCode.ALOAD_2:
+ case ByteCode.ALOAD_3:
+ case ByteCode.BIPUSH:
+ case ByteCode.DUP:
+ case ByteCode.DUP_X1:
+ case ByteCode.DUP_X2:
+ case ByteCode.F2D:
+ case ByteCode.F2L:
+ case ByteCode.FCONST_0:
+ case ByteCode.FCONST_1:
+ case ByteCode.FCONST_2:
+ case ByteCode.FLOAD:
+ case ByteCode.FLOAD_0:
+ case ByteCode.FLOAD_1:
+ case ByteCode.FLOAD_2:
+ case ByteCode.FLOAD_3:
+ case ByteCode.I2D:
+ case ByteCode.I2L:
+ case ByteCode.ICONST_0:
+ case ByteCode.ICONST_1:
+ case ByteCode.ICONST_2:
+ case ByteCode.ICONST_3:
+ case ByteCode.ICONST_4:
+ case ByteCode.ICONST_5:
+ case ByteCode.ICONST_M1:
+ case ByteCode.ILOAD:
+ case ByteCode.ILOAD_0:
+ case ByteCode.ILOAD_1:
+ case ByteCode.ILOAD_2:
+ case ByteCode.ILOAD_3:
+ case ByteCode.JSR:
+ case ByteCode.JSR_W:
+ case ByteCode.LDC:
+ case ByteCode.LDC_W:
+ case ByteCode.MULTIANEWARRAY:
+ case ByteCode.NEW:
+ case ByteCode.SIPUSH:
+ return 1;
+
+ case ByteCode.DCONST_0:
+ case ByteCode.DCONST_1:
+ case ByteCode.DLOAD:
+ case ByteCode.DLOAD_0:
+ case ByteCode.DLOAD_1:
+ case ByteCode.DLOAD_2:
+ case ByteCode.DLOAD_3:
+ case ByteCode.DUP2:
+ case ByteCode.DUP2_X1:
+ case ByteCode.DUP2_X2:
+ case ByteCode.LCONST_0:
+ case ByteCode.LCONST_1:
+ case ByteCode.LDC2_W:
+ case ByteCode.LLOAD:
+ case ByteCode.LLOAD_0:
+ case ByteCode.LLOAD_1:
+ case ByteCode.LLOAD_2:
+ case ByteCode.LLOAD_3:
+ return 2;
+ }
+ throw new IllegalArgumentException("Bad opcode: "+opcode);
+ }
+
+ /*
+ * Number of bytes of operands generated after the opcode.
+ * Not in use currently.
+ */
+/*
+ int extra(int opcode)
+ {
+ switch (opcode) {
+ case ByteCode.AALOAD:
+ case ByteCode.AASTORE:
+ case ByteCode.ACONST_NULL:
+ case ByteCode.ALOAD_0:
+ case ByteCode.ALOAD_1:
+ case ByteCode.ALOAD_2:
+ case ByteCode.ALOAD_3:
+ case ByteCode.ARETURN:
+ case ByteCode.ARRAYLENGTH:
+ case ByteCode.ASTORE_0:
+ case ByteCode.ASTORE_1:
+ case ByteCode.ASTORE_2:
+ case ByteCode.ASTORE_3:
+ case ByteCode.ATHROW:
+ case ByteCode.BALOAD:
+ case ByteCode.BASTORE:
+ case ByteCode.BREAKPOINT:
+ case ByteCode.CALOAD:
+ case ByteCode.CASTORE:
+ case ByteCode.D2F:
+ case ByteCode.D2I:
+ case ByteCode.D2L:
+ case ByteCode.DADD:
+ case ByteCode.DALOAD:
+ case ByteCode.DASTORE:
+ case ByteCode.DCMPG:
+ case ByteCode.DCMPL:
+ case ByteCode.DCONST_0:
+ case ByteCode.DCONST_1:
+ case ByteCode.DDIV:
+ case ByteCode.DLOAD_0:
+ case ByteCode.DLOAD_1:
+ case ByteCode.DLOAD_2:
+ case ByteCode.DLOAD_3:
+ case ByteCode.DMUL:
+ case ByteCode.DNEG:
+ case ByteCode.DREM:
+ case ByteCode.DRETURN:
+ case ByteCode.DSTORE_0:
+ case ByteCode.DSTORE_1:
+ case ByteCode.DSTORE_2:
+ case ByteCode.DSTORE_3:
+ case ByteCode.DSUB:
+ case ByteCode.DUP2:
+ case ByteCode.DUP2_X1:
+ case ByteCode.DUP2_X2:
+ case ByteCode.DUP:
+ case ByteCode.DUP_X1:
+ case ByteCode.DUP_X2:
+ case ByteCode.F2D:
+ case ByteCode.F2I:
+ case ByteCode.F2L:
+ case ByteCode.FADD:
+ case ByteCode.FALOAD:
+ case ByteCode.FASTORE:
+ case ByteCode.FCMPG:
+ case ByteCode.FCMPL:
+ case ByteCode.FCONST_0:
+ case ByteCode.FCONST_1:
+ case ByteCode.FCONST_2:
+ case ByteCode.FDIV:
+ case ByteCode.FLOAD_0:
+ case ByteCode.FLOAD_1:
+ case ByteCode.FLOAD_2:
+ case ByteCode.FLOAD_3:
+ case ByteCode.FMUL:
+ case ByteCode.FNEG:
+ case ByteCode.FREM:
+ case ByteCode.FRETURN:
+ case ByteCode.FSTORE_0:
+ case ByteCode.FSTORE_1:
+ case ByteCode.FSTORE_2:
+ case ByteCode.FSTORE_3:
+ case ByteCode.FSUB:
+ case ByteCode.I2B:
+ case ByteCode.I2C:
+ case ByteCode.I2D:
+ case ByteCode.I2F:
+ case ByteCode.I2L:
+ case ByteCode.I2S:
+ case ByteCode.IADD:
+ case ByteCode.IALOAD:
+ case ByteCode.IAND:
+ case ByteCode.IASTORE:
+ case ByteCode.ICONST_0:
+ case ByteCode.ICONST_1:
+ case ByteCode.ICONST_2:
+ case ByteCode.ICONST_3:
+ case ByteCode.ICONST_4:
+ case ByteCode.ICONST_5:
+ case ByteCode.ICONST_M1:
+ case ByteCode.IDIV:
+ case ByteCode.ILOAD_0:
+ case ByteCode.ILOAD_1:
+ case ByteCode.ILOAD_2:
+ case ByteCode.ILOAD_3:
+ case ByteCode.IMPDEP1:
+ case ByteCode.IMPDEP2:
+ case ByteCode.IMUL:
+ case ByteCode.INEG:
+ case ByteCode.IOR:
+ case ByteCode.IREM:
+ case ByteCode.IRETURN:
+ case ByteCode.ISHL:
+ case ByteCode.ISHR:
+ case ByteCode.ISTORE_0:
+ case ByteCode.ISTORE_1:
+ case ByteCode.ISTORE_2:
+ case ByteCode.ISTORE_3:
+ case ByteCode.ISUB:
+ case ByteCode.IUSHR:
+ case ByteCode.IXOR:
+ case ByteCode.L2D:
+ case ByteCode.L2F:
+ case ByteCode.L2I:
+ case ByteCode.LADD:
+ case ByteCode.LALOAD:
+ case ByteCode.LAND:
+ case ByteCode.LASTORE:
+ case ByteCode.LCMP:
+ case ByteCode.LCONST_0:
+ case ByteCode.LCONST_1:
+ case ByteCode.LDIV:
+ case ByteCode.LLOAD_0:
+ case ByteCode.LLOAD_1:
+ case ByteCode.LLOAD_2:
+ case ByteCode.LLOAD_3:
+ case ByteCode.LMUL:
+ case ByteCode.LNEG:
+ case ByteCode.LOR:
+ case ByteCode.LREM:
+ case ByteCode.LRETURN:
+ case ByteCode.LSHL:
+ case ByteCode.LSHR:
+ case ByteCode.LSTORE_0:
+ case ByteCode.LSTORE_1:
+ case ByteCode.LSTORE_2:
+ case ByteCode.LSTORE_3:
+ case ByteCode.LSUB:
+ case ByteCode.LUSHR:
+ case ByteCode.LXOR:
+ case ByteCode.MONITORENTER:
+ case ByteCode.MONITOREXIT:
+ case ByteCode.NOP:
+ case ByteCode.POP2:
+ case ByteCode.POP:
+ case ByteCode.RETURN:
+ case ByteCode.SALOAD:
+ case ByteCode.SASTORE:
+ case ByteCode.SWAP:
+ case ByteCode.WIDE:
+ return 0;
+
+ case ByteCode.ALOAD:
+ case ByteCode.ASTORE:
+ case ByteCode.BIPUSH:
+ case ByteCode.DLOAD:
+ case ByteCode.DSTORE:
+ case ByteCode.FLOAD:
+ case ByteCode.FSTORE:
+ case ByteCode.ILOAD:
+ case ByteCode.ISTORE:
+ case ByteCode.LDC:
+ case ByteCode.LLOAD:
+ case ByteCode.LSTORE:
+ case ByteCode.NEWARRAY:
+ case ByteCode.RET:
+ return 1;
+
+ case ByteCode.ANEWARRAY:
+ case ByteCode.CHECKCAST:
+ case ByteCode.GETFIELD:
+ case ByteCode.GETSTATIC:
+ case ByteCode.GOTO:
+ case ByteCode.IFEQ:
+ case ByteCode.IFGE:
+ case ByteCode.IFGT:
+ case ByteCode.IFLE:
+ case ByteCode.IFLT:
+ case ByteCode.IFNE:
+ case ByteCode.IFNONNULL:
+ case ByteCode.IFNULL:
+ case ByteCode.IF_ACMPEQ:
+ case ByteCode.IF_ACMPNE:
+ case ByteCode.IF_ICMPEQ:
+ case ByteCode.IF_ICMPGE:
+ case ByteCode.IF_ICMPGT:
+ case ByteCode.IF_ICMPLE:
+ case ByteCode.IF_ICMPLT:
+ case ByteCode.IF_ICMPNE:
+ case ByteCode.IINC:
+ case ByteCode.INSTANCEOF:
+ case ByteCode.INVOKEINTERFACE:
+ case ByteCode.INVOKESPECIAL:
+ case ByteCode.INVOKESTATIC:
+ case ByteCode.INVOKEVIRTUAL:
+ case ByteCode.JSR:
+ case ByteCode.LDC2_W:
+ case ByteCode.LDC_W:
+ case ByteCode.NEW:
+ case ByteCode.PUTFIELD:
+ case ByteCode.PUTSTATIC:
+ case ByteCode.SIPUSH:
+ return 2;
+
+ case ByteCode.MULTIANEWARRAY:
+ return 3;
+
+ case ByteCode.GOTO_W:
+ case ByteCode.JSR_W:
+ return 4;
+
+ case ByteCode.LOOKUPSWITCH: // depends on alignment
+ case ByteCode.TABLESWITCH: // depends on alignment
+ return -1;
+ }
+ throw new IllegalArgumentException("Bad opcode: "+opcode);
+ }
+*/
+ private static String bytecodeStr(int code)
+ {
+ if (DEBUGSTACK || DEBUGCODE) {
+ switch (code) {
+ case ByteCode.NOP: return "nop";
+ case ByteCode.ACONST_NULL: return "aconst_null";
+ case ByteCode.ICONST_M1: return "iconst_m1";
+ case ByteCode.ICONST_0: return "iconst_0";
+ case ByteCode.ICONST_1: return "iconst_1";
+ case ByteCode.ICONST_2: return "iconst_2";
+ case ByteCode.ICONST_3: return "iconst_3";
+ case ByteCode.ICONST_4: return "iconst_4";
+ case ByteCode.ICONST_5: return "iconst_5";
+ case ByteCode.LCONST_0: return "lconst_0";
+ case ByteCode.LCONST_1: return "lconst_1";
+ case ByteCode.FCONST_0: return "fconst_0";
+ case ByteCode.FCONST_1: return "fconst_1";
+ case ByteCode.FCONST_2: return "fconst_2";
+ case ByteCode.DCONST_0: return "dconst_0";
+ case ByteCode.DCONST_1: return "dconst_1";
+ case ByteCode.BIPUSH: return "bipush";
+ case ByteCode.SIPUSH: return "sipush";
+ case ByteCode.LDC: return "ldc";
+ case ByteCode.LDC_W: return "ldc_w";
+ case ByteCode.LDC2_W: return "ldc2_w";
+ case ByteCode.ILOAD: return "iload";
+ case ByteCode.LLOAD: return "lload";
+ case ByteCode.FLOAD: return "fload";
+ case ByteCode.DLOAD: return "dload";
+ case ByteCode.ALOAD: return "aload";
+ case ByteCode.ILOAD_0: return "iload_0";
+ case ByteCode.ILOAD_1: return "iload_1";
+ case ByteCode.ILOAD_2: return "iload_2";
+ case ByteCode.ILOAD_3: return "iload_3";
+ case ByteCode.LLOAD_0: return "lload_0";
+ case ByteCode.LLOAD_1: return "lload_1";
+ case ByteCode.LLOAD_2: return "lload_2";
+ case ByteCode.LLOAD_3: return "lload_3";
+ case ByteCode.FLOAD_0: return "fload_0";
+ case ByteCode.FLOAD_1: return "fload_1";
+ case ByteCode.FLOAD_2: return "fload_2";
+ case ByteCode.FLOAD_3: return "fload_3";
+ case ByteCode.DLOAD_0: return "dload_0";
+ case ByteCode.DLOAD_1: return "dload_1";
+ case ByteCode.DLOAD_2: return "dload_2";
+ case ByteCode.DLOAD_3: return "dload_3";
+ case ByteCode.ALOAD_0: return "aload_0";
+ case ByteCode.ALOAD_1: return "aload_1";
+ case ByteCode.ALOAD_2: return "aload_2";
+ case ByteCode.ALOAD_3: return "aload_3";
+ case ByteCode.IALOAD: return "iaload";
+ case ByteCode.LALOAD: return "laload";
+ case ByteCode.FALOAD: return "faload";
+ case ByteCode.DALOAD: return "daload";
+ case ByteCode.AALOAD: return "aaload";
+ case ByteCode.BALOAD: return "baload";
+ case ByteCode.CALOAD: return "caload";
+ case ByteCode.SALOAD: return "saload";
+ case ByteCode.ISTORE: return "istore";
+ case ByteCode.LSTORE: return "lstore";
+ case ByteCode.FSTORE: return "fstore";
+ case ByteCode.DSTORE: return "dstore";
+ case ByteCode.ASTORE: return "astore";
+ case ByteCode.ISTORE_0: return "istore_0";
+ case ByteCode.ISTORE_1: return "istore_1";
+ case ByteCode.ISTORE_2: return "istore_2";
+ case ByteCode.ISTORE_3: return "istore_3";
+ case ByteCode.LSTORE_0: return "lstore_0";
+ case ByteCode.LSTORE_1: return "lstore_1";
+ case ByteCode.LSTORE_2: return "lstore_2";
+ case ByteCode.LSTORE_3: return "lstore_3";
+ case ByteCode.FSTORE_0: return "fstore_0";
+ case ByteCode.FSTORE_1: return "fstore_1";
+ case ByteCode.FSTORE_2: return "fstore_2";
+ case ByteCode.FSTORE_3: return "fstore_3";
+ case ByteCode.DSTORE_0: return "dstore_0";
+ case ByteCode.DSTORE_1: return "dstore_1";
+ case ByteCode.DSTORE_2: return "dstore_2";
+ case ByteCode.DSTORE_3: return "dstore_3";
+ case ByteCode.ASTORE_0: return "astore_0";
+ case ByteCode.ASTORE_1: return "astore_1";
+ case ByteCode.ASTORE_2: return "astore_2";
+ case ByteCode.ASTORE_3: return "astore_3";
+ case ByteCode.IASTORE: return "iastore";
+ case ByteCode.LASTORE: return "lastore";
+ case ByteCode.FASTORE: return "fastore";
+ case ByteCode.DASTORE: return "dastore";
+ case ByteCode.AASTORE: return "aastore";
+ case ByteCode.BASTORE: return "bastore";
+ case ByteCode.CASTORE: return "castore";
+ case ByteCode.SASTORE: return "sastore";
+ case ByteCode.POP: return "pop";
+ case ByteCode.POP2: return "pop2";
+ case ByteCode.DUP: return "dup";
+ case ByteCode.DUP_X1: return "dup_x1";
+ case ByteCode.DUP_X2: return "dup_x2";
+ case ByteCode.DUP2: return "dup2";
+ case ByteCode.DUP2_X1: return "dup2_x1";
+ case ByteCode.DUP2_X2: return "dup2_x2";
+ case ByteCode.SWAP: return "swap";
+ case ByteCode.IADD: return "iadd";
+ case ByteCode.LADD: return "ladd";
+ case ByteCode.FADD: return "fadd";
+ case ByteCode.DADD: return "dadd";
+ case ByteCode.ISUB: return "isub";
+ case ByteCode.LSUB: return "lsub";
+ case ByteCode.FSUB: return "fsub";
+ case ByteCode.DSUB: return "dsub";
+ case ByteCode.IMUL: return "imul";
+ case ByteCode.LMUL: return "lmul";
+ case ByteCode.FMUL: return "fmul";
+ case ByteCode.DMUL: return "dmul";
+ case ByteCode.IDIV: return "idiv";
+ case ByteCode.LDIV: return "ldiv";
+ case ByteCode.FDIV: return "fdiv";
+ case ByteCode.DDIV: return "ddiv";
+ case ByteCode.IREM: return "irem";
+ case ByteCode.LREM: return "lrem";
+ case ByteCode.FREM: return "frem";
+ case ByteCode.DREM: return "drem";
+ case ByteCode.INEG: return "ineg";
+ case ByteCode.LNEG: return "lneg";
+ case ByteCode.FNEG: return "fneg";
+ case ByteCode.DNEG: return "dneg";
+ case ByteCode.ISHL: return "ishl";
+ case ByteCode.LSHL: return "lshl";
+ case ByteCode.ISHR: return "ishr";
+ case ByteCode.LSHR: return "lshr";
+ case ByteCode.IUSHR: return "iushr";
+ case ByteCode.LUSHR: return "lushr";
+ case ByteCode.IAND: return "iand";
+ case ByteCode.LAND: return "land";
+ case ByteCode.IOR: return "ior";
+ case ByteCode.LOR: return "lor";
+ case ByteCode.IXOR: return "ixor";
+ case ByteCode.LXOR: return "lxor";
+ case ByteCode.IINC: return "iinc";
+ case ByteCode.I2L: return "i2l";
+ case ByteCode.I2F: return "i2f";
+ case ByteCode.I2D: return "i2d";
+ case ByteCode.L2I: return "l2i";
+ case ByteCode.L2F: return "l2f";
+ case ByteCode.L2D: return "l2d";
+ case ByteCode.F2I: return "f2i";
+ case ByteCode.F2L: return "f2l";
+ case ByteCode.F2D: return "f2d";
+ case ByteCode.D2I: return "d2i";
+ case ByteCode.D2L: return "d2l";
+ case ByteCode.D2F: return "d2f";
+ case ByteCode.I2B: return "i2b";
+ case ByteCode.I2C: return "i2c";
+ case ByteCode.I2S: return "i2s";
+ case ByteCode.LCMP: return "lcmp";
+ case ByteCode.FCMPL: return "fcmpl";
+ case ByteCode.FCMPG: return "fcmpg";
+ case ByteCode.DCMPL: return "dcmpl";
+ case ByteCode.DCMPG: return "dcmpg";
+ case ByteCode.IFEQ: return "ifeq";
+ case ByteCode.IFNE: return "ifne";
+ case ByteCode.IFLT: return "iflt";
+ case ByteCode.IFGE: return "ifge";
+ case ByteCode.IFGT: return "ifgt";
+ case ByteCode.IFLE: return "ifle";
+ case ByteCode.IF_ICMPEQ: return "if_icmpeq";
+ case ByteCode.IF_ICMPNE: return "if_icmpne";
+ case ByteCode.IF_ICMPLT: return "if_icmplt";
+ case ByteCode.IF_ICMPGE: return "if_icmpge";
+ case ByteCode.IF_ICMPGT: return "if_icmpgt";
+ case ByteCode.IF_ICMPLE: return "if_icmple";
+ case ByteCode.IF_ACMPEQ: return "if_acmpeq";
+ case ByteCode.IF_ACMPNE: return "if_acmpne";
+ case ByteCode.GOTO: return "goto";
+ case ByteCode.JSR: return "jsr";
+ case ByteCode.RET: return "ret";
+ case ByteCode.TABLESWITCH: return "tableswitch";
+ case ByteCode.LOOKUPSWITCH: return "lookupswitch";
+ case ByteCode.IRETURN: return "ireturn";
+ case ByteCode.LRETURN: return "lreturn";
+ case ByteCode.FRETURN: return "freturn";
+ case ByteCode.DRETURN: return "dreturn";
+ case ByteCode.ARETURN: return "areturn";
+ case ByteCode.RETURN: return "return";
+ case ByteCode.GETSTATIC: return "getstatic";
+ case ByteCode.PUTSTATIC: return "putstatic";
+ case ByteCode.GETFIELD: return "getfield";
+ case ByteCode.PUTFIELD: return "putfield";
+ case ByteCode.INVOKEVIRTUAL: return "invokevirtual";
+ case ByteCode.INVOKESPECIAL: return "invokespecial";
+ case ByteCode.INVOKESTATIC: return "invokestatic";
+ case ByteCode.INVOKEINTERFACE: return "invokeinterface";
+ case ByteCode.NEW: return "new";
+ case ByteCode.NEWARRAY: return "newarray";
+ case ByteCode.ANEWARRAY: return "anewarray";
+ case ByteCode.ARRAYLENGTH: return "arraylength";
+ case ByteCode.ATHROW: return "athrow";
+ case ByteCode.CHECKCAST: return "checkcast";
+ case ByteCode.INSTANCEOF: return "instanceof";
+ case ByteCode.MONITORENTER: return "monitorenter";
+ case ByteCode.MONITOREXIT: return "monitorexit";
+ case ByteCode.WIDE: return "wide";
+ case ByteCode.MULTIANEWARRAY: return "multianewarray";
+ case ByteCode.IFNULL: return "ifnull";
+ case ByteCode.IFNONNULL: return "ifnonnull";
+ case ByteCode.GOTO_W: return "goto_w";
+ case ByteCode.JSR_W: return "jsr_w";
+ case ByteCode.BREAKPOINT: return "breakpoint";
+
+ case ByteCode.IMPDEP1: return "impdep1";
+ case ByteCode.IMPDEP2: return "impdep2";
+ }
+ }
+ return "";
+ }
+
+ final char[] getCharBuffer(int minimalSize)
+ {
+ if (minimalSize > tmpCharBuffer.length) {
+ int newSize = tmpCharBuffer.length * 2;
+ if (minimalSize > newSize) { newSize = minimalSize; }
+ tmpCharBuffer = new char[newSize];
+ }
+ return tmpCharBuffer;
+ }
+
+ private static final int LineNumberTableSize = 16;
+ private static final int ExceptionTableSize = 4;
+
+ private final static long FileHeaderConstant = 0xCAFEBABE0003002DL;
+ // Set DEBUG flags to true to get better checking and progress info.
+ private static final boolean DEBUGSTACK = false;
+ private static final boolean DEBUGLABELS = false;
+ private static final boolean DEBUGCODE = false;
+
+ private String generatedClassName;
+
+ private ExceptionTableEntry itsExceptionTable[];
+ private int itsExceptionTableTop;
+
+ private int itsLineNumberTable[]; // pack start_pc & line_number together
+ private int itsLineNumberTableTop;
+
+ private byte[] itsCodeBuffer = new byte[256];
+ private int itsCodeBufferTop;
+
+ private ConstantPool itsConstantPool;
+
+ private ClassFileMethod itsCurrentMethod;
+ private short itsStackTop;
+
+ private short itsMaxStack;
+ private short itsMaxLocals;
+
+ private ObjArray itsMethods = new ObjArray();
+ private ObjArray itsFields = new ObjArray();
+ private ObjArray itsInterfaces = new ObjArray();
+
+ private short itsFlags;
+ private short itsThisClassIndex;
+ private short itsSuperClassIndex;
+ private short itsSourceFileNameIndex;
+
+ private static final int MIN_LABEL_TABLE_SIZE = 32;
+ private int[] itsLabelTable;
+ private int itsLabelTableTop;
+
+// itsFixupTable[i] = (label_index << 32) | fixup_site
+ private static final int MIN_FIXUP_TABLE_SIZE = 40;
+ private long[] itsFixupTable;
+ private int itsFixupTableTop;
+ private ObjArray itsVarDescriptors;
+
+ private char[] tmpCharBuffer = new char[64];
+}
+
+final class ExceptionTableEntry
+{
+
+ ExceptionTableEntry(int startLabel, int endLabel,
+ int handlerLabel, short catchType)
+ {
+ itsStartLabel = startLabel;
+ itsEndLabel = endLabel;
+ itsHandlerLabel = handlerLabel;
+ itsCatchType = catchType;
+ }
+
+ int itsStartLabel;
+ int itsEndLabel;
+ int itsHandlerLabel;
+ short itsCatchType;
+}
+
+final class ClassFileField
+{
+
+ ClassFileField(short nameIndex, short typeIndex, short flags)
+ {
+ itsNameIndex = nameIndex;
+ itsTypeIndex = typeIndex;
+ itsFlags = flags;
+ itsHasAttributes = false;
+ }
+
+ void setAttributes(short attr1, short attr2, short attr3, int index)
+ {
+ itsHasAttributes = true;
+ itsAttr1 = attr1;
+ itsAttr2 = attr2;
+ itsAttr3 = attr3;
+ itsIndex = index;
+ }
+
+ int write(byte[] data, int offset)
+ {
+ offset = ClassFileWriter.putInt16(itsFlags, data, offset);
+ offset = ClassFileWriter.putInt16(itsNameIndex, data, offset);
+ offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset);
+ if (!itsHasAttributes) {
+ // write 0 attributes
+ offset = ClassFileWriter.putInt16(0, data, offset);
+ } else {
+ offset = ClassFileWriter.putInt16(1, data, offset);
+ offset = ClassFileWriter.putInt16(itsAttr1, data, offset);
+ offset = ClassFileWriter.putInt16(itsAttr2, data, offset);
+ offset = ClassFileWriter.putInt16(itsAttr3, data, offset);
+ offset = ClassFileWriter.putInt16(itsIndex, data, offset);
+ }
+ return offset;
+ }
+
+ int getWriteSize()
+ {
+ int size = 2 * 3;
+ if (!itsHasAttributes) {
+ size += 2;
+ } else {
+ size += 2 + 2 * 4;
+ }
+ return size;
+ }
+
+ private short itsNameIndex;
+ private short itsTypeIndex;
+ private short itsFlags;
+ private boolean itsHasAttributes;
+ private short itsAttr1, itsAttr2, itsAttr3;
+ private int itsIndex;
+}
+
+final class ClassFileMethod
+{
+
+ ClassFileMethod(short nameIndex, short typeIndex, short flags)
+ {
+ itsNameIndex = nameIndex;
+ itsTypeIndex = typeIndex;
+ itsFlags = flags;
+ }
+
+ void setCodeAttribute(byte codeAttribute[])
+ {
+ itsCodeAttribute = codeAttribute;
+ }
+
+ int write(byte[] data, int offset)
+ {
+ offset = ClassFileWriter.putInt16(itsFlags, data, offset);
+ offset = ClassFileWriter.putInt16(itsNameIndex, data, offset);
+ offset = ClassFileWriter.putInt16(itsTypeIndex, data, offset);
+ // Code attribute only
+ offset = ClassFileWriter.putInt16(1, data, offset);
+ System.arraycopy(itsCodeAttribute, 0, data, offset,
+ itsCodeAttribute.length);
+ offset += itsCodeAttribute.length;
+ return offset;
+ }
+
+ int getWriteSize()
+ {
+ return 2 * 4 + itsCodeAttribute.length;
+ }
+
+ private short itsNameIndex;
+ private short itsTypeIndex;
+ private short itsFlags;
+ private byte[] itsCodeAttribute;
+
+}
+
+final class ConstantPool
+{
+
+ ConstantPool(ClassFileWriter cfw)
+ {
+ this.cfw = cfw;
+ itsTopIndex = 1; // the zero'th entry is reserved
+ itsPool = new byte[ConstantPoolSize];
+ itsTop = 0;
+ }
+
+ private static final int ConstantPoolSize = 256;
+ private static final byte
+ CONSTANT_Class = 7,
+ CONSTANT_Fieldref = 9,
+ CONSTANT_Methodref = 10,
+ CONSTANT_InterfaceMethodref = 11,
+ CONSTANT_String = 8,
+ CONSTANT_Integer = 3,
+ CONSTANT_Float = 4,
+ CONSTANT_Long = 5,
+ CONSTANT_Double = 6,
+ CONSTANT_NameAndType = 12,
+ CONSTANT_Utf8 = 1;
+
+ int write(byte[] data, int offset)
+ {
+ offset = ClassFileWriter.putInt16((short)itsTopIndex, data, offset);
+ System.arraycopy(itsPool, 0, data, offset, itsTop);
+ offset += itsTop;
+ return offset;
+ }
+
+ int getWriteSize()
+ {
+ return 2 + itsTop;
+ }
+
+ int addConstant(int k)
+ {
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_Integer;
+ itsTop = ClassFileWriter.putInt32(k, itsPool, itsTop);
+ return (short)(itsTopIndex++);
+ }
+
+ int addConstant(long k)
+ {
+ ensure(9);
+ itsPool[itsTop++] = CONSTANT_Long;
+ itsTop = ClassFileWriter.putInt64(k, itsPool, itsTop);
+ int index = itsTopIndex;
+ itsTopIndex += 2;
+ return index;
+ }
+
+ int addConstant(float k)
+ {
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_Float;
+ int bits = Float.floatToIntBits(k);
+ itsTop = ClassFileWriter.putInt32(bits, itsPool, itsTop);
+ return itsTopIndex++;
+ }
+
+ int addConstant(double k)
+ {
+ ensure(9);
+ itsPool[itsTop++] = CONSTANT_Double;
+ long bits = Double.doubleToLongBits(k);
+ itsTop = ClassFileWriter.putInt64(bits, itsPool, itsTop);
+ int index = itsTopIndex;
+ itsTopIndex += 2;
+ return index;
+ }
+
+ int addConstant(String k)
+ {
+ int utf8Index = 0xFFFF & addUtf8(k);
+ int theIndex = itsStringConstHash.getInt(utf8Index, -1);
+ if (theIndex == -1) {
+ theIndex = itsTopIndex++;
+ ensure(3);
+ itsPool[itsTop++] = CONSTANT_String;
+ itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop);
+ itsStringConstHash.put(utf8Index, theIndex);
+ }
+ return theIndex;
+ }
+
+ boolean isUnderUtfEncodingLimit(String s)
+ {
+ int strLen = s.length();
+ if (strLen * 3 <= MAX_UTF_ENCODING_SIZE) {
+ return true;
+ } else if (strLen > MAX_UTF_ENCODING_SIZE) {
+ return false;
+ }
+ return strLen == getUtfEncodingLimit(s, 0, strLen);
+ }
+
+ /**
+ * Get maximum i such that <tt>start <= i <= end</tt> and
+ * <tt>s.substring(start, i)</tt> fits JVM UTF string encoding limit.
+ */
+ int getUtfEncodingLimit(String s, int start, int end)
+ {
+ if ((end - start) * 3 <= MAX_UTF_ENCODING_SIZE) {
+ return end;
+ }
+ int limit = MAX_UTF_ENCODING_SIZE;
+ for (int i = start; i != end; i++) {
+ int c = s.charAt(i);
+ if (0 != c && c <= 0x7F) {
+ --limit;
+ } else if (c < 0x7FF) {
+ limit -= 2;
+ } else {
+ limit -= 3;
+ }
+ if (limit < 0) {
+ return i;
+ }
+ }
+ return end;
+ }
+
+ short addUtf8(String k)
+ {
+ int theIndex = itsUtf8Hash.get(k, -1);
+ if (theIndex == -1) {
+ int strLen = k.length();
+ boolean tooBigString;
+ if (strLen > MAX_UTF_ENCODING_SIZE) {
+ tooBigString = true;
+ } else {
+ tooBigString = false;
+ // Ask for worst case scenario buffer when each char takes 3
+ // bytes
+ ensure(1 + 2 + strLen * 3);
+ int top = itsTop;
+
+ itsPool[top++] = CONSTANT_Utf8;
+ top += 2; // skip length
+
+ char[] chars = cfw.getCharBuffer(strLen);
+ k.getChars(0, strLen, chars, 0);
+
+ for (int i = 0; i != strLen; i++) {
+ int c = chars[i];
+ if (c != 0 && c <= 0x7F) {
+ itsPool[top++] = (byte)c;
+ } else if (c > 0x7FF) {
+ itsPool[top++] = (byte)(0xE0 | (c >> 12));
+ itsPool[top++] = (byte)(0x80 | ((c >> 6) & 0x3F));
+ itsPool[top++] = (byte)(0x80 | (c & 0x3F));
+ } else {
+ itsPool[top++] = (byte)(0xC0 | (c >> 6));
+ itsPool[top++] = (byte)(0x80 | (c & 0x3F));
+ }
+ }
+
+ int utfLen = top - (itsTop + 1 + 2);
+ if (utfLen > MAX_UTF_ENCODING_SIZE) {
+ tooBigString = true;
+ } else {
+ // Write back length
+ itsPool[itsTop + 1] = (byte)(utfLen >>> 8);
+ itsPool[itsTop + 2] = (byte)utfLen;
+
+ itsTop = top;
+ theIndex = itsTopIndex++;
+ itsUtf8Hash.put(k, theIndex);
+ }
+ }
+ if (tooBigString) {
+ throw new IllegalArgumentException("Too big string");
+ }
+ }
+ return (short)theIndex;
+ }
+
+ private short addNameAndType(String name, String type)
+ {
+ short nameIndex = addUtf8(name);
+ short typeIndex = addUtf8(type);
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_NameAndType;
+ itsTop = ClassFileWriter.putInt16(nameIndex, itsPool, itsTop);
+ itsTop = ClassFileWriter.putInt16(typeIndex, itsPool, itsTop);
+ return (short)(itsTopIndex++);
+ }
+
+ short addClass(String className)
+ {
+ int theIndex = itsClassHash.get(className, -1);
+ if (theIndex == -1) {
+ String slashed = className;
+ if (className.indexOf('.') > 0) {
+ slashed = ClassFileWriter.getSlashedForm(className);
+ theIndex = itsClassHash.get(slashed, -1);
+ if (theIndex != -1) {
+ itsClassHash.put(className, theIndex);
+ }
+ }
+ if (theIndex == -1) {
+ int utf8Index = addUtf8(slashed);
+ ensure(3);
+ itsPool[itsTop++] = CONSTANT_Class;
+ itsTop = ClassFileWriter.putInt16(utf8Index, itsPool, itsTop);
+ theIndex = itsTopIndex++;
+ itsClassHash.put(slashed, theIndex);
+ if (className != slashed) {
+ itsClassHash.put(className, theIndex);
+ }
+ }
+ }
+ return (short)theIndex;
+ }
+
+ short addFieldRef(String className, String fieldName, String fieldType)
+ {
+ FieldOrMethodRef ref = new FieldOrMethodRef(className, fieldName,
+ fieldType);
+
+ int theIndex = itsFieldRefHash.get(ref, -1);
+ if (theIndex == -1) {
+ short ntIndex = addNameAndType(fieldName, fieldType);
+ short classIndex = addClass(className);
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_Fieldref;
+ itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
+ itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
+ theIndex = itsTopIndex++;
+ itsFieldRefHash.put(ref, theIndex);
+ }
+ return (short)theIndex;
+ }
+
+ short addMethodRef(String className, String methodName,
+ String methodType)
+ {
+ FieldOrMethodRef ref = new FieldOrMethodRef(className, methodName,
+ methodType);
+
+ int theIndex = itsMethodRefHash.get(ref, -1);
+ if (theIndex == -1) {
+ short ntIndex = addNameAndType(methodName, methodType);
+ short classIndex = addClass(className);
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_Methodref;
+ itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
+ itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
+ theIndex = itsTopIndex++;
+ itsMethodRefHash.put(ref, theIndex);
+ }
+ return (short)theIndex;
+ }
+
+ short addInterfaceMethodRef(String className,
+ String methodName, String methodType)
+ {
+ short ntIndex = addNameAndType(methodName, methodType);
+ short classIndex = addClass(className);
+ ensure(5);
+ itsPool[itsTop++] = CONSTANT_InterfaceMethodref;
+ itsTop = ClassFileWriter.putInt16(classIndex, itsPool, itsTop);
+ itsTop = ClassFileWriter.putInt16(ntIndex, itsPool, itsTop);
+ return (short)(itsTopIndex++);
+ }
+
+ void ensure(int howMuch)
+ {
+ if (itsTop + howMuch > itsPool.length) {
+ int newCapacity = itsPool.length * 2;
+ if (itsTop + howMuch > newCapacity) {
+ newCapacity = itsTop + howMuch;
+ }
+ byte[] tmp = new byte[newCapacity];
+ System.arraycopy(itsPool, 0, tmp, 0, itsTop);
+ itsPool = tmp;
+ }
+ }
+
+ private ClassFileWriter cfw;
+
+ private static final int MAX_UTF_ENCODING_SIZE = 65535;
+
+ private UintMap itsStringConstHash = new UintMap();
+ private ObjToIntMap itsUtf8Hash = new ObjToIntMap();
+ private ObjToIntMap itsFieldRefHash = new ObjToIntMap();
+ private ObjToIntMap itsMethodRefHash = new ObjToIntMap();
+ private ObjToIntMap itsClassHash = new ObjToIntMap();
+
+ private int itsTop;
+ private int itsTopIndex;
+ private byte itsPool[];
+}
+
+final class FieldOrMethodRef
+{
+ FieldOrMethodRef(String className, String name, String type)
+ {
+ this.className = className;
+ this.name = name;
+ this.type = type;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof FieldOrMethodRef)) { return false; }
+ FieldOrMethodRef x = (FieldOrMethodRef)obj;
+ return className.equals(x.className)
+ && name.equals(x.name)
+ && type.equals(x.type);
+ }
+
+ public int hashCode()
+ {
+ if (hashCode == -1) {
+ int h1 = className.hashCode();
+ int h2 = name.hashCode();
+ int h3 = type.hashCode();
+ hashCode = h1 ^ h2 ^ h3;
+ }
+ return hashCode;
+ }
+
+ private String className;
+ private String name;
+ private String type;
+ private int hashCode = -1;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
new file mode 100644
index 0000000..954b078
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Arguments.java
@@ -0,0 +1,311 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the "arguments" object.
+ *
+ * See ECMA 10.1.8
+ *
+ * @see org.mozilla.javascript.NativeCall
+ * @author Norris Boyd
+ */
+final class Arguments extends IdScriptableObject
+{
+ static final long serialVersionUID = 4275508002492040609L;
+
+ public Arguments(NativeCall activation)
+ {
+ this.activation = activation;
+
+ Scriptable parent = activation.getParentScope();
+ setParentScope(parent);
+ setPrototype(ScriptableObject.getObjectPrototype(parent));
+
+ args = activation.originalArgs;
+ lengthObj = new Integer(args.length);
+
+ NativeFunction f = activation.function;
+ calleeObj = f;
+
+ int version = f.getLanguageVersion();
+ if (version <= Context.VERSION_1_3
+ && version != Context.VERSION_DEFAULT)
+ {
+ callerObj = null;
+ } else {
+ callerObj = NOT_FOUND;
+ }
+ }
+
+ public String getClassName()
+ {
+ return "Object";
+ }
+
+ public boolean has(int index, Scriptable start)
+ {
+ if (0 <= index && index < args.length) {
+ if (args[index] != NOT_FOUND) {
+ return true;
+ }
+ }
+ return super.has(index, start);
+ }
+
+ public Object get(int index, Scriptable start)
+ {
+ if (0 <= index && index < args.length) {
+ Object value = args[index];
+ if (value != NOT_FOUND) {
+ if (sharedWithActivation(index)) {
+ NativeFunction f = activation.function;
+ String argName = f.getParamOrVarName(index);
+ value = activation.get(argName, activation);
+ if (value == NOT_FOUND) Kit.codeBug();
+ }
+ return value;
+ }
+ }
+ return super.get(index, start);
+ }
+
+ private boolean sharedWithActivation(int index)
+ {
+ NativeFunction f = activation.function;
+ int definedCount = f.getParamCount();
+ if (index < definedCount) {
+ // Check if argument is not hidden by later argument with the same
+ // name as hidden arguments are not shared with activation
+ if (index < definedCount - 1) {
+ String argName = f.getParamOrVarName(index);
+ for (int i = index + 1; i < definedCount; i++) {
+ if (argName.equals(f.getParamOrVarName(i))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void put(int index, Scriptable start, Object value)
+ {
+ if (0 <= index && index < args.length) {
+ if (args[index] != NOT_FOUND) {
+ if (sharedWithActivation(index)) {
+ String argName;
+ argName = activation.function.getParamOrVarName(index);
+ activation.put(argName, activation, value);
+ return;
+ }
+ synchronized (this) {
+ if (args[index] != NOT_FOUND) {
+ if (args == activation.originalArgs) {
+ args = args.clone();
+ }
+ args[index] = value;
+ return;
+ }
+ }
+ }
+ }
+ super.put(index, start, value);
+ }
+
+ public void delete(int index)
+ {
+ if (0 <= index && index < args.length) {
+ synchronized (this) {
+ if (args[index] != NOT_FOUND) {
+ if (args == activation.originalArgs) {
+ args = args.clone();
+ }
+ args[index] = NOT_FOUND;
+ return;
+ }
+ }
+ }
+ super.delete(index);
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_callee = 1,
+ Id_length = 2,
+ Id_caller = 3,
+
+ MAX_INSTANCE_ID = 3;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:04 EDT
+ L0: { id = 0; String X = null; int c;
+ if (s.length()==6) {
+ c=s.charAt(5);
+ if (c=='e') { X="callee";id=Id_callee; }
+ else if (c=='h') { X="length";id=Id_length; }
+ else if (c=='r') { X="caller";id=Id_caller; }
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_callee:
+ case Id_caller:
+ case Id_length:
+ attr = DONTENUM;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, id);
+ }
+
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id) {
+ case Id_callee: return "callee";
+ case Id_length: return "length";
+ case Id_caller: return "caller";
+ }
+ return null;
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id) {
+ case Id_callee: return calleeObj;
+ case Id_length: return lengthObj;
+ case Id_caller: {
+ Object value = callerObj;
+ if (value == UniqueTag.NULL_VALUE) { value = null; }
+ else if (value == null) {
+ NativeCall caller = activation.parentActivationCall;
+ if (caller != null) {
+ value = caller.get("arguments", caller);
+ }
+ }
+ return value;
+ }
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ switch (id) {
+ case Id_callee: calleeObj = value; return;
+ case Id_length: lengthObj = value; return;
+ case Id_caller:
+ callerObj = (value != null) ? value : UniqueTag.NULL_VALUE;
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+ Object[] getIds(boolean getAll)
+ {
+ Object[] ids = super.getIds(getAll);
+ if (getAll && args.length != 0) {
+ boolean[] present = null;
+ int extraCount = args.length;
+ for (int i = 0; i != ids.length; ++i) {
+ Object id = ids[i];
+ if (id instanceof Integer) {
+ int index = ((Integer)id).intValue();
+ if (0 <= index && index < args.length) {
+ if (present == null) {
+ present = new boolean[args.length];
+ }
+ if (!present[index]) {
+ present[index] = true;
+ extraCount--;
+ }
+ }
+ }
+ }
+ if (extraCount != 0) {
+ Object[] tmp = new Object[extraCount + ids.length];
+ System.arraycopy(ids, 0, tmp, extraCount, ids.length);
+ ids = tmp;
+ int offset = 0;
+ for (int i = 0; i != args.length; ++i) {
+ if (present == null || !present[i]) {
+ ids[offset] = new Integer(i);
+ ++offset;
+ }
+ }
+ if (offset != extraCount) Kit.codeBug();
+ }
+ }
+ return ids;
+ }
+
+// Fields to hold caller, callee and length properties,
+// where NOT_FOUND value tags deleted properties.
+// In addition if callerObj == NULL_VALUE, it tags null for scripts, as
+// initial callerObj == null means access to caller arguments available
+// only in JS <= 1.3 scripts
+ private Object callerObj;
+ private Object calleeObj;
+ private Object lengthObj;
+
+ private NativeCall activation;
+
+// Initially args holds activation.getOriginalArgs(), but any modification
+// of its elements triggers creation of a copy. If its element holds NOT_FOUND,
+// it indicates deleted index, in which case super class is queried.
+ private Object[] args;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java
new file mode 100644
index 0000000..d7d8992
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/BaseFunction.java
@@ -0,0 +1,553 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Roger Lawrence
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The base class for Function objects
+ * See ECMA 15.3.
+ * @author Norris Boyd
+ */
+public class BaseFunction extends IdScriptableObject implements Function
+{
+
+ static final long serialVersionUID = 5311394446546053859L;
+
+ private static final Object FUNCTION_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ BaseFunction obj = new BaseFunction();
+ // Function.prototype attributes: see ECMA 15.3.3.1
+ obj.prototypePropertyAttributes = DONTENUM | READONLY | PERMANENT;
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ public BaseFunction()
+ {
+ }
+
+ public BaseFunction(Scriptable scope, Scriptable prototype)
+ {
+ super(scope, prototype);
+ }
+
+ public String getClassName() {
+ return "Function";
+ }
+
+ /**
+ * Implements the instanceof operator for JavaScript Function objects.
+ * <p>
+ * <code>
+ * foo = new Foo();<br>
+ * foo instanceof Foo; // true<br>
+ * </code>
+ *
+ * @param instance The value that appeared on the LHS of the instanceof
+ * operator
+ * @return true if the "prototype" property of "this" appears in
+ * value's prototype chain
+ *
+ */
+ public boolean hasInstance(Scriptable instance)
+ {
+ Object protoProp = ScriptableObject.getProperty(this, "prototype");
+ if (protoProp instanceof Scriptable) {
+ return ScriptRuntime.jsDelegatesTo(instance, (Scriptable)protoProp);
+ }
+ throw ScriptRuntime.typeError1("msg.instanceof.bad.prototype",
+ getFunctionName());
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_length = 1,
+ Id_arity = 2,
+ Id_name = 3,
+ Id_prototype = 4,
+ Id_arguments = 5,
+
+ MAX_INSTANCE_ID = 5;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:15 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 4: X="name";id=Id_name; break L;
+ case 5: X="arity";id=Id_arity; break L;
+ case 6: X="length";id=Id_length; break L;
+ case 9: c=s.charAt(0);
+ if (c=='a') { X="arguments";id=Id_arguments; }
+ else if (c=='p') { X="prototype";id=Id_prototype; }
+ break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+// #/string_id_map#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_length:
+ case Id_arity:
+ case Id_name:
+ attr = DONTENUM | READONLY | PERMANENT;
+ break;
+ case Id_prototype:
+ attr = prototypePropertyAttributes;
+ break;
+ case Id_arguments:
+ attr = DONTENUM | PERMANENT;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, id);
+ }
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id) {
+ case Id_length: return "length";
+ case Id_arity: return "arity";
+ case Id_name: return "name";
+ case Id_prototype: return "prototype";
+ case Id_arguments: return "arguments";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id) {
+ case Id_length: return ScriptRuntime.wrapInt(getLength());
+ case Id_arity: return ScriptRuntime.wrapInt(getArity());
+ case Id_name: return getFunctionName();
+ case Id_prototype: return getPrototypeProperty();
+ case Id_arguments: return getArguments();
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ if (id == Id_prototype) {
+ if ((prototypePropertyAttributes & READONLY) == 0) {
+ prototypeProperty = (value != null)
+ ? value : UniqueTag.NULL_VALUE;
+ }
+ return;
+ } else if (id == Id_arguments) {
+ if (value == NOT_FOUND) {
+ // This should not be called since "arguments" is PERMANENT
+ Kit.codeBug();
+ }
+ defaultPut("arguments", value);
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ // Fix up bootstrapping problem: getPrototype of the IdFunctionObject
+ // can not return Function.prototype because Function object is not
+ // yet defined.
+ ctor.setPrototype(this);
+ super.fillConstructorProperties(ctor);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=1; s="toString"; break;
+ case Id_toSource: arity=1; s="toSource"; break;
+ case Id_apply: arity=2; s="apply"; break;
+ case Id_call: arity=1; s="call"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(FUNCTION_TAG, id, s, arity);
+ }
+
+ static boolean isApply(IdFunctionObject f) {
+ return f.hasTag(FUNCTION_TAG) && f.methodId() == Id_apply;
+ }
+
+ static boolean isApplyOrCall(IdFunctionObject f) {
+ if(f.hasTag(FUNCTION_TAG)) {
+ switch(f.methodId()) {
+ case Id_apply:
+ case Id_call:
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(FUNCTION_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return jsConstructor(cx, scope, args);
+
+ case Id_toString: {
+ BaseFunction realf = realFunction(thisObj, f);
+ int indent = ScriptRuntime.toInt32(args, 0);
+ return realf.decompile(indent, 0);
+ }
+
+ case Id_toSource: {
+ BaseFunction realf = realFunction(thisObj, f);
+ int indent = 0;
+ int flags = Decompiler.TO_SOURCE_FLAG;
+ if (args.length != 0) {
+ indent = ScriptRuntime.toInt32(args[0]);
+ if (indent >= 0) {
+ flags = 0;
+ } else {
+ indent = 0;
+ }
+ }
+ return realf.decompile(indent, flags);
+ }
+
+ case Id_apply:
+ case Id_call:
+ return ScriptRuntime.applyOrCall(id == Id_apply,
+ cx, scope, thisObj, args);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private BaseFunction realFunction(Scriptable thisObj, IdFunctionObject f)
+ {
+ Object x = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
+ if (x instanceof BaseFunction) {
+ return (BaseFunction)x;
+ }
+ throw ScriptRuntime.typeError1("msg.incompat.call",
+ f.getFunctionName());
+ }
+
+ /**
+ * Make value as DontEnum, DontDelete, ReadOnly
+ * prototype property of this Function object
+ */
+ public void setImmunePrototypeProperty(Object value)
+ {
+ if ((prototypePropertyAttributes & READONLY) != 0) {
+ throw new IllegalStateException();
+ }
+ prototypeProperty = (value != null) ? value : UniqueTag.NULL_VALUE;
+ prototypePropertyAttributes = DONTENUM | PERMANENT | READONLY;
+ }
+
+ protected Scriptable getClassPrototype()
+ {
+ Object protoVal = getPrototypeProperty();
+ if (protoVal instanceof Scriptable) {
+ return (Scriptable) protoVal;
+ }
+ return getClassPrototype(this, "Object");
+ }
+
+ /**
+ * Should be overridden.
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return Undefined.instance;
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ Scriptable result = createObject(cx, scope);
+ if (result != null) {
+ Object val = call(cx, scope, result, args);
+ if (val instanceof Scriptable) {
+ result = (Scriptable)val;
+ }
+ } else {
+ Object val = call(cx, scope, null, args);
+ if (!(val instanceof Scriptable)) {
+ // It is program error not to return Scriptable from
+ // the call method if createObject returns null.
+ throw new IllegalStateException(
+ "Bad implementaion of call as constructor, name="
+ +getFunctionName()+" in "+getClass().getName());
+ }
+ result = (Scriptable)val;
+ if (result.getPrototype() == null) {
+ result.setPrototype(getClassPrototype());
+ }
+ if (result.getParentScope() == null) {
+ Scriptable parent = getParentScope();
+ if (result != parent) {
+ result.setParentScope(parent);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates new script object.
+ * The default implementation of {@link #construct} uses the method to
+ * to get the value for <tt>thisObj</tt> argument when invoking
+ * {@link #call}.
+ * The methos is allowed to return <tt>null</tt> to indicate that
+ * {@link #call} will create a new object itself. In this case
+ * {@link #construct} will set scope and prototype on the result
+ * {@link #call} unless they are already set.
+ */
+ public Scriptable createObject(Context cx, Scriptable scope)
+ {
+ Scriptable newInstance = new NativeObject();
+ newInstance.setPrototype(getClassPrototype());
+ newInstance.setParentScope(getParentScope());
+ return newInstance;
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string.
+ *
+ * @param indent How much to indent the decompiled result.
+ *
+ * @param flags Flags specifying format of decompilation output.
+ */
+ String decompile(int indent, int flags)
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ if (!justbody) {
+ sb.append("function ");
+ sb.append(getFunctionName());
+ sb.append("() {\n\t");
+ }
+ sb.append("[native code, arity=");
+ sb.append(getArity());
+ sb.append("]\n");
+ if (!justbody) {
+ sb.append("}\n");
+ }
+ return sb.toString();
+ }
+
+ public int getArity() { return 0; }
+
+ public int getLength() { return 0; }
+
+ public String getFunctionName()
+ {
+ return "";
+ }
+
+ final Object getPrototypeProperty() {
+ Object result = prototypeProperty;
+ if (result == null) {
+ synchronized (this) {
+ result = prototypeProperty;
+ if (result == null) {
+ setupDefaultPrototype();
+ result = prototypeProperty;
+ }
+ }
+ }
+ else if (result == UniqueTag.NULL_VALUE) { result = null; }
+ return result;
+ }
+
+ private void setupDefaultPrototype()
+ {
+ NativeObject obj = new NativeObject();
+ final int attr = ScriptableObject.DONTENUM;
+ obj.defineProperty("constructor", this, attr);
+ // put the prototype property into the object now, then in the
+ // wacky case of a user defining a function Object(), we don't
+ // get an infinite loop trying to find the prototype.
+ prototypeProperty = obj;
+ Scriptable proto = getObjectPrototype(this);
+ if (proto != obj) {
+ // not the one we just made, it must remain grounded
+ obj.setPrototype(proto);
+ }
+ }
+
+ private Object getArguments()
+ {
+ // <Function name>.arguments is deprecated, so we use a slow
+ // way of getting it that doesn't add to the invocation cost.
+ // TODO: add warning, error based on version
+ Object value = defaultGet("arguments");
+ if (value != NOT_FOUND) {
+ // Should after changing <Function name>.arguments its
+ // activation still be available during Function call?
+ // This code assumes it should not:
+ // defaultGet("arguments") != NOT_FOUND
+ // means assigned arguments
+ return value;
+ }
+ Context cx = Context.getContext();
+ NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
+ return (activation == null)
+ ? null
+ : activation.get("arguments", activation);
+ }
+
+ private static Object jsConstructor(Context cx, Scriptable scope,
+ Object[] args)
+ {
+ int arglen = args.length;
+ StringBuffer sourceBuf = new StringBuffer();
+
+ sourceBuf.append("function ");
+ /* version != 1.2 Function constructor behavior -
+ * print 'anonymous' as the function name if the
+ * version (under which the function was compiled) is
+ * less than 1.2... or if it's greater than 1.2, because
+ * we need to be closer to ECMA.
+ */
+ if (cx.getLanguageVersion() != Context.VERSION_1_2) {
+ sourceBuf.append("anonymous");
+ }
+ sourceBuf.append('(');
+
+ // Append arguments as coma separated strings
+ for (int i = 0; i < arglen - 1; i++) {
+ if (i > 0) {
+ sourceBuf.append(',');
+ }
+ sourceBuf.append(ScriptRuntime.toString(args[i]));
+ }
+ sourceBuf.append(") {");
+ if (arglen != 0) {
+ // append function body
+ String funBody = ScriptRuntime.toString(args[arglen - 1]);
+ sourceBuf.append(funBody);
+ }
+ sourceBuf.append('}');
+ String source = sourceBuf.toString();
+
+ int[] linep = new int[1];
+ String filename = Context.getSourcePositionFromStack(linep);
+ if (filename == null) {
+ filename = "<eval'ed string>";
+ linep[0] = 1;
+ }
+
+ String sourceURI = ScriptRuntime.
+ makeUrlForGeneratedScript(false, filename, linep[0]);
+
+ Scriptable global = ScriptableObject.getTopLevelScope(scope);
+
+ ErrorReporter reporter;
+ reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
+
+ Evaluator evaluator = Context.createInterpreter();
+ if (evaluator == null) {
+ throw new JavaScriptException("Interpreter not present",
+ filename, linep[0]);
+ }
+
+ // Compile with explicit interpreter instance to force interpreter
+ // mode.
+ return cx.compileFunction(global, source, evaluator, reporter,
+ sourceURI, 1, null);
+ }
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #string_id_map#
+// #generated# Last update: 2007-05-09 08:15:15 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 4: X="call";id=Id_call; break L;
+ case 5: X="apply";id=Id_apply; break L;
+ case 8: c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ break L;
+ case 11: X="constructor";id=Id_constructor; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ Id_apply = 4,
+ Id_call = 5,
+
+ MAX_PROTOTYPE_ID = 5;
+
+// #/string_id_map#
+
+ private Object prototypeProperty;
+ // For function object instances, attribute is PERMANENT; see ECMA 15.3.5.2
+ private int prototypePropertyAttributes = PERMANENT;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java
new file mode 100644
index 0000000..03e0fce
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Callable.java
@@ -0,0 +1,59 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * Generic notion of callable object that can execute some script-related code
+ * upon request with specified values for script scope and this objects.
+ */
+public interface Callable
+{
+ /**
+ * Perform the call.
+ *
+ * @param cx the current Context for this thread
+ * @param scope the scope to use to resolve properties.
+ * @param thisObj the JavaScript <code>this</code> object
+ * @param args the array of arguments
+ * @return the result of the call
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args);
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java
new file mode 100644
index 0000000..9047278
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassCache.java
@@ -0,0 +1,220 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Cache of generated classes and data structures to access Java runtime
+ * from JavaScript.
+ *
+ * @author Igor Bukanov
+ *
+ * @since Rhino 1.5 Release 5
+ */
+public class ClassCache
+{
+ private static final Object AKEY = new Object();
+ private volatile boolean cachingIsEnabled = true;
+ private HashMap<Class<?>,JavaMembers> classTable
+ = new HashMap<Class<?>,JavaMembers>();
+ private HashMap<Class<?>,JavaMembers> javaAdapterGeneratedClasses
+ = new HashMap<Class<?>,JavaMembers>();
+ private HashMap<JavaAdapter.JavaAdapterSignature,Class<?>> classAdapterCache
+ = new HashMap<JavaAdapter.JavaAdapterSignature,Class<?>>();
+ private HashMap<Class<?>,Object> interfaceAdapterCache;
+ private int generatedClassSerial;
+
+ /**
+ * Search for ClassCache object in the given scope.
+ * The method first calls
+ * {@link ScriptableObject#getTopLevelScope(Scriptable scope)}
+ * to get the top most scope and then tries to locate associated
+ * ClassCache object in the prototype chain of the top scope.
+ *
+ * @param scope scope to search for ClassCache object.
+ * @return previously associated ClassCache object or a new instance of
+ * ClassCache if no ClassCache object was found.
+ *
+ * @see #associate(ScriptableObject topScope)
+ */
+ public static ClassCache get(Scriptable scope)
+ {
+ ClassCache cache = (ClassCache)
+ ScriptableObject.getTopScopeValue(scope, AKEY);
+ if (cache == null) {
+ throw new RuntimeException("Can't find top level scope for " +
+ "ClassCache.get");
+ }
+ return cache;
+ }
+
+ /**
+ * Associate ClassCache object with the given top-level scope.
+ * The ClassCache object can only be associated with the given scope once.
+ *
+ * @param topScope scope to associate this ClassCache object with.
+ * @return true if no previous ClassCache objects were embedded into
+ * the scope and this ClassCache were successfully associated
+ * or false otherwise.
+ *
+ * @see #get(Scriptable scope)
+ */
+ public boolean associate(ScriptableObject topScope)
+ {
+ if (topScope.getParentScope() != null) {
+ // Can only associate cache with top level scope
+ throw new IllegalArgumentException();
+ }
+ if (this == topScope.associateValue(AKEY, this)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Empty caches of generated Java classes and Java reflection information.
+ */
+ public synchronized void clearCaches()
+ {
+ classTable.clear();
+ javaAdapterGeneratedClasses.clear();
+ classAdapterCache.clear();
+ interfaceAdapterCache = null;
+ }
+
+ /**
+ * Check if generated Java classes and Java reflection information
+ * is cached.
+ */
+ public final boolean isCachingEnabled()
+ {
+ return cachingIsEnabled;
+ }
+
+ /**
+ * Set whether to cache some values.
+ * <p>
+ * By default, the engine will cache the results of
+ * <tt>Class.getMethods()</tt> and similar calls.
+ * This can speed execution dramatically, but increases the memory
+ * footprint. Also, with caching enabled, references may be held to
+ * objects past the lifetime of any real usage.
+ * <p>
+ * If caching is enabled and this method is called with a
+ * <code>false</code> argument, the caches will be emptied.
+ * <p>
+ * Caching is enabled by default.
+ *
+ * @param enabled if true, caching is enabled
+ *
+ * @see #clearCaches()
+ */
+ public synchronized void setCachingEnabled(boolean enabled)
+ {
+ if (enabled == cachingIsEnabled)
+ return;
+ if (!enabled)
+ clearCaches();
+ cachingIsEnabled = enabled;
+ }
+
+ /**
+ * @return a map from classes to associated JavaMembers objects
+ */
+ Map<Class<?>,JavaMembers> getClassCacheMap() {
+ return classTable;
+ }
+
+ Map<JavaAdapter.JavaAdapterSignature,Class<?>> getInterfaceAdapterCacheMap()
+ {
+ return classAdapterCache;
+ }
+
+ /**
+ * @deprecated
+ * The method always returns false.
+ * @see #setInvokerOptimizationEnabled(boolean enabled)
+ */
+ public boolean isInvokerOptimizationEnabled()
+ {
+ return false;
+ }
+
+ /**
+ * @deprecated
+ * The method does nothing.
+ * Invoker optimization is no longer used by Rhino.
+ * On modern JDK like 1.4 or 1.5 the disadvantages of the optimization
+ * like increased memory usage or longer initialization time overweight
+ * small speed increase that can be gained using generated proxy class
+ * to replace reflection.
+ */
+ public synchronized void setInvokerOptimizationEnabled(boolean enabled)
+ {
+ }
+
+ /**
+ * Internal engine method to return serial number for generated classes
+ * to ensure name uniqueness.
+ */
+ public final synchronized int newClassSerialNumber()
+ {
+ return ++generatedClassSerial;
+ }
+
+ Object getInterfaceAdapter(Class<?> cl)
+ {
+ return interfaceAdapterCache == null
+ ? null
+ : interfaceAdapterCache.get(cl);
+ }
+
+ synchronized void cacheInterfaceAdapter(Class<?> cl, Object iadapter)
+ {
+ if (cachingIsEnabled) {
+ if (interfaceAdapterCache == null) {
+ interfaceAdapterCache = new HashMap<Class<?>,Object>();
+ }
+ interfaceAdapterCache.put(cl, iadapter);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java
new file mode 100644
index 0000000..d5f4cd6
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ClassShutter.java
@@ -0,0 +1,89 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+Embeddings that wish to filter Java classes that are visible to scripts
+through the LiveConnect, should implement this interface.
+
+@see Context#setClassShutter(ClassShutter)
+@since 1.5 Release 4
+@author Norris Boyd
+*/
+
+ public interface ClassShutter {
+
+ /**
+ * Return true iff the Java class with the given name should be exposed
+ * to scripts.
+ * <p>
+ * An embedding may filter which Java classes are exposed through
+ * LiveConnect to JavaScript scripts.
+ * <p>
+ * Due to the fact that there is no package reflection in Java,
+ * this method will also be called with package names. There
+ * is no way for Rhino to tell if "Packages.a.b" is a package name
+ * or a class that doesn't exist. What Rhino does is attempt
+ * to load each segment of "Packages.a.b.c": It first attempts to
+ * load class "a", then attempts to load class "a.b", then
+ * finally attempts to load class "a.b.c". On a Rhino installation
+ * without any ClassShutter set, and without any of the
+ * above classes, the expression "Packages.a.b.c" will result in
+ * a [JavaPackage a.b.c] and not an error.
+ * <p>
+ * With ClassShutter supplied, Rhino will first call
+ * visibleToScripts before attempting to look up the class name. If
+ * visibleToScripts returns false, the class name lookup is not
+ * performed and subsequent Rhino execution assumes the class is
+ * not present. So for "java.lang.System.out.println" the lookup
+ * of "java.lang.System" is skipped and thus Rhino assumes that
+ * "java.lang.System" doesn't exist. So then for "java.lang.System.out",
+ * Rhino attempts to load the class "java.lang.System.out" because
+ * it assumes that "java.lang.System" is a package name.
+ * <p>
+ * @param fullClassName the full name of the class (including the package
+ * name, with '.' as a delimiter). For example the
+ * standard string class is "java.lang.String"
+ * @return whether or not to reveal this class to scripts
+ */
+ public boolean visibleToScripts(String fullClassName);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java
new file mode 100644
index 0000000..645d098
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/CompilerEnvirons.java
@@ -0,0 +1,233 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ * Bob Jervis
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Hashtable;
+
+public class CompilerEnvirons
+{
+ public CompilerEnvirons()
+ {
+ errorReporter = DefaultErrorReporter.instance;
+ languageVersion = Context.VERSION_DEFAULT;
+ generateDebugInfo = true;
+ useDynamicScope = false;
+ reservedKeywordAsIdentifier = false;
+ allowMemberExprAsFunctionName = false;
+ xmlAvailable = true;
+ optimizationLevel = 0;
+ generatingSource = true;
+ strictMode = false;
+ warningAsError = false;
+ generateObserverCount = false;
+ }
+
+ public void initFromContext(Context cx)
+ {
+ setErrorReporter(cx.getErrorReporter());
+ this.languageVersion = cx.getLanguageVersion();
+ useDynamicScope = cx.compileFunctionsWithDynamicScopeFlag;
+ generateDebugInfo = (!cx.isGeneratingDebugChanged()
+ || cx.isGeneratingDebug());
+ reservedKeywordAsIdentifier
+ = cx.hasFeature(Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER);
+ allowMemberExprAsFunctionName
+ = cx.hasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME);
+ strictMode
+ = cx.hasFeature(Context.FEATURE_STRICT_MODE);
+ warningAsError = cx.hasFeature(Context.FEATURE_WARNING_AS_ERROR);
+ xmlAvailable
+ = cx.hasFeature(Context.FEATURE_E4X);
+
+ optimizationLevel = cx.getOptimizationLevel();
+
+ generatingSource = cx.isGeneratingSource();
+ activationNames = cx.activationNames;
+
+ // Observer code generation in compiled code :
+ generateObserverCount = cx.generateObserverCount;
+ }
+
+ public final ErrorReporter getErrorReporter()
+ {
+ return errorReporter;
+ }
+
+ public void setErrorReporter(ErrorReporter errorReporter)
+ {
+ if (errorReporter == null) throw new IllegalArgumentException();
+ this.errorReporter = errorReporter;
+ }
+
+ public final int getLanguageVersion()
+ {
+ return languageVersion;
+ }
+
+ public void setLanguageVersion(int languageVersion)
+ {
+ Context.checkLanguageVersion(languageVersion);
+ this.languageVersion = languageVersion;
+ }
+
+ public final boolean isGenerateDebugInfo()
+ {
+ return generateDebugInfo;
+ }
+
+ public void setGenerateDebugInfo(boolean flag)
+ {
+ this.generateDebugInfo = flag;
+ }
+
+ public final boolean isUseDynamicScope()
+ {
+ return useDynamicScope;
+ }
+
+ public final boolean isReservedKeywordAsIdentifier()
+ {
+ return reservedKeywordAsIdentifier;
+ }
+
+ public void setReservedKeywordAsIdentifier(boolean flag)
+ {
+ reservedKeywordAsIdentifier = flag;
+ }
+
+ public final boolean isAllowMemberExprAsFunctionName()
+ {
+ return allowMemberExprAsFunctionName;
+ }
+
+ public void setAllowMemberExprAsFunctionName(boolean flag)
+ {
+ allowMemberExprAsFunctionName = flag;
+ }
+
+ public final boolean isXmlAvailable()
+ {
+ return xmlAvailable;
+ }
+
+ public void setXmlAvailable(boolean flag)
+ {
+ xmlAvailable = flag;
+ }
+
+ public final int getOptimizationLevel()
+ {
+ return optimizationLevel;
+ }
+
+ public void setOptimizationLevel(int level)
+ {
+ Context.checkOptimizationLevel(level);
+ this.optimizationLevel = level;
+ }
+
+ public final boolean isGeneratingSource()
+ {
+ return generatingSource;
+ }
+
+ public final boolean isStrictMode()
+ {
+ return strictMode;
+ }
+
+ public final boolean reportWarningAsError()
+ {
+ return warningAsError;
+ }
+
+ /**
+ * Specify whether or not source information should be generated.
+ * <p>
+ * Without source information, evaluating the "toString" method
+ * on JavaScript functions produces only "[native code]" for
+ * the body of the function.
+ * Note that code generated without source is not fully ECMA
+ * conformant.
+ */
+ public void setGeneratingSource(boolean generatingSource)
+ {
+ this.generatingSource = generatingSource;
+ }
+
+ /**
+ * @return true iff code will be generated with callbacks to enable
+ * instruction thresholds
+ */
+ public boolean isGenerateObserverCount() {
+ return generateObserverCount;
+ }
+
+ /**
+ * Turn on or off generation of code with callbacks to
+ * track the count of executed instructions.
+ * Currently only affects JVM byte code generation: this slows down the
+ * generated code, but code generated without the callbacks will not
+ * be counted toward instruction thresholds. Rhino's interpretive
+ * mode does instruction counting without inserting callbacks, so
+ * there is no requirement to compile code differently.
+ * @param generateObserverCount if true, generated code will contain
+ * calls to accumulate an estimate of the instructions executed.
+ */
+ public void setGenerateObserverCount(boolean generateObserverCount) {
+ this.generateObserverCount = generateObserverCount;
+ }
+
+ private ErrorReporter errorReporter;
+
+ private int languageVersion;
+ private boolean generateDebugInfo;
+ private boolean useDynamicScope;
+ private boolean reservedKeywordAsIdentifier;
+ private boolean allowMemberExprAsFunctionName;
+ private boolean xmlAvailable;
+ private int optimizationLevel;
+ private boolean generatingSource;
+ private boolean strictMode;
+ private boolean warningAsError;
+ private boolean generateObserverCount;
+ Hashtable activationNames;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java
new file mode 100644
index 0000000..860db79
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ConstProperties.java
@@ -0,0 +1,109 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bob Jervis
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+public interface ConstProperties {
+ /**
+ * Sets a named const property in this object.
+ * <p>
+ * The property is specified by a string name
+ * as defined for <code>Scriptable.get</code>.
+ * <p>
+ * The possible values that may be passed in are as defined for
+ * <code>Scriptable.get</code>. A class that implements this method may choose
+ * to ignore calls to set certain properties, in which case those
+ * properties are effectively read-only.<p>
+ * For properties defined in a prototype chain,
+ * use <code>putProperty</code> in ScriptableObject. <p>
+ * Note that if a property <i>a</i> is defined in the prototype <i>p</i>
+ * of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
+ * <code>set</code> to be called on the prototype <i>p</i> with
+ * <i>o</i> as the <i>start</i> parameter.
+ * To preserve JavaScript semantics, it is the Scriptable
+ * object's responsibility to modify <i>o</i>. <p>
+ * This design allows properties to be defined in prototypes and implemented
+ * in terms of getters and setters of Java values without consuming slots
+ * in each instance.<p>
+ * <p>
+ * The values that may be set are limited to the following:
+ * <UL>
+ * <LI>java.lang.Boolean objects</LI>
+ * <LI>java.lang.String objects</LI>
+ * <LI>java.lang.Number objects</LI>
+ * <LI>org.mozilla.javascript.Scriptable objects</LI>
+ * <LI>null</LI>
+ * <LI>The value returned by Context.getUndefinedValue()</LI>
+ * </UL><p>
+ * Arbitrary Java objects may be wrapped in a Scriptable by first calling
+ * <code>Context.toObject</code>. This allows the property of a JavaScript
+ * object to contain an arbitrary Java object as a value.<p>
+ * Note that <code>has</code> will be called by the runtime first before
+ * <code>set</code> is called to determine in which object the
+ * property is defined.
+ * Note that this method is not expected to traverse the prototype chain,
+ * which is different from the ECMA [[Put]] operation.
+ * @param name the name of the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
+ * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object)
+ * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
+ */
+ public void putConst(String name, Scriptable start, Object value);
+
+ /**
+ * Reserves a definition spot for a const. This will set up a definition
+ * of the const property, but set its value to undefined. The semantics of
+ * the start parameter is the same as for putConst.
+ * @param name The name of the property.
+ * @param start The object whose property is being reserved.
+ */
+ public void defineConst(String name, Scriptable start);
+
+ /**
+ * Returns true if the named property is defined as a const on this object.
+ * @param name
+ * @return true if the named property is defined as a const, false
+ * otherwise.
+ */
+ public boolean isConst(String name);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java
new file mode 100644
index 0000000..0833883
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Context.java
@@ -0,0 +1,2526 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bob Jervis
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import org.mozilla.javascript.debug.DebuggableScript;
+import org.mozilla.javascript.debug.Debugger;
+import org.mozilla.javascript.xml.XMLLib;
+
+/**
+ * This class represents the runtime context of an executing script.
+ *
+ * Before executing a script, an instance of Context must be created
+ * and associated with the thread that will be executing the script.
+ * The Context will be used to store information about the executing
+ * of the script such as the call stack. Contexts are associated with
+ * the current thread using the {@link #call(ContextAction)}
+ * or {@link #enter()} methods.<p>
+ *
+ * Different forms of script execution are supported. Scripts may be
+ * evaluated from the source directly, or first compiled and then later
+ * executed. Interactive execution is also supported.<p>
+ *
+ * Some aspects of script execution, such as type conversions and
+ * object creation, may be accessed directly through methods of
+ * Context.
+ *
+ * @see Scriptable
+ * @author Norris Boyd
+ * @author Brendan Eich
+ */
+
+public class Context
+{
+ /**
+ * Language versions.
+ *
+ * All integral values are reserved for future version numbers.
+ */
+
+ /**
+ * The unknown version.
+ */
+ public static final int VERSION_UNKNOWN = -1;
+
+ /**
+ * The default version.
+ */
+ public static final int VERSION_DEFAULT = 0;
+
+ /**
+ * JavaScript 1.0
+ */
+ public static final int VERSION_1_0 = 100;
+
+ /**
+ * JavaScript 1.1
+ */
+ public static final int VERSION_1_1 = 110;
+
+ /**
+ * JavaScript 1.2
+ */
+ public static final int VERSION_1_2 = 120;
+
+ /**
+ * JavaScript 1.3
+ */
+ public static final int VERSION_1_3 = 130;
+
+ /**
+ * JavaScript 1.4
+ */
+ public static final int VERSION_1_4 = 140;
+
+ /**
+ * JavaScript 1.5
+ */
+ public static final int VERSION_1_5 = 150;
+
+ /**
+ * JavaScript 1.6
+ */
+ public static final int VERSION_1_6 = 160;
+
+ /**
+ * JavaScript 1.7
+ */
+ public static final int VERSION_1_7 = 170;
+
+ /**
+ * Controls behaviour of <tt>Date.prototype.getYear()</tt>.
+ * If <tt>hasFeature(FEATURE_NON_ECMA_GET_YEAR)</tt> returns true,
+ * Date.prototype.getYear subtructs 1900 only if 1900 <= date < 2000.
+ * The default behavior of {@link #hasFeature(int)} is always to subtruct
+ * 1900 as rquired by ECMAScript B.2.4.
+ */
+ public static final int FEATURE_NON_ECMA_GET_YEAR = 1;
+
+ /**
+ * Control if member expression as function name extension is available.
+ * If <tt>hasFeature(FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)</tt> returns
+ * true, allow <tt>function memberExpression(args) { body }</tt> to be
+ * syntax sugar for <tt>memberExpression = function(args) { body }</tt>,
+ * when memberExpression is not a simple identifier.
+ * See ECMAScript-262, section 11.2 for definition of memberExpression.
+ * By default {@link #hasFeature(int)} returns false.
+ */
+ public static final int FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME = 2;
+
+ /**
+ * Control if reserved keywords are treated as identifiers.
+ * If <tt>hasFeature(RESERVED_KEYWORD_AS_IDENTIFIER)</tt> returns true,
+ * treat future reserved keyword (see Ecma-262, section 7.5.3) as ordinary
+ * identifiers but warn about this usage.
+ *
+ * By default {@link #hasFeature(int)} returns false.
+ */
+ public static final int FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER = 3;
+
+ /**
+ * Control if <tt>toString()</tt> should returns the same result
+ * as <tt>toSource()</tt> when applied to objects and arrays.
+ * If <tt>hasFeature(FEATURE_TO_STRING_AS_SOURCE)</tt> returns true,
+ * calling <tt>toString()</tt> on JS objects gives the same result as
+ * calling <tt>toSource()</tt>. That is it returns JS source with code
+ * to create an object with all enumeratable fields of the original object
+ * instead of printing <tt>[object <i>result of
+ * {@link Scriptable#getClassName()}</i>]</tt>.
+ * <p>
+ * By default {@link #hasFeature(int)} returns true only if
+ * the current JS version is set to {@link #VERSION_1_2}.
+ */
+ public static final int FEATURE_TO_STRING_AS_SOURCE = 4;
+
+ /**
+ * Control if properties <tt>__proto__</tt> and <tt>__parent__</tt>
+ * are treated specially.
+ * If <tt>hasFeature(FEATURE_PARENT_PROTO_PROPERTIES)</tt> returns true,
+ * treat <tt>__parent__</tt> and <tt>__proto__</tt> as special properties.
+ * <p>
+ * The properties allow to query and set scope and prototype chains for the
+ * objects. The special meaning of the properties is available
+ * only when they are used as the right hand side of the dot operator.
+ * For example, while <tt>x.__proto__ = y</tt> changes the prototype
+ * chain of the object <tt>x</tt> to point to <tt>y</tt>,
+ * <tt>x["__proto__"] = y</tt> simply assigns a new value to the property
+ * <tt>__proto__</tt> in <tt>x</tt> even when the feature is on.
+ *
+ * By default {@link #hasFeature(int)} returns true.
+ */
+ public static final int FEATURE_PARENT_PROTO_PROPERTIES = 5;
+
+ /**
+ * @deprecated In previous releases, this name was given to
+ * FEATURE_PARENT_PROTO_PROPERTIES.
+ */
+ public static final int FEATURE_PARENT_PROTO_PROPRTIES = 5;
+
+ /**
+ * Control if support for E4X(ECMAScript for XML) extension is available.
+ * If hasFeature(FEATURE_E4X) returns true, the XML syntax is available.
+ * <p>
+ * By default {@link #hasFeature(int)} returns true if
+ * the current JS version is set to {@link #VERSION_DEFAULT}
+ * or is at least {@link #VERSION_1_6}.
+ * @since 1.6 Release 1
+ */
+ public static final int FEATURE_E4X = 6;
+
+ /**
+ * Control if dynamic scope should be used for name access.
+ * If hasFeature(FEATURE_DYNAMIC_SCOPE) returns true, then the name lookup
+ * during name resolution will use the top scope of the script or function
+ * which is at the top of JS execution stack instead of the top scope of the
+ * script or function from the current stack frame if the top scope of
+ * the top stack frame contains the top scope of the current stack frame
+ * on its prototype chain.
+ * <p>
+ * This is useful to define shared scope containing functions that can
+ * be called from scripts and functions using private scopes.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.6 Release 1
+ */
+ public static final int FEATURE_DYNAMIC_SCOPE = 7;
+
+ /**
+ * Control if strict variable mode is enabled.
+ * When the feature is on Rhino reports runtime errors if assignment
+ * to a global variable that does not exist is executed. When the feature
+ * is off such assignments creates new variable in the global scope as
+ * required by ECMA 262.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.6 Release 1
+ */
+ public static final int FEATURE_STRICT_VARS = 8;
+
+ /**
+ * Control if strict eval mode is enabled.
+ * When the feature is on Rhino reports runtime errors if non-string
+ * argument is passed to the eval function. When the feature is off
+ * eval simply return non-string argument as is without performing any
+ * evaluation as required by ECMA 262.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.6 Release 1
+ */
+ public static final int FEATURE_STRICT_EVAL = 9;
+
+ /**
+ * When the feature is on Rhino will add a "fileName" and "lineNumber"
+ * properties to Error objects automatically. When the feature is off, you
+ * have to explicitly pass them as the second and third argument to the
+ * Error constructor. Note that neither behaviour is fully ECMA 262
+ * compliant (as 262 doesn't specify a three-arg constructor), but keeping
+ * the feature off results in Error objects that don't have
+ * additional non-ECMA properties when constructed using the ECMA-defined
+ * single-arg constructor and is thus desirable if a stricter ECMA
+ * compliance is desired, specifically adherence to the point 15.11.5. of
+ * the standard.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.6 Release 6
+ */
+ public static final int FEATURE_LOCATION_INFORMATION_IN_ERROR = 10;
+
+ /**
+ * Controls whether JS 1.5 'strict mode' is enabled.
+ * When the feature is on, Rhino reports more than a dozen different
+ * warnings. When the feature is off, these warnings are not generated.
+ * FEATURE_STRICT_MODE implies FEATURE_STRICT_VARS and FEATURE_STRICT_EVAL.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.6 Release 6
+ */
+ public static final int FEATURE_STRICT_MODE = 11;
+
+ /**
+ * Controls whether a warning should be treated as an error.
+ * @since 1.6 Release 6
+ */
+ public static final int FEATURE_WARNING_AS_ERROR = 12;
+
+ /**
+ * Enables enhanced access to Java.
+ * Specifically, controls whether private and protected members can be
+ * accessed, and whether scripts can catch all Java exceptions.
+ * <p>
+ * Note that this feature should only be enabled for trusted scripts.
+ * <p>
+ * By default {@link #hasFeature(int)} returns false.
+ * @since 1.7 Release 1
+ */
+ public static final int FEATURE_ENHANCED_JAVA_ACCESS = 13;
+
+
+ public static final String languageVersionProperty = "language version";
+ public static final String errorReporterProperty = "error reporter";
+
+ /**
+ * Convenient value to use as zero-length array of objects.
+ */
+ public static final Object[] emptyArgs = ScriptRuntime.emptyArgs;
+
+ /**
+ * Create a new Context.
+ *
+ * Note that the Context must be associated with a thread before
+ * it can be used to execute a script.
+ * @deprecated use {@link ContextFactory#enter()} or
+ * {@link ContextFactory#call(ContextAction)} instead.
+ */
+ public Context()
+ {
+ this(ContextFactory.getGlobal());
+ }
+
+ Context(ContextFactory factory)
+ {
+ assert factory != null;
+ this.factory = factory;
+ setLanguageVersion(VERSION_DEFAULT);
+ optimizationLevel = codegenClass != null ? 0 : -1;
+ maximumInterpreterStackDepth = Integer.MAX_VALUE;
+ }
+
+ /**
+ * Get the current Context.
+ *
+ * The current Context is per-thread; this method looks up
+ * the Context associated with the current thread. <p>
+ *
+ * @return the Context associated with the current thread, or
+ * null if no context is associated with the current
+ * thread.
+ * @see ContextFactory#enterContext()
+ * @see ContextFactory#call(ContextAction)
+ */
+ public static Context getCurrentContext()
+ {
+ Object helper = VMBridge.instance.getThreadContextHelper();
+ return VMBridge.instance.getContext(helper);
+ }
+
+ /**
+ * Same as calling {@link ContextFactory#enterContext()} on the global
+ * ContextFactory instance.
+ * @deprecated use {@link ContextFactory#enter()} or
+ * {@link ContextFactory#call(ContextAction)} instead as this method relies
+ * on usage of a static singleton "global" ContextFactory.
+ * @return a Context associated with the current thread
+ * @see #getCurrentContext()
+ * @see #exit()
+ * @see #call(ContextAction)
+ */
+ public static Context enter()
+ {
+ return enter(null);
+ }
+
+ /**
+ * Get a Context associated with the current thread, using
+ * the given Context if need be.
+ * <p>
+ * The same as <code>enter()</code> except that <code>cx</code>
+ * is associated with the current thread and returned if
+ * the current thread has no associated context and <code>cx</code>
+ * is not associated with any other thread.
+ * @param cx a Context to associate with the thread if possible
+ * @return a Context associated with the current thread
+ * @deprecated use {@link ContextFactory#enterContext(Context)} instead as
+ * this method relies on usage of a static singleton "global" ContextFactory.
+ * @see ContextFactory#enterContext(Context)
+ * @see ContextFactory#call(ContextAction)
+ */
+ public static Context enter(Context cx)
+ {
+ return enter(cx, ContextFactory.getGlobal());
+ }
+
+ static final Context enter(Context cx, ContextFactory factory)
+ {
+ Object helper = VMBridge.instance.getThreadContextHelper();
+ Context old = VMBridge.instance.getContext(helper);
+ if (old != null) {
+ cx = old;
+ } else {
+ if (cx == null) {
+ cx = factory.makeContext();
+ if (cx.enterCount != 0) {
+ throw new IllegalStateException("factory.makeContext() returned Context instance already associated with some thread");
+ }
+ factory.onContextCreated(cx);
+ if (factory.isSealed() && !cx.isSealed()) {
+ cx.seal(null);
+ }
+ } else {
+ if (cx.enterCount != 0) {
+ throw new IllegalStateException("can not use Context instance already associated with some thread");
+ }
+ }
+ VMBridge.instance.setContext(helper, cx);
+ }
+ ++cx.enterCount;
+ return cx;
+ }
+
+ /**
+ * Exit a block of code requiring a Context.
+ *
+ * Calling <code>exit()</code> will remove the association between
+ * the current thread and a Context if the prior call to
+ * {@link ContextFactory#enterContext()} on this thread newly associated a
+ * Context with this thread. Once the current thread no longer has an
+ * associated Context, it cannot be used to execute JavaScript until it is
+ * again associated with a Context.
+ * @see ContextFactory#enterContext()
+ */
+ public static void exit()
+ {
+ Object helper = VMBridge.instance.getThreadContextHelper();
+ Context cx = VMBridge.instance.getContext(helper);
+ if (cx == null) {
+ throw new IllegalStateException(
+ "Calling Context.exit without previous Context.enter");
+ }
+ if (cx.enterCount < 1) Kit.codeBug();
+ if (--cx.enterCount == 0) {
+ VMBridge.instance.setContext(helper, null);
+ cx.factory.onContextReleased(cx);
+ }
+ }
+
+ /**
+ * Call {@link ContextAction#run(Context cx)}
+ * using the Context instance associated with the current thread.
+ * If no Context is associated with the thread, then
+ * <tt>ContextFactory.getGlobal().makeContext()</tt> will be called to
+ * construct new Context instance. The instance will be temporary
+ * associated with the thread during call to
+ * {@link ContextAction#run(Context)}.
+ * @deprecated use {@link ContextFactory#call(ContextAction)} instead as
+ * this method relies on usage of a static singleton "global"
+ * ContextFactory.
+ * @return The result of {@link ContextAction#run(Context)}.
+ */
+ public static Object call(ContextAction action)
+ {
+ return call(ContextFactory.getGlobal(), action);
+ }
+
+ /**
+ * Call {@link
+ * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,
+ * Object[] args)}
+ * using the Context instance associated with the current thread.
+ * If no Context is associated with the thread, then
+ * {@link ContextFactory#makeContext()} will be called to construct
+ * new Context instance. The instance will be temporary associated
+ * with the thread during call to {@link ContextAction#run(Context)}.
+ * <p>
+ * It is allowed but not advisable to use null for <tt>factory</tt>
+ * argument in which case the global static singleton ContextFactory
+ * instance will be used to create new context instances.
+ * @see ContextFactory#call(ContextAction)
+ */
+ public static Object call(ContextFactory factory, final Callable callable,
+ final Scriptable scope, final Scriptable thisObj,
+ final Object[] args)
+ {
+ if(factory == null) {
+ factory = ContextFactory.getGlobal();
+ }
+ return call(factory, new ContextAction() {
+ public Object run(Context cx) {
+ return callable.call(cx, scope, thisObj, args);
+ }
+ });
+ }
+
+ /**
+ * The method implements {@links ContextFactory#call(ContextAction)} logic.
+ */
+ static Object call(ContextFactory factory, ContextAction action) {
+ Context cx = enter(null, factory);
+ try {
+ return action.run(cx);
+ }
+ finally {
+ exit();
+ }
+ }
+
+ /**
+ * @deprecated
+ * @see ContextFactory#addListener(ContextFactory.Listener)
+ * @see ContextFactory#getGlobal()
+ */
+ public static void addContextListener(ContextListener listener)
+ {
+ // Special workaround for the debugger
+ String DBG = "org.mozilla.javascript.tools.debugger.Main";
+ if (DBG.equals(listener.getClass().getName())) {
+ Class cl = listener.getClass();
+ Class factoryClass = Kit.classOrNull(
+ "org.mozilla.javascript.ContextFactory");
+ Class[] sig = { factoryClass };
+ Object[] args = { ContextFactory.getGlobal() };
+ try {
+ Method m = cl.getMethod("attachTo", sig);
+ m.invoke(listener, args);
+ } catch (Exception ex) {
+ RuntimeException rex = new RuntimeException();
+ Kit.initCause(rex, ex);
+ throw rex;
+ }
+ return;
+ }
+
+ ContextFactory.getGlobal().addListener(listener);
+ }
+
+ /**
+ * @deprecated
+ * @see ContextFactory#removeListener(ContextFactory.Listener)
+ * @see ContextFactory#getGlobal()
+ */
+ public static void removeContextListener(ContextListener listener)
+ {
+ ContextFactory.getGlobal().addListener(listener);
+ }
+
+ /**
+ * Return {@link ContextFactory} instance used to create this Context.
+ */
+ public final ContextFactory getFactory()
+ {
+ return factory;
+ }
+
+ /**
+ * Checks if this is a sealed Context. A sealed Context instance does not
+ * allow to modify any of its properties and will throw an exception
+ * on any such attempt.
+ * @see #seal(Object sealKey)
+ */
+ public final boolean isSealed()
+ {
+ return sealed;
+ }
+
+ /**
+ * Seal this Context object so any attempt to modify any of its properties
+ * including calling {@link #enter()} and {@link #exit()} methods will
+ * throw an exception.
+ * <p>
+ * If <tt>sealKey</tt> is not null, calling
+ * {@link #unseal(Object sealKey)} with the same key unseals
+ * the object. If <tt>sealKey</tt> is null, unsealing is no longer possible.
+ *
+ * @see #isSealed()
+ * @see #unseal(Object)
+ */
+ public final void seal(Object sealKey)
+ {
+ if (sealed) onSealedMutation();
+ sealed = true;
+ this.sealKey = sealKey;
+ }
+
+ /**
+ * Unseal previously sealed Context object.
+ * The <tt>sealKey</tt> argument should not be null and should match
+ * <tt>sealKey</tt> suplied with the last call to
+ * {@link #seal(Object)} or an exception will be thrown.
+ *
+ * @see #isSealed()
+ * @see #seal(Object sealKey)
+ */
+ public final void unseal(Object sealKey)
+ {
+ if (sealKey == null) throw new IllegalArgumentException();
+ if (this.sealKey != sealKey) throw new IllegalArgumentException();
+ if (!sealed) throw new IllegalStateException();
+ sealed = false;
+ this.sealKey = null;
+ }
+
+ static void onSealedMutation()
+ {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * Get the current language version.
+ * <p>
+ * The language version number affects JavaScript semantics as detailed
+ * in the overview documentation.
+ *
+ * @return an integer that is one of VERSION_1_0, VERSION_1_1, etc.
+ */
+ public final int getLanguageVersion()
+ {
+ return version;
+ }
+
+ /**
+ * Set the language version.
+ *
+ * <p>
+ * Setting the language version will affect functions and scripts compiled
+ * subsequently. See the overview documentation for version-specific
+ * behavior.
+ *
+ * @param version the version as specified by VERSION_1_0, VERSION_1_1, etc.
+ */
+ public void setLanguageVersion(int version)
+ {
+ if (sealed) onSealedMutation();
+ checkLanguageVersion(version);
+ Object listeners = propertyListeners;
+ if (listeners != null && version != this.version) {
+ firePropertyChangeImpl(listeners, languageVersionProperty,
+ new Integer(this.version),
+ new Integer(version));
+ }
+ this.version = version;
+ }
+
+ public static boolean isValidLanguageVersion(int version)
+ {
+ switch (version) {
+ case VERSION_DEFAULT:
+ case VERSION_1_0:
+ case VERSION_1_1:
+ case VERSION_1_2:
+ case VERSION_1_3:
+ case VERSION_1_4:
+ case VERSION_1_5:
+ case VERSION_1_6:
+ case VERSION_1_7:
+ return true;
+ }
+ return false;
+ }
+
+ public static void checkLanguageVersion(int version)
+ {
+ if (isValidLanguageVersion(version)) {
+ return;
+ }
+ throw new IllegalArgumentException("Bad language version: "+version);
+ }
+
+ /**
+ * Get the implementation version.
+ *
+ * <p>
+ * The implementation version is of the form
+ * <pre>
+ * "<i>name langVer</i> <code>release</code> <i>relNum date</i>"
+ * </pre>
+ * where <i>name</i> is the name of the product, <i>langVer</i> is
+ * the language version, <i>relNum</i> is the release number, and
+ * <i>date</i> is the release date for that specific
+ * release in the form "yyyy mm dd".
+ *
+ * @return a string that encodes the product, language version, release
+ * number, and date.
+ */
+ public final String getImplementationVersion()
+ {
+ // XXX Probably it would be better to embed this directly into source
+ // with special build preprocessing but that would require some ant
+ // tweaking and then replacing token in resource files was simpler
+ if (implementationVersion == null) {
+ implementationVersion
+ = ScriptRuntime.getMessage0("implementation.version");
+ }
+ return implementationVersion;
+ }
+
+ /**
+ * Get the current error reporter.
+ *
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public final ErrorReporter getErrorReporter()
+ {
+ if (errorReporter == null) {
+ return DefaultErrorReporter.instance;
+ }
+ return errorReporter;
+ }
+
+ /**
+ * Change the current error reporter.
+ *
+ * @return the previous error reporter
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public final ErrorReporter setErrorReporter(ErrorReporter reporter)
+ {
+ if (sealed) onSealedMutation();
+ if (reporter == null) throw new IllegalArgumentException();
+ ErrorReporter old = getErrorReporter();
+ if (reporter == old) {
+ return old;
+ }
+ Object listeners = propertyListeners;
+ if (listeners != null) {
+ firePropertyChangeImpl(listeners, errorReporterProperty,
+ old, reporter);
+ }
+ this.errorReporter = reporter;
+ return old;
+ }
+
+ /**
+ * Get the current locale. Returns the default locale if none has
+ * been set.
+ *
+ * @see java.util.Locale
+ */
+
+ public final Locale getLocale()
+ {
+ if (locale == null)
+ locale = Locale.getDefault();
+ return locale;
+ }
+
+ /**
+ * Set the current locale.
+ *
+ * @see java.util.Locale
+ */
+ public final Locale setLocale(Locale loc)
+ {
+ if (sealed) onSealedMutation();
+ Locale result = locale;
+ locale = loc;
+ return result;
+ }
+
+ /**
+ * Register an object to receive notifications when a bound property
+ * has changed
+ * @see java.beans.PropertyChangeEvent
+ * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
+ * @param l the listener
+ */
+ public final void addPropertyChangeListener(PropertyChangeListener l)
+ {
+ if (sealed) onSealedMutation();
+ propertyListeners = Kit.addListener(propertyListeners, l);
+ }
+
+ /**
+ * Remove an object from the list of objects registered to receive
+ * notification of changes to a bounded property
+ * @see java.beans.PropertyChangeEvent
+ * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
+ * @param l the listener
+ */
+ public final void removePropertyChangeListener(PropertyChangeListener l)
+ {
+ if (sealed) onSealedMutation();
+ propertyListeners = Kit.removeListener(propertyListeners, l);
+ }
+
+ /**
+ * Notify any registered listeners that a bounded property has changed
+ * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
+ * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
+ * @see java.beans.PropertyChangeListener
+ * @see java.beans.PropertyChangeEvent
+ * @param property the bound property
+ * @param oldValue the old value
+ * @param newValue the new value
+ */
+ final void firePropertyChange(String property, Object oldValue,
+ Object newValue)
+ {
+ Object listeners = propertyListeners;
+ if (listeners != null) {
+ firePropertyChangeImpl(listeners, property, oldValue, newValue);
+ }
+ }
+
+ private void firePropertyChangeImpl(Object listeners, String property,
+ Object oldValue, Object newValue)
+ {
+ for (int i = 0; ; ++i) {
+ Object l = Kit.getListener(listeners, i);
+ if (l == null)
+ break;
+ if (l instanceof PropertyChangeListener) {
+ PropertyChangeListener pcl = (PropertyChangeListener)l;
+ pcl.propertyChange(new PropertyChangeEvent(
+ this, property, oldValue, newValue));
+ }
+ }
+ }
+
+ /**
+ * Report a warning using the error reporter for the current thread.
+ *
+ * @param message the warning message to report
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static void reportWarning(String message, String sourceName,
+ int lineno, String lineSource,
+ int lineOffset)
+ {
+ Context cx = Context.getContext();
+ if (cx.hasFeature(FEATURE_WARNING_AS_ERROR))
+ reportError(message, sourceName, lineno, lineSource, lineOffset);
+ else
+ cx.getErrorReporter().warning(message, sourceName, lineno,
+ lineSource, lineOffset);
+ }
+
+ /**
+ * Report a warning using the error reporter for the current thread.
+ *
+ * @param message the warning message to report
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static void reportWarning(String message)
+ {
+ int[] linep = { 0 };
+ String filename = getSourcePositionFromStack(linep);
+ Context.reportWarning(message, filename, linep[0], null, 0);
+ }
+
+ public static void reportWarning(String message, Throwable t)
+ {
+ int[] linep = { 0 };
+ String filename = getSourcePositionFromStack(linep);
+ Writer sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println(message);
+ t.printStackTrace(pw);
+ pw.flush();
+ Context.reportWarning(sw.toString(), filename, linep[0], null, 0);
+ }
+
+ /**
+ * Report an error using the error reporter for the current thread.
+ *
+ * @param message the error message to report
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static void reportError(String message, String sourceName,
+ int lineno, String lineSource,
+ int lineOffset)
+ {
+ Context cx = getCurrentContext();
+ if (cx != null) {
+ cx.getErrorReporter().error(message, sourceName, lineno,
+ lineSource, lineOffset);
+ } else {
+ throw new EvaluatorException(message, sourceName, lineno,
+ lineSource, lineOffset);
+ }
+ }
+
+ /**
+ * Report an error using the error reporter for the current thread.
+ *
+ * @param message the error message to report
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static void reportError(String message)
+ {
+ int[] linep = { 0 };
+ String filename = getSourcePositionFromStack(linep);
+ Context.reportError(message, filename, linep[0], null, 0);
+ }
+
+ /**
+ * Report a runtime error using the error reporter for the current thread.
+ *
+ * @param message the error message to report
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ * @return a runtime exception that will be thrown to terminate the
+ * execution of the script
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static EvaluatorException reportRuntimeError(String message,
+ String sourceName,
+ int lineno,
+ String lineSource,
+ int lineOffset)
+ {
+ Context cx = getCurrentContext();
+ if (cx != null) {
+ return cx.getErrorReporter().
+ runtimeError(message, sourceName, lineno,
+ lineSource, lineOffset);
+ } else {
+ throw new EvaluatorException(message, sourceName, lineno,
+ lineSource, lineOffset);
+ }
+ }
+
+ static EvaluatorException reportRuntimeError0(String messageId)
+ {
+ String msg = ScriptRuntime.getMessage0(messageId);
+ return reportRuntimeError(msg);
+ }
+
+ static EvaluatorException reportRuntimeError1(String messageId,
+ Object arg1)
+ {
+ String msg = ScriptRuntime.getMessage1(messageId, arg1);
+ return reportRuntimeError(msg);
+ }
+
+ static EvaluatorException reportRuntimeError2(String messageId,
+ Object arg1, Object arg2)
+ {
+ String msg = ScriptRuntime.getMessage2(messageId, arg1, arg2);
+ return reportRuntimeError(msg);
+ }
+
+ static EvaluatorException reportRuntimeError3(String messageId,
+ Object arg1, Object arg2,
+ Object arg3)
+ {
+ String msg = ScriptRuntime.getMessage3(messageId, arg1, arg2, arg3);
+ return reportRuntimeError(msg);
+ }
+
+ static EvaluatorException reportRuntimeError4(String messageId,
+ Object arg1, Object arg2,
+ Object arg3, Object arg4)
+ {
+ String msg
+ = ScriptRuntime.getMessage4(messageId, arg1, arg2, arg3, arg4);
+ return reportRuntimeError(msg);
+ }
+
+ /**
+ * Report a runtime error using the error reporter for the current thread.
+ *
+ * @param message the error message to report
+ * @see org.mozilla.javascript.ErrorReporter
+ */
+ public static EvaluatorException reportRuntimeError(String message)
+ {
+ int[] linep = { 0 };
+ String filename = getSourcePositionFromStack(linep);
+ return Context.reportRuntimeError(message, filename, linep[0], null, 0);
+ }
+
+ /**
+ * Initialize the standard objects.
+ *
+ * Creates instances of the standard objects and their constructors
+ * (Object, String, Number, Date, etc.), setting up 'scope' to act
+ * as a global object as in ECMA 15.1.<p>
+ *
+ * This method must be called to initialize a scope before scripts
+ * can be evaluated in that scope.<p>
+ *
+ * This method does not affect the Context it is called upon.
+ *
+ * @return the initialized scope
+ */
+ public final ScriptableObject initStandardObjects()
+ {
+ return initStandardObjects(null, false);
+ }
+
+ /**
+ * Initialize the standard objects.
+ *
+ * Creates instances of the standard objects and their constructors
+ * (Object, String, Number, Date, etc.), setting up 'scope' to act
+ * as a global object as in ECMA 15.1.<p>
+ *
+ * This method must be called to initialize a scope before scripts
+ * can be evaluated in that scope.<p>
+ *
+ * This method does not affect the Context it is called upon.
+ *
+ * @param scope the scope to initialize, or null, in which case a new
+ * object will be created to serve as the scope
+ * @return the initialized scope. The method returns the value of the scope
+ * argument if it is not null or newly allocated scope object which
+ * is an instance {@link ScriptableObject}.
+ */
+ public final Scriptable initStandardObjects(ScriptableObject scope)
+ {
+ return initStandardObjects(scope, false);
+ }
+
+ /**
+ * Initialize the standard objects.
+ *
+ * Creates instances of the standard objects and their constructors
+ * (Object, String, Number, Date, etc.), setting up 'scope' to act
+ * as a global object as in ECMA 15.1.<p>
+ *
+ * This method must be called to initialize a scope before scripts
+ * can be evaluated in that scope.<p>
+ *
+ * This method does not affect the Context it is called upon.<p>
+ *
+ * This form of the method also allows for creating "sealed" standard
+ * objects. An object that is sealed cannot have properties added, changed,
+ * or removed. This is useful to create a "superglobal" that can be shared
+ * among several top-level objects. Note that sealing is not allowed in
+ * the current ECMA/ISO language specification, but is likely for
+ * the next version.
+ *
+ * @param scope the scope to initialize, or null, in which case a new
+ * object will be created to serve as the scope
+ * @param sealed whether or not to create sealed standard objects that
+ * cannot be modified.
+ * @return the initialized scope. The method returns the value of the scope
+ * argument if it is not null or newly allocated scope object.
+ * @since 1.4R3
+ */
+ public ScriptableObject initStandardObjects(ScriptableObject scope,
+ boolean sealed)
+ {
+ return ScriptRuntime.initStandardObjects(this, scope, sealed);
+ }
+
+ /**
+ * Get the singleton object that represents the JavaScript Undefined value.
+ */
+ public static Object getUndefinedValue()
+ {
+ return Undefined.instance;
+ }
+
+ /**
+ * Evaluate a JavaScript source string.
+ *
+ * The provided source name and line number are used for error messages
+ * and for producing debug information.
+ *
+ * @param scope the scope to execute in
+ * @param source the JavaScript source
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param securityDomain an arbitrary object that specifies security
+ * information about the origin or owner of the script. For
+ * implementations that don't care about security, this value
+ * may be null.
+ * @return the result of evaluating the string
+ * @see org.mozilla.javascript.SecurityController
+ */
+ public final Object evaluateString(Scriptable scope, String source,
+ String sourceName, int lineno,
+ Object securityDomain)
+ {
+ Script script = compileString(source, sourceName, lineno,
+ securityDomain);
+ if (script != null) {
+ return script.exec(this, scope);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Evaluate a reader as JavaScript source.
+ *
+ * All characters of the reader are consumed.
+ *
+ * @param scope the scope to execute in
+ * @param in the Reader to get JavaScript source from
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param securityDomain an arbitrary object that specifies security
+ * information about the origin or owner of the script. For
+ * implementations that don't care about security, this value
+ * may be null.
+ * @return the result of evaluating the source
+ *
+ * @exception IOException if an IOException was generated by the Reader
+ */
+ public final Object evaluateReader(Scriptable scope, Reader in,
+ String sourceName, int lineno,
+ Object securityDomain)
+ throws IOException
+ {
+ Script script = compileReader(scope, in, sourceName, lineno,
+ securityDomain);
+ if (script != null) {
+ return script.exec(this, scope);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Check whether a string is ready to be compiled.
+ * <p>
+ * stringIsCompilableUnit is intended to support interactive compilation of
+ * javascript. If compiling the string would result in an error
+ * that might be fixed by appending more source, this method
+ * returns false. In every other case, it returns true.
+ * <p>
+ * Interactive shells may accumulate source lines, using this
+ * method after each new line is appended to check whether the
+ * statement being entered is complete.
+ *
+ * @param source the source buffer to check
+ * @return whether the source is ready for compilation
+ * @since 1.4 Release 2
+ */
+ public final boolean stringIsCompilableUnit(String source)
+ {
+ boolean errorseen = false;
+ CompilerEnvirons compilerEnv = new CompilerEnvirons();
+ compilerEnv.initFromContext(this);
+ // no source name or source text manager, because we're just
+ // going to throw away the result.
+ compilerEnv.setGeneratingSource(false);
+ /*APPJET*/
+ Parser p = InformativeParser.makeParser(compilerEnv,
+ DefaultErrorReporter.instance);
+ try {
+ p.parse(source, null, 1);
+ } catch (EvaluatorException ee) {
+ errorseen = true;
+ }
+ // Return false only if an error occurred as a result of reading past
+ // the end of the file, i.e. if the source could be fixed by
+ // appending more source.
+ if (errorseen && p.eof())
+ return false;
+ else
+ return true;
+ }
+
+ /**
+ * @deprecated
+ * @see #compileReader(Reader in, String sourceName, int lineno,
+ * Object securityDomain)
+ */
+ public final Script compileReader(Scriptable scope, Reader in,
+ String sourceName, int lineno,
+ Object securityDomain)
+ throws IOException
+ {
+ return compileReader(in, sourceName, lineno, securityDomain);
+ }
+
+ /**
+ * Compiles the source in the given reader.
+ * <p>
+ * Returns a script that may later be executed.
+ * Will consume all the source in the reader.
+ *
+ * @param in the input reader
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number for reporting errors
+ * @param securityDomain an arbitrary object that specifies security
+ * information about the origin or owner of the script. For
+ * implementations that don't care about security, this value
+ * may be null.
+ * @return a script that may later be executed
+ * @exception IOException if an IOException was generated by the Reader
+ * @see org.mozilla.javascript.Script
+ */
+ public final Script compileReader(Reader in, String sourceName,
+ int lineno, Object securityDomain)
+ throws IOException
+ {
+ if (lineno < 0) {
+ // For compatibility IllegalArgumentException can not be thrown here
+ lineno = 0;
+ }
+ return (Script) compileImpl(null, in, null, sourceName, lineno,
+ securityDomain, false, null, null);
+ }
+
+ /**
+ * Compiles the source in the given string.
+ * <p>
+ * Returns a script that may later be executed.
+ *
+ * @param source the source string
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number for reporting errors
+ * @param securityDomain an arbitrary object that specifies security
+ * information about the origin or owner of the script. For
+ * implementations that don't care about security, this value
+ * may be null.
+ * @return a script that may later be executed
+ * @see org.mozilla.javascript.Script
+ */
+ public final Script compileString(String source,
+ String sourceName, int lineno,
+ Object securityDomain)
+ {
+ if (lineno < 0) {
+ // For compatibility IllegalArgumentException can not be thrown here
+ lineno = 0;
+ }
+ return compileString(source, null, null, sourceName, lineno,
+ securityDomain);
+ }
+
+ final Script compileString(String source,
+ Evaluator compiler,
+ ErrorReporter compilationErrorReporter,
+ String sourceName, int lineno,
+ Object securityDomain)
+ {
+ try {
+ return (Script) compileImpl(null, null, source, sourceName, lineno,
+ securityDomain, false,
+ compiler, compilationErrorReporter);
+ } catch (IOException ex) {
+ // Should not happen when dealing with source as string
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Compile a JavaScript function.
+ * <p>
+ * The function source must be a function definition as defined by
+ * ECMA (e.g., "function f(a) { return a; }").
+ *
+ * @param scope the scope to compile relative to
+ * @param source the function definition source
+ * @param sourceName a string describing the source, such as a filename
+ * @param lineno the starting line number
+ * @param securityDomain an arbitrary object that specifies security
+ * information about the origin or owner of the script. For
+ * implementations that don't care about security, this value
+ * may be null.
+ * @return a Function that may later be called
+ * @see org.mozilla.javascript.Function
+ */
+ public final Function compileFunction(Scriptable scope, String source,
+ String sourceName, int lineno,
+ Object securityDomain)
+ {
+ return compileFunction(scope, source, null, null, sourceName, lineno,
+ securityDomain);
+ }
+
+ final Function compileFunction(Scriptable scope, String source,
+ Evaluator compiler,
+ ErrorReporter compilationErrorReporter,
+ String sourceName, int lineno,
+ Object securityDomain)
+ {
+ try {
+ return (Function) compileImpl(scope, null, source, sourceName,
+ lineno, securityDomain, true,
+ compiler, compilationErrorReporter);
+ }
+ catch (IOException ioe) {
+ // Should never happen because we just made the reader
+ // from a String
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Decompile the script.
+ * <p>
+ * The canonical source of the script is returned.
+ *
+ * @param script the script to decompile
+ * @param indent the number of spaces to indent the result
+ * @return a string representing the script source
+ */
+ public final String decompileScript(Script script, int indent)
+ {
+ NativeFunction scriptImpl = (NativeFunction) script;
+ return scriptImpl.decompile(indent, 0);
+ }
+
+ /**
+ * Decompile a JavaScript Function.
+ * <p>
+ * Decompiles a previously compiled JavaScript function object to
+ * canonical source.
+ * <p>
+ * Returns function body of '[native code]' if no decompilation
+ * information is available.
+ *
+ * @param fun the JavaScript function to decompile
+ * @param indent the number of spaces to indent the result
+ * @return a string representing the function source
+ */
+ public final String decompileFunction(Function fun, int indent)
+ {
+ if (fun instanceof BaseFunction)
+ return ((BaseFunction)fun).decompile(indent, 0);
+ else
+ return "function " + fun.getClassName() +
+ "() {\n\t[native code]\n}\n";
+ }
+
+ /**
+ * Decompile the body of a JavaScript Function.
+ * <p>
+ * Decompiles the body a previously compiled JavaScript Function
+ * object to canonical source, omitting the function header and
+ * trailing brace.
+ *
+ * Returns '[native code]' if no decompilation information is available.
+ *
+ * @param fun the JavaScript function to decompile
+ * @param indent the number of spaces to indent the result
+ * @return a string representing the function body source.
+ */
+ public final String decompileFunctionBody(Function fun, int indent)
+ {
+ if (fun instanceof BaseFunction) {
+ BaseFunction bf = (BaseFunction)fun;
+ return bf.decompile(indent, Decompiler.ONLY_BODY_FLAG);
+ }
+ // ALERT: not sure what the right response here is.
+ return "[native code]\n";
+ }
+
+ /**
+ * Create a new JavaScript object.
+ *
+ * Equivalent to evaluating "new Object()".
+ * @param scope the scope to search for the constructor and to evaluate
+ * against
+ * @return the new object
+ */
+ public final Scriptable newObject(Scriptable scope)
+ {
+ return newObject(scope, "Object", ScriptRuntime.emptyArgs);
+ }
+
+ /**
+ * Create a new JavaScript object by executing the named constructor.
+ *
+ * The call <code>newObject(scope, "Foo")</code> is equivalent to
+ * evaluating "new Foo()".
+ *
+ * @param scope the scope to search for the constructor and to evaluate against
+ * @param constructorName the name of the constructor to call
+ * @return the new object
+ */
+ public final Scriptable newObject(Scriptable scope, String constructorName)
+ {
+ return newObject(scope, constructorName, ScriptRuntime.emptyArgs);
+ }
+
+ /**
+ * Creates a new JavaScript object by executing the named constructor.
+ *
+ * Searches <code>scope</code> for the named constructor, calls it with
+ * the given arguments, and returns the result.<p>
+ *
+ * The code
+ * <pre>
+ * Object[] args = { "a", "b" };
+ * newObject(scope, "Foo", args)</pre>
+ * is equivalent to evaluating "new Foo('a', 'b')", assuming that the Foo
+ * constructor has been defined in <code>scope</code>.
+ *
+ * @param scope The scope to search for the constructor and to evaluate
+ * against
+ * @param constructorName the name of the constructor to call
+ * @param args the array of arguments for the constructor
+ * @return the new object
+ */
+ public final Scriptable newObject(Scriptable scope, String constructorName,
+ Object[] args)
+ {
+ scope = ScriptableObject.getTopLevelScope(scope);
+ Function ctor = ScriptRuntime.getExistingCtor(this, scope,
+ constructorName);
+ if (args == null) { args = ScriptRuntime.emptyArgs; }
+ return ctor.construct(this, scope, args);
+ }
+
+ /**
+ * Create an array with a specified initial length.
+ * <p>
+ * @param scope the scope to create the object in
+ * @param length the initial length (JavaScript arrays may have
+ * additional properties added dynamically).
+ * @return the new array object
+ */
+ public final Scriptable newArray(Scriptable scope, int length)
+ {
+ NativeArray result = new NativeArray(length);
+ ScriptRuntime.setObjectProtoAndParent(result, scope);
+ return result;
+ }
+
+ /**
+ * Create an array with a set of initial elements.
+ *
+ * @param scope the scope to create the object in.
+ * @param elements the initial elements. Each object in this array
+ * must be an acceptable JavaScript type and type
+ * of array should be exactly Object[], not
+ * SomeObjectSubclass[].
+ * @return the new array object.
+ */
+ public final Scriptable newArray(Scriptable scope, Object[] elements)
+ {
+ if (elements.getClass().getComponentType() != ScriptRuntime.ObjectClass)
+ throw new IllegalArgumentException();
+ NativeArray result = new NativeArray(elements);
+ ScriptRuntime.setObjectProtoAndParent(result, scope);
+ return result;
+ }
+
+ /**
+ * Get the elements of a JavaScript array.
+ * <p>
+ * If the object defines a length property convertible to double number,
+ * then the number is converted Uint32 value as defined in Ecma 9.6
+ * and Java array of that size is allocated.
+ * The array is initialized with the values obtained by
+ * calling get() on object for each value of i in [0,length-1]. If
+ * there is not a defined value for a property the Undefined value
+ * is used to initialize the corresponding element in the array. The
+ * Java array is then returned.
+ * If the object doesn't define a length property or it is not a number,
+ * empty array is returned.
+ * @param object the JavaScript array or array-like object
+ * @return a Java array of objects
+ * @since 1.4 release 2
+ */
+ public final Object[] getElements(Scriptable object)
+ {
+ return ScriptRuntime.getArrayElements(object);
+ }
+
+ /**
+ * Convert the value to a JavaScript boolean value.
+ * <p>
+ * See ECMA 9.2.
+ *
+ * @param value a JavaScript value
+ * @return the corresponding boolean value converted using
+ * the ECMA rules
+ */
+ public static boolean toBoolean(Object value)
+ {
+ return ScriptRuntime.toBoolean(value);
+ }
+
+ /**
+ * Convert the value to a JavaScript Number value.
+ * <p>
+ * Returns a Java double for the JavaScript Number.
+ * <p>
+ * See ECMA 9.3.
+ *
+ * @param value a JavaScript value
+ * @return the corresponding double value converted using
+ * the ECMA rules
+ */
+ public static double toNumber(Object value)
+ {
+ return ScriptRuntime.toNumber(value);
+ }
+
+ /**
+ * Convert the value to a JavaScript String value.
+ * <p>
+ * See ECMA 9.8.
+ * <p>
+ * @param value a JavaScript value
+ * @return the corresponding String value converted using
+ * the ECMA rules
+ */
+ public static String toString(Object value)
+ {
+ return ScriptRuntime.toString(value);
+ }
+
+ /**
+ * Convert the value to an JavaScript object value.
+ * <p>
+ * Note that a scope must be provided to look up the constructors
+ * for Number, Boolean, and String.
+ * <p>
+ * See ECMA 9.9.
+ * <p>
+ * Additionally, arbitrary Java objects and classes will be
+ * wrapped in a Scriptable object with its Java fields and methods
+ * reflected as JavaScript properties of the object.
+ *
+ * @param value any Java object
+ * @param scope global scope containing constructors for Number,
+ * Boolean, and String
+ * @return new JavaScript object
+ */
+ public static Scriptable toObject(Object value, Scriptable scope)
+ {
+ return ScriptRuntime.toObject(scope, value);
+ }
+
+ /**
+ * @deprecated
+ * @see #toObject(Object, Scriptable)
+ */
+ public static Scriptable toObject(Object value, Scriptable scope,
+ Class staticType)
+ {
+ return ScriptRuntime.toObject(scope, value);
+ }
+
+ /**
+ * Convenient method to convert java value to its closest representation
+ * in JavaScript.
+ * <p>
+ * If value is an instance of String, Number, Boolean, Function or
+ * Scriptable, it is returned as it and will be treated as the corresponding
+ * JavaScript type of string, number, boolean, function and object.
+ * <p>
+ * Note that for Number instances during any arithmetic operation in
+ * JavaScript the engine will always use the result of
+ * <tt>Number.doubleValue()</tt> resulting in a precision loss if
+ * the number can not fit into double.
+ * <p>
+ * If value is an instance of Character, it will be converted to string of
+ * length 1 and its JavaScript type will be string.
+ * <p>
+ * The rest of values will be wrapped as LiveConnect objects
+ * by calling {@link WrapFactory#wrap(Context cx, Scriptable scope,
+ * Object obj, Class staticType)} as in:
+ * <pre>
+ * Context cx = Context.getCurrentContext();
+ * return cx.getWrapFactory().wrap(cx, scope, value, null);
+ * </pre>
+ *
+ * @param value any Java object
+ * @param scope top scope object
+ * @return value suitable to pass to any API that takes JavaScript values.
+ */
+ public static Object javaToJS(Object value, Scriptable scope)
+ {
+ if (value instanceof String || value instanceof Number
+ || value instanceof Boolean || value instanceof Scriptable)
+ {
+ return value;
+ } else if (value instanceof Character) {
+ return String.valueOf(((Character)value).charValue());
+ } else {
+ Context cx = Context.getContext();
+ return cx.getWrapFactory().wrap(cx, scope, value, null);
+ }
+ }
+
+ /**
+ * Convert a JavaScript value into the desired type.
+ * Uses the semantics defined with LiveConnect3 and throws an
+ * Illegal argument exception if the conversion cannot be performed.
+ * @param value the JavaScript value to convert
+ * @param desiredType the Java type to convert to. Primitive Java
+ * types are represented using the TYPE fields in the corresponding
+ * wrapper class in java.lang.
+ * @return the converted value
+ * @throws EvaluatorException if the conversion cannot be performed
+ */
+ public static Object jsToJava(Object value, Class desiredType)
+ throws EvaluatorException
+ {
+ return NativeJavaObject.coerceTypeImpl(desiredType, value);
+ }
+
+ /**
+ * @deprecated
+ * @see #jsToJava(Object, Class)
+ * @throws IllegalArgumentException if the conversion cannot be performed.
+ * Note that {@link #jsToJava(Object, Class)} throws
+ * {@link EvaluatorException} instead.
+ */
+ public static Object toType(Object value, Class desiredType)
+ throws IllegalArgumentException
+ {
+ try {
+ return jsToJava(value, desiredType);
+ } catch (EvaluatorException ex) {
+ IllegalArgumentException
+ ex2 = new IllegalArgumentException(ex.getMessage());
+ Kit.initCause(ex2, ex);
+ throw ex2;
+ }
+ }
+
+ /**
+ * Rethrow the exception wrapping it as the script runtime exception.
+ * Unless the exception is instance of {@link EcmaError} or
+ * {@link EvaluatorException} it will be wrapped as
+ * {@link WrappedException}, a subclass of {@link EvaluatorException}.
+ * The resulting exception object always contains
+ * source name and line number of script that triggered exception.
+ * <p>
+ * This method always throws an exception, its return value is provided
+ * only for convenience to allow a usage like:
+ * <pre>
+ * throw Context.throwAsScriptRuntimeEx(ex);
+ * </pre>
+ * to indicate that code after the method is unreachable.
+ * @throws EvaluatorException
+ * @throws EcmaError
+ */
+ public static RuntimeException throwAsScriptRuntimeEx(Throwable e)
+ {
+ while ((e instanceof InvocationTargetException)) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+ // special handling of Error so scripts would not catch them
+ if (e instanceof Error) {
+ Context cx = getContext();
+ if (cx == null ||
+ !cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS))
+ {
+ throw (Error)e;
+ }
+ }
+ if (e instanceof RhinoException) {
+ throw (RhinoException)e;
+ }
+ throw new WrappedException(e);
+ }
+
+ /**
+ * Tell whether debug information is being generated.
+ * @since 1.3
+ */
+ public final boolean isGeneratingDebug()
+ {
+ return generatingDebug;
+ }
+
+ /**
+ * Specify whether or not debug information should be generated.
+ * <p>
+ * Setting the generation of debug information on will set the
+ * optimization level to zero.
+ * @since 1.3
+ */
+ public final void setGeneratingDebug(boolean generatingDebug)
+ {
+ if (sealed) onSealedMutation();
+ generatingDebugChanged = true;
+ if (generatingDebug && getOptimizationLevel() > 0)
+ setOptimizationLevel(0);
+ this.generatingDebug = generatingDebug;
+ }
+
+ /**
+ * Tell whether source information is being generated.
+ * @since 1.3
+ */
+ public final boolean isGeneratingSource()
+ {
+ return generatingSource;
+ }
+
+ /**
+ * Specify whether or not source information should be generated.
+ * <p>
+ * Without source information, evaluating the "toString" method
+ * on JavaScript functions produces only "[native code]" for
+ * the body of the function.
+ * Note that code generated without source is not fully ECMA
+ * conformant.
+ * @since 1.3
+ */
+ public final void setGeneratingSource(boolean generatingSource)
+ {
+ if (sealed) onSealedMutation();
+ this.generatingSource = generatingSource;
+ }
+
+ /**
+ * Get the current optimization level.
+ * <p>
+ * The optimization level is expressed as an integer between -1 and
+ * 9.
+ * @since 1.3
+ *
+ */
+ public final int getOptimizationLevel()
+ {
+ return optimizationLevel;
+ }
+
+ /**
+ * Set the current optimization level.
+ * <p>
+ * The optimization level is expected to be an integer between -1 and
+ * 9. Any negative values will be interpreted as -1, and any values
+ * greater than 9 will be interpreted as 9.
+ * An optimization level of -1 indicates that interpretive mode will
+ * always be used. Levels 0 through 9 indicate that class files may
+ * be generated. Higher optimization levels trade off compile time
+ * performance for runtime performance.
+ * The optimizer level can't be set greater than -1 if the optimizer
+ * package doesn't exist at run time.
+ * @param optimizationLevel an integer indicating the level of
+ * optimization to perform
+ * @since 1.3
+ *
+ */
+ public final void setOptimizationLevel(int optimizationLevel)
+ {
+ if (sealed) onSealedMutation();
+ if (optimizationLevel == -2) {
+ // To be compatible with Cocoon fork
+ optimizationLevel = -1;
+ }
+ checkOptimizationLevel(optimizationLevel);
+ if (codegenClass == null)
+ optimizationLevel = -1;
+ this.optimizationLevel = optimizationLevel;
+ }
+
+ public static boolean isValidOptimizationLevel(int optimizationLevel)
+ {
+ return -1 <= optimizationLevel && optimizationLevel <= 9;
+ }
+
+ public static void checkOptimizationLevel(int optimizationLevel)
+ {
+ if (isValidOptimizationLevel(optimizationLevel)) {
+ return;
+ }
+ throw new IllegalArgumentException(
+ "Optimization level outside [-1..9]: "+optimizationLevel);
+ }
+
+ /**
+ * Returns the maximum stack depth (in terms of number of call frames)
+ * allowed in a single invocation of interpreter. If the set depth would be
+ * exceeded, the interpreter will throw an EvaluatorException in the script.
+ * Defaults to Integer.MAX_VALUE. The setting only has effect for
+ * interpreted functions (those compiled with optimization level set to -1).
+ * As the interpreter doesn't use the Java stack but rather manages its own
+ * stack in the heap memory, a runaway recursion in interpreted code would
+ * eventually consume all available memory and cause OutOfMemoryError
+ * instead of a StackOverflowError limited to only a single thread. This
+ * setting helps prevent such situations.
+ *
+ * @return The current maximum interpreter stack depth.
+ */
+ public final int getMaximumInterpreterStackDepth()
+ {
+ return maximumInterpreterStackDepth;
+ }
+
+ /**
+ * Sets the maximum stack depth (in terms of number of call frames)
+ * allowed in a single invocation of interpreter. If the set depth would be
+ * exceeded, the interpreter will throw an EvaluatorException in the script.
+ * Defaults to Integer.MAX_VALUE. The setting only has effect for
+ * interpreted functions (those compiled with optimization level set to -1).
+ * As the interpreter doesn't use the Java stack but rather manages its own
+ * stack in the heap memory, a runaway recursion in interpreted code would
+ * eventually consume all available memory and cause OutOfMemoryError
+ * instead of a StackOverflowError limited to only a single thread. This
+ * setting helps prevent such situations.
+ *
+ * @param max the new maximum interpreter stack depth
+ * @throws IllegalStateException if this context's optimization level is not
+ * -1
+ * @throws IllegalArgumentException if the new depth is not at least 1
+ */
+ public final void setMaximumInterpreterStackDepth(int max)
+ {
+ if(sealed) onSealedMutation();
+ if(optimizationLevel != -1) {
+ throw new IllegalStateException("Cannot set maximumInterpreterStackDepth when optimizationLevel != -1");
+ }
+ if(max < 1) {
+ throw new IllegalArgumentException("Cannot set maximumInterpreterStackDepth to less than 1");
+ }
+ maximumInterpreterStackDepth = max;
+ }
+
+ /**
+ * Set the security controller for this context.
+ * <p> SecurityController may only be set if it is currently null
+ * and {@link SecurityController#hasGlobal()} is <tt>false</tt>.
+ * Otherwise a SecurityException is thrown.
+ * @param controller a SecurityController object
+ * @throws SecurityException if there is already a SecurityController
+ * object for this Context or globally installed.
+ * @see SecurityController#initGlobal(SecurityController controller)
+ * @see SecurityController#hasGlobal()
+ */
+ public final void setSecurityController(SecurityController controller)
+ {
+ if (sealed) onSealedMutation();
+ if (controller == null) throw new IllegalArgumentException();
+ if (securityController != null) {
+ throw new SecurityException("Can not overwrite existing SecurityController object");
+ }
+ if (SecurityController.hasGlobal()) {
+ throw new SecurityException("Can not overwrite existing global SecurityController object");
+ }
+ securityController = controller;
+ }
+
+ /**
+ * Set the LiveConnect access filter for this context.
+ * <p> {@link ClassShutter} may only be set if it is currently null.
+ * Otherwise a SecurityException is thrown.
+ * @param shutter a ClassShutter object
+ * @throws SecurityException if there is already a ClassShutter
+ * object for this Context
+ */
+ public final void setClassShutter(ClassShutter shutter)
+ {
+ if (sealed) onSealedMutation();
+ if (shutter == null) throw new IllegalArgumentException();
+ if (classShutter != null) {
+ throw new SecurityException("Cannot overwrite existing " +
+ "ClassShutter object");
+ }
+ classShutter = shutter;
+ }
+
+ final ClassShutter getClassShutter()
+ {
+ return classShutter;
+ }
+
+ /**
+ * Get a value corresponding to a key.
+ * <p>
+ * Since the Context is associated with a thread it can be
+ * used to maintain values that can be later retrieved using
+ * the current thread.
+ * <p>
+ * Note that the values are maintained with the Context, so
+ * if the Context is disassociated from the thread the values
+ * cannot be retrieved. Also, if private data is to be maintained
+ * in this manner the key should be a java.lang.Object
+ * whose reference is not divulged to untrusted code.
+ * @param key the key used to lookup the value
+ * @return a value previously stored using putThreadLocal.
+ */
+ public final Object getThreadLocal(Object key)
+ {
+ if (hashtable == null)
+ return null;
+ return hashtable.get(key);
+ }
+
+ /**
+ * Put a value that can later be retrieved using a given key.
+ * <p>
+ * @param key the key used to index the value
+ * @param value the value to save
+ */
+ public final void putThreadLocal(Object key, Object value)
+ {
+ if (sealed) onSealedMutation();
+ if (hashtable == null)
+ hashtable = new Hashtable();
+ hashtable.put(key, value);
+ }
+
+ /**
+ * Remove values from thread-local storage.
+ * @param key the key for the entry to remove.
+ * @since 1.5 release 2
+ */
+ public final void removeThreadLocal(Object key)
+ {
+ if (sealed) onSealedMutation();
+ if (hashtable == null)
+ return;
+ hashtable.remove(key);
+ }
+
+ /**
+ * @deprecated
+ * @see #FEATURE_DYNAMIC_SCOPE
+ * @see #hasFeature(int)
+ */
+ public final boolean hasCompileFunctionsWithDynamicScope()
+ {
+ return compileFunctionsWithDynamicScopeFlag;
+ }
+
+ /**
+ * @deprecated
+ * @see #FEATURE_DYNAMIC_SCOPE
+ * @see #hasFeature(int)
+ */
+ public final void setCompileFunctionsWithDynamicScope(boolean flag)
+ {
+ if (sealed) onSealedMutation();
+ compileFunctionsWithDynamicScopeFlag = flag;
+ }
+
+ /**
+ * @deprecated
+ * @see ClassCache#get(Scriptable)
+ * @see ClassCache#setCachingEnabled(boolean)
+ */
+ public static void setCachingEnabled(boolean cachingEnabled)
+ {
+ }
+
+ /**
+ * Set a WrapFactory for this Context.
+ * <p>
+ * The WrapFactory allows custom object wrapping behavior for
+ * Java object manipulated with JavaScript.
+ * @see WrapFactory
+ * @since 1.5 Release 4
+ */
+ public final void setWrapFactory(WrapFactory wrapFactory)
+ {
+ if (sealed) onSealedMutation();
+ if (wrapFactory == null) throw new IllegalArgumentException();
+ this.wrapFactory = wrapFactory;
+ }
+
+ /**
+ * Return the current WrapFactory, or null if none is defined.
+ * @see WrapFactory
+ * @since 1.5 Release 4
+ */
+ public final WrapFactory getWrapFactory()
+ {
+ if (wrapFactory == null) {
+ wrapFactory = new WrapFactory();
+ }
+ return wrapFactory;
+ }
+
+ /**
+ * Return the current debugger.
+ * @return the debugger, or null if none is attached.
+ */
+ public final Debugger getDebugger()
+ {
+ return debugger;
+ }
+
+ /**
+ * Return the debugger context data associated with current context.
+ * @return the debugger data, or null if debugger is not attached
+ */
+ public final Object getDebuggerContextData()
+ {
+ return debuggerData;
+ }
+
+ /**
+ * Set the associated debugger.
+ * @param debugger the debugger to be used on callbacks from
+ * the engine.
+ * @param contextData arbitrary object that debugger can use to store
+ * per Context data.
+ */
+ public final void setDebugger(Debugger debugger, Object contextData)
+ {
+ if (sealed) onSealedMutation();
+ this.debugger = debugger;
+ debuggerData = contextData;
+ }
+
+ /**
+ * Return DebuggableScript instance if any associated with the script.
+ * If callable supports DebuggableScript implementation, the method
+ * returns it. Otherwise null is returned.
+ */
+ public static DebuggableScript getDebuggableView(Script script)
+ {
+ if (script instanceof NativeFunction) {
+ return ((NativeFunction)script).getDebuggableView();
+ }
+ return null;
+ }
+
+ /**
+ * Controls certain aspects of script semantics.
+ * Should be overwritten to alter default behavior.
+ * <p>
+ * The default implementation calls
+ * {@link ContextFactory#hasFeature(Context cx, int featureIndex)}
+ * that allows to customize Context behavior without introducing
+ * Context subclasses. {@link ContextFactory} documentation gives
+ * an example of hasFeature implementation.
+ *
+ * @param featureIndex feature index to check
+ * @return true if the <code>featureIndex</code> feature is turned on
+ * @see #FEATURE_NON_ECMA_GET_YEAR
+ * @see #FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME
+ * @see #FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER
+ * @see #FEATURE_TO_STRING_AS_SOURCE
+ * @see #FEATURE_PARENT_PROTO_PROPRTIES
+ * @see #FEATURE_E4X
+ * @see #FEATURE_DYNAMIC_SCOPE
+ * @see #FEATURE_STRICT_VARS
+ * @see #FEATURE_STRICT_EVAL
+ * @see #FEATURE_LOCATION_INFORMATION_IN_ERROR
+ * @see #FEATURE_STRICT_MODE
+ * @see #FEATURE_WARNING_AS_ERROR
+ * @see #FEATURE_ENHANCED_JAVA_ACCESS
+ */
+ public boolean hasFeature(int featureIndex)
+ {
+ ContextFactory f = getFactory();
+ return f.hasFeature(this, featureIndex);
+ }
+
+ /**
+ Returns an object which specifies an E4X implementation to use within
+ this <code>Context</code>. Note
+ that the XMLLib.Factory interface should be considered experimental.
+
+ The default implementation uses the implementation provided by this
+ <code>Context</code>'s {@link ContextFactory}.
+
+ @return An XMLLib.Factory. Should not return <code>null</code> if
+ {@link #FEATURE_E4X} is enabled. See {@link #hasFeature}.
+ */
+ public XMLLib.Factory getE4xImplementationFactory() {
+ return getFactory().getE4xImplementationFactory();
+ }
+
+ /**
+ * Get threshold of executed instructions counter that triggers call to
+ * <code>observeInstructionCount()</code>.
+ * When the threshold is zero, instruction counting is disabled,
+ * otherwise each time the run-time executes at least the threshold value
+ * of script instructions, <code>observeInstructionCount()</code> will
+ * be called.
+ */
+ public final int getInstructionObserverThreshold()
+ {
+ return instructionThreshold;
+ }
+
+ /**
+ * Set threshold of executed instructions counter that triggers call to
+ * <code>observeInstructionCount()</code>.
+ * When the threshold is zero, instruction counting is disabled,
+ * otherwise each time the run-time executes at least the threshold value
+ * of script instructions, <code>observeInstructionCount()</code> will
+ * be called.<p/>
+ * Note that the meaning of "instruction" is not guaranteed to be
+ * consistent between compiled and interpretive modes: executing a given
+ * script or function in the different modes will result in different
+ * instruction counts against the threshold.
+ * {@link #setGenerateObserverCount} is called with true if
+ * <code>threshold</code> is greater than zero, false otherwise.
+ * @param threshold The instruction threshold
+ */
+ public final void setInstructionObserverThreshold(int threshold)
+ {
+ if (sealed) onSealedMutation();
+ if (threshold < 0) throw new IllegalArgumentException();
+ instructionThreshold = threshold;
+ setGenerateObserverCount(threshold > 0);
+ }
+
+ /**
+ * Turn on or off generation of code with callbacks to
+ * track the count of executed instructions.
+ * Currently only affects JVM byte code generation: this slows down the
+ * generated code, but code generated without the callbacks will not
+ * be counted toward instruction thresholds. Rhino's interpretive
+ * mode does instruction counting without inserting callbacks, so
+ * there is no requirement to compile code differently.
+ * @param generateObserverCount if true, generated code will contain
+ * calls to accumulate an estimate of the instructions executed.
+ */
+ public void setGenerateObserverCount(boolean generateObserverCount) {
+ this.generateObserverCount = generateObserverCount;
+ }
+
+ /**
+ * Allow application to monitor counter of executed script instructions
+ * in Context subclasses.
+ * Run-time calls this when instruction counting is enabled and the counter
+ * reaches limit set by <code>setInstructionObserverThreshold()</code>.
+ * The method is useful to observe long running scripts and if necessary
+ * to terminate them.
+ * <p>
+ * The instruction counting support is available only for interpreted
+ * scripts generated when the optimization level is set to -1.
+ * <p>
+ * The default implementation calls
+ * {@link ContextFactory#observeInstructionCount(Context cx,
+ * int instructionCount)}
+ * that allows to customize Context behavior without introducing
+ * Context subclasses.
+ *
+ * @param instructionCount amount of script instruction executed since
+ * last call to <code>observeInstructionCount</code>
+ * @throws Error to terminate the script
+ * @see #setOptimizationLevel(int)
+ */
+ protected void observeInstructionCount(int instructionCount)
+ {
+ ContextFactory f = getFactory();
+ f.observeInstructionCount(this, instructionCount);
+ }
+
+ /**
+ * Create class loader for generated classes.
+ * The method calls {@link ContextFactory#createClassLoader(ClassLoader)}
+ * using the result of {@link #getFactory()}.
+ */
+ public GeneratedClassLoader createClassLoader(ClassLoader parent)
+ {
+ ContextFactory f = getFactory();
+ return f.createClassLoader(parent);
+ }
+
+ public final ClassLoader getApplicationClassLoader()
+ {
+ if (applicationClassLoader == null) {
+ ContextFactory f = getFactory();
+ ClassLoader loader = f.getApplicationClassLoader();
+ if (loader == null) {
+ ClassLoader threadLoader
+ = VMBridge.instance.getCurrentThreadClassLoader();
+ if (threadLoader != null
+ && Kit.testIfCanLoadRhinoClasses(threadLoader))
+ {
+ // Thread.getContextClassLoader is not cached since
+ // its caching prevents it from GC which may lead to
+ // a memory leak and hides updates to
+ // Thread.getContextClassLoader
+ return threadLoader;
+ }
+ // Thread.getContextClassLoader can not load Rhino classes,
+ // try to use the loader of ContextFactory or Context
+ // subclasses.
+ Class fClass = f.getClass();
+ if (fClass != ScriptRuntime.ContextFactoryClass) {
+ loader = fClass.getClassLoader();
+ } else {
+ loader = getClass().getClassLoader();
+ }
+ }
+ applicationClassLoader = loader;
+ }
+ return applicationClassLoader;
+ }
+
+ public final void setApplicationClassLoader(ClassLoader loader)
+ {
+ if (sealed) onSealedMutation();
+ if (loader == null) {
+ // restore default behaviour
+ applicationClassLoader = null;
+ return;
+ }
+ if (!Kit.testIfCanLoadRhinoClasses(loader)) {
+ throw new IllegalArgumentException(
+ "Loader can not resolve Rhino classes");
+ }
+ applicationClassLoader = loader;
+ }
+
+ /********** end of API **********/
+
+ /**
+ * Internal method that reports an error for missing calls to
+ * enter().
+ */
+ static Context getContext()
+ {
+ Context cx = getCurrentContext();
+ if (cx == null) {
+ throw new RuntimeException(
+ "No Context associated with current Thread");
+ }
+ return cx;
+ }
+
+ private Object compileImpl(Scriptable scope,
+ Reader sourceReader, String sourceString,
+ String sourceName, int lineno,
+ Object securityDomain, boolean returnFunction,
+ Evaluator compiler,
+ ErrorReporter compilationErrorReporter)
+ throws IOException
+ {
+ if(sourceName == null) {
+ sourceName = "unnamed script";
+ }
+ if (securityDomain != null && getSecurityController() == null) {
+ throw new IllegalArgumentException(
+ "securityDomain should be null if setSecurityController() was never called");
+ }
+
+ // One of sourceReader or sourceString has to be null
+ if (!(sourceReader == null ^ sourceString == null)) Kit.codeBug();
+ // scope should be given if and only if compiling function
+ if (!(scope == null ^ returnFunction)) Kit.codeBug();
+
+ CompilerEnvirons compilerEnv = new CompilerEnvirons();
+ compilerEnv.initFromContext(this);
+ if (compilationErrorReporter == null) {
+ compilationErrorReporter = compilerEnv.getErrorReporter();
+ }
+
+ if (debugger != null) {
+ if (sourceReader != null) {
+ sourceString = Kit.readReader(sourceReader);
+ sourceReader = null;
+ }
+ }
+
+ /*APPJET*/
+ Parser p = InformativeParser.makeParser(compilerEnv,
+ compilationErrorReporter);
+ if (returnFunction) {
+ p.calledByCompileFunction = true;
+ }
+ ScriptOrFnNode tree;
+ if (sourceString != null) {
+ tree = p.parse(sourceString, sourceName, lineno);
+ } else {
+ tree = p.parse(sourceReader, sourceName, lineno);
+ }
+ if (returnFunction) {
+ if (!(tree.getFunctionCount() == 1
+ && tree.getFirstChild() != null
+ && tree.getFirstChild().getType() == Token.FUNCTION))
+ {
+ // XXX: the check just look for the first child
+ // and allows for more nodes after it for compatibility
+ // with sources like function() {};;;
+ throw new IllegalArgumentException(
+ "compileFunction only accepts source with single JS function: "+sourceString);
+ }
+ }
+
+ if (compiler == null) {
+ compiler = createCompiler();
+ }
+
+ String encodedSource = p.getEncodedSource();
+
+ Object bytecode = compiler.compile(compilerEnv,
+ tree, encodedSource,
+ returnFunction);
+
+ if (debugger != null) {
+ if (sourceString == null) Kit.codeBug();
+ if (bytecode instanceof DebuggableScript) {
+ DebuggableScript dscript = (DebuggableScript)bytecode;
+ notifyDebugger_r(this, dscript, sourceString);
+ } else {
+ throw new RuntimeException("NOT SUPPORTED");
+ }
+ }
+
+ Object result;
+ if (returnFunction) {
+ result = compiler.createFunctionObject(this, scope, bytecode, securityDomain);
+ } else {
+ result = compiler.createScriptObject(bytecode, securityDomain);
+ }
+
+ return result;
+ }
+
+ private static void notifyDebugger_r(Context cx, DebuggableScript dscript,
+ String debugSource)
+ {
+ cx.debugger.handleCompilationDone(cx, dscript, debugSource);
+ for (int i = 0; i != dscript.getFunctionCount(); ++i) {
+ notifyDebugger_r(cx, dscript.getFunction(i), debugSource);
+ }
+ }
+
+ private static Class codegenClass = Kit.classOrNull(
+ "org.mozilla.javascript.optimizer.Codegen");
+ private static Class interpreterClass = Kit.classOrNull(
+ "org.mozilla.javascript.Interpreter");
+
+ private Evaluator createCompiler()
+ {
+ Evaluator result = null;
+ if (optimizationLevel >= 0 && codegenClass != null) {
+ result = (Evaluator)Kit.newInstanceOrNull(codegenClass);
+ }
+ if (result == null) {
+ result = createInterpreter();
+ }
+ return result;
+ }
+
+ static Evaluator createInterpreter()
+ {
+ return (Evaluator)Kit.newInstanceOrNull(interpreterClass);
+ }
+
+ static String getSourcePositionFromStack(int[] linep)
+ {
+ Context cx = getCurrentContext();
+ if (cx == null)
+ return null;
+ if (cx.lastInterpreterFrame != null) {
+ Evaluator evaluator = createInterpreter();
+ if (evaluator != null)
+ return evaluator.getSourcePositionFromStack(cx, linep);
+ }
+ /**
+ * A bit of a hack, but the only way to get filename and line
+ * number from an enclosing frame.
+ */
+ CharArrayWriter writer = new CharArrayWriter();
+ RuntimeException re = new RuntimeException();
+ re.printStackTrace(new PrintWriter(writer));
+ String s = writer.toString();
+ int open = -1;
+ int close = -1;
+ int colon = -1;
+ for (int i=0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == ':')
+ colon = i;
+ else if (c == '(')
+ open = i;
+ else if (c == ')')
+ close = i;
+ else if (c == '\n' && open != -1 && close != -1 && colon != -1 &&
+ open < colon && colon < close)
+ {
+ String fileStr = s.substring(open + 1, colon);
+ if (!fileStr.endsWith(".java")) {
+ String lineStr = s.substring(colon + 1, close);
+ try {
+ linep[0] = Integer.parseInt(lineStr);
+ if (linep[0] < 0) {
+ linep[0] = 0;
+ }
+ return fileStr;
+ }
+ catch (NumberFormatException e) {
+ // fall through
+ }
+ }
+ open = close = colon = -1;
+ }
+ }
+
+ return null;
+ }
+
+ RegExpProxy getRegExpProxy()
+ {
+ if (regExpProxy == null) {
+ Class cl = Kit.classOrNull(
+ "org.mozilla.javascript.regexp.RegExpImpl");
+ if (cl != null) {
+ regExpProxy = (RegExpProxy)Kit.newInstanceOrNull(cl);
+ }
+ }
+ return regExpProxy;
+ }
+
+ final boolean isVersionECMA1()
+ {
+ return version == VERSION_DEFAULT || version >= VERSION_1_3;
+ }
+
+// The method must NOT be public or protected
+ SecurityController getSecurityController()
+ {
+ SecurityController global = SecurityController.global();
+ if (global != null) {
+ return global;
+ }
+ return securityController;
+ }
+
+ public final boolean isGeneratingDebugChanged()
+ {
+ return generatingDebugChanged;
+ }
+
+ /**
+ * Add a name to the list of names forcing the creation of real
+ * activation objects for functions.
+ *
+ * @param name the name of the object to add to the list
+ */
+ public void addActivationName(String name)
+ {
+ if (sealed) onSealedMutation();
+ if (activationNames == null)
+ activationNames = new Hashtable(5);
+ activationNames.put(name, name);
+ }
+
+ /**
+ * Check whether the name is in the list of names of objects
+ * forcing the creation of activation objects.
+ *
+ * @param name the name of the object to test
+ *
+ * @return true if an function activation object is needed.
+ */
+ public final boolean isActivationNeeded(String name)
+ {
+ return activationNames != null && activationNames.containsKey(name);
+ }
+
+ /**
+ * Remove a name from the list of names forcing the creation of real
+ * activation objects for functions.
+ *
+ * @param name the name of the object to remove from the list
+ */
+ public void removeActivationName(String name)
+ {
+ if (sealed) onSealedMutation();
+ if (activationNames != null)
+ activationNames.remove(name);
+ }
+
+ private static String implementationVersion;
+
+ private final ContextFactory factory;
+ private boolean sealed;
+ private Object sealKey;
+
+ Scriptable topCallScope;
+ NativeCall currentActivationCall;
+ XMLLib cachedXMLLib;
+
+ // for Objects, Arrays to tag themselves as being printed out,
+ // so they don't print themselves out recursively.
+ // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility
+ ObjToIntMap iterating;
+
+ Object interpreterSecurityDomain;
+
+ int version;
+
+ private SecurityController securityController;
+ private ClassShutter classShutter;
+ private ErrorReporter errorReporter;
+ RegExpProxy regExpProxy;
+ private Locale locale;
+ private boolean generatingDebug;
+ private boolean generatingDebugChanged;
+ private boolean generatingSource=true;
+ boolean compileFunctionsWithDynamicScopeFlag;
+ boolean useDynamicScope;
+ private int optimizationLevel;
+ private int maximumInterpreterStackDepth;
+ private WrapFactory wrapFactory;
+ Debugger debugger;
+ private Object debuggerData;
+ private int enterCount;
+ private Object propertyListeners;
+ private Hashtable hashtable;
+ private ClassLoader applicationClassLoader;
+
+ /**
+ * This is the list of names of objects forcing the creation of
+ * function activation records.
+ */
+ Hashtable activationNames;
+
+ // For the interpreter to store the last frame for error reports etc.
+ Object lastInterpreterFrame;
+
+ // For the interpreter to store information about previous invocations
+ // interpreter invocations
+ ObjArray previousInterpreterInvocations;
+
+ // For instruction counting (interpreter only)
+ int instructionCount;
+ int instructionThreshold;
+
+ // It can be used to return the second index-like result from function
+ int scratchIndex;
+
+ // It can be used to return the second uint32 result from function
+ long scratchUint32;
+
+ // It can be used to return the second Scriptable result from function
+ Scriptable scratchScriptable;
+
+ // Generate an observer count on compiled code
+ public boolean generateObserverCount = false;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java
new file mode 100644
index 0000000..1c584a9
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextAction.java
@@ -0,0 +1,59 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Interface to represent arbitrary action that requires to have Context
+ * object associated with the current thread for its execution.
+ */
+public interface ContextAction
+{
+ /**
+ * Execute action using the supplied Context instance.
+ * When Rhino runtime calls the method, <tt>cx</tt> will be associated
+ * with the current thread as active context.
+ *
+ * @see Context#call(ContextAction)
+ * @see ContextFactory#call(ContextAction)
+ */
+ public Object run(Context cx);
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java
new file mode 100644
index 0000000..4f9fde2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextFactory.java
@@ -0,0 +1,594 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Factory class that Rhino runtime uses to create new {@link Context}
+ * instances. A <code>ContextFactory</code> can also notify listeners
+ * about context creation and release.
+ * <p>
+ * When the Rhino runtime needs to create new {@link Context} instance during
+ * execution of {@link Context#enter()} or {@link Context}, it will call
+ * {@link #makeContext()} of the current global ContextFactory.
+ * See {@link #getGlobal()} and {@link #initGlobal(ContextFactory)}.
+ * <p>
+ * It is also possible to use explicit ContextFactory instances for Context
+ * creation. This is useful to have a set of independent Rhino runtime
+ * instances under single JVM. See {@link #call(ContextAction)}.
+ * <p>
+ * The following example demonstrates Context customization to terminate
+ * scripts running more then 10 seconds and to provide better compatibility
+ * with JavaScript code using MSIE-specific features.
+ * <pre>
+ * import org.mozilla.javascript.*;
+ *
+ * class MyFactory extends ContextFactory
+ * {
+ *
+ * // Custom {@link Context} to store execution time.
+ * private static class MyContext extends Context
+ * {
+ * long startTime;
+ * }
+ *
+ * static {
+ * // Initialize GlobalFactory with custom factory
+ * ContextFactory.initGlobal(new MyFactory());
+ * }
+ *
+ * // Override {@link #makeContext()}
+ * protected Context makeContext()
+ * {
+ * MyContext cx = new MyContext();
+ * // Use pure interpreter mode to allow for
+ * // {@link #observeInstructionCount(Context, int)} to work
+ * cx.setOptimizationLevel(-1);
+ * // Make Rhino runtime to call observeInstructionCount
+ * // each 10000 bytecode instructions
+ * cx.setInstructionObserverThreshold(10000);
+ * return cx;
+ * }
+ *
+ * // Override {@link #hasFeature(Context, int)}
+ * public boolean hasFeature(Context cx, int featureIndex)
+ * {
+ * // Turn on maximum compatibility with MSIE scripts
+ * switch (featureIndex) {
+ * case {@link Context#FEATURE_NON_ECMA_GET_YEAR}:
+ * return true;
+ *
+ * case {@link Context#FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME}:
+ * return true;
+ *
+ * case {@link Context#FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER}:
+ * return true;
+ *
+ * case {@link Context#FEATURE_PARENT_PROTO_PROPERTIES}:
+ * return false;
+ * }
+ * return super.hasFeature(cx, featureIndex);
+ * }
+ *
+ * // Override {@link #observeInstructionCount(Context, int)}
+ * protected void observeInstructionCount(Context cx, int instructionCount)
+ * {
+ * MyContext mcx = (MyContext)cx;
+ * long currentTime = System.currentTimeMillis();
+ * if (currentTime - mcx.startTime > 10*1000) {
+ * // More then 10 seconds from Context creation time:
+ * // it is time to stop the script.
+ * // Throw Error instance to ensure that script will never
+ * // get control back through catch or finally.
+ * throw new Error();
+ * }
+ * }
+ *
+ * // Override {@link #doTopCall(Callable,
+ Context, Scriptable,
+ Scriptable, Object[])}
+ * protected Object doTopCall(Callable callable,
+ * Context cx, Scriptable scope,
+ * Scriptable thisObj, Object[] args)
+ * {
+ * MyContext mcx = (MyContext)cx;
+ * mcx.startTime = System.currentTimeMillis();
+ *
+ * return super.doTopCall(callable, cx, scope, thisObj, args);
+ * }
+ *
+ * }
+ *
+ * </pre>
+ */
+
+public class ContextFactory
+{
+ private static volatile boolean hasCustomGlobal;
+ private static ContextFactory global = new ContextFactory();
+
+ private volatile boolean sealed;
+
+ private final Object listenersLock = new Object();
+ private volatile Object listeners;
+ private boolean disabledListening;
+ private ClassLoader applicationClassLoader;
+
+ /**
+ * Listener of {@link Context} creation and release events.
+ */
+ public interface Listener
+ {
+ /**
+ * Notify about newly created {@link Context} object.
+ */
+ public void contextCreated(Context cx);
+
+ /**
+ * Notify that the specified {@link Context} instance is no longer
+ * associated with the current thread.
+ */
+ public void contextReleased(Context cx);
+ }
+
+ /**
+ * Get global ContextFactory.
+ *
+ * @see #hasExplicitGlobal()
+ * @see #initGlobal(ContextFactory)
+ */
+ public static ContextFactory getGlobal()
+ {
+ return global;
+ }
+
+ /**
+ * Check if global factory was set.
+ * Return true to indicate that {@link #initGlobal(ContextFactory)} was
+ * already called and false to indicate that the global factory was not
+ * explicitly set.
+ *
+ * @see #getGlobal()
+ * @see #initGlobal(ContextFactory)
+ */
+ public static boolean hasExplicitGlobal()
+ {
+ return hasCustomGlobal;
+ }
+
+ /**
+ * Set global ContextFactory.
+ * The method can only be called once.
+ *
+ * @see #getGlobal()
+ * @see #hasExplicitGlobal()
+ */
+ public synchronized static void initGlobal(ContextFactory factory)
+ {
+ if (factory == null) {
+ throw new IllegalArgumentException();
+ }
+ if (hasCustomGlobal) {
+ throw new IllegalStateException();
+ }
+ hasCustomGlobal = true;
+ global = factory;
+ }
+
+ /**
+ * Create new {@link Context} instance to be associated with the current
+ * thread.
+ * This is a callback method used by Rhino to create {@link Context}
+ * instance when it is necessary to associate one with the current
+ * execution thread. <tt>makeContext()</tt> is allowed to call
+ * {@link Context#seal(Object)} on the result to prevent
+ * {@link Context} changes by hostile scripts or applets.
+ */
+ protected Context makeContext()
+ {
+ return new Context(this);
+ }
+
+ /**
+ * Implementation of {@link Context#hasFeature(int featureIndex)}.
+ * This can be used to customize {@link Context} without introducing
+ * additional subclasses.
+ */
+ protected boolean hasFeature(Context cx, int featureIndex)
+ {
+ int version;
+ switch (featureIndex) {
+ case Context.FEATURE_NON_ECMA_GET_YEAR:
+ /*
+ * During the great date rewrite of 1.3, we tried to track the
+ * evolving ECMA standard, which then had a definition of
+ * getYear which always subtracted 1900. Which we
+ * implemented, not realizing that it was incompatible with
+ * the old behavior... now, rather than thrash the behavior
+ * yet again, we've decided to leave it with the - 1900
+ * behavior and point people to the getFullYear method. But
+ * we try to protect existing scripts that have specified a
+ * version...
+ */
+ version = cx.getLanguageVersion();
+ return (version == Context.VERSION_1_0
+ || version == Context.VERSION_1_1
+ || version == Context.VERSION_1_2);
+
+ case Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME:
+ return false;
+
+ case Context.FEATURE_RESERVED_KEYWORD_AS_IDENTIFIER:
+ return false;
+
+ case Context.FEATURE_TO_STRING_AS_SOURCE:
+ version = cx.getLanguageVersion();
+ return version == Context.VERSION_1_2;
+
+ case Context.FEATURE_PARENT_PROTO_PROPERTIES:
+ return true;
+
+ case Context.FEATURE_E4X:
+ version = cx.getLanguageVersion();
+ return (version == Context.VERSION_DEFAULT
+ || version >= Context.VERSION_1_6);
+
+ case Context.FEATURE_DYNAMIC_SCOPE:
+ return false;
+
+ case Context.FEATURE_STRICT_VARS:
+ return false;
+
+ case Context.FEATURE_STRICT_EVAL:
+ return false;
+
+ case Context.FEATURE_LOCATION_INFORMATION_IN_ERROR:
+ return false;
+
+ case Context.FEATURE_STRICT_MODE:
+ return false;
+
+ case Context.FEATURE_WARNING_AS_ERROR:
+ return false;
+
+ case Context.FEATURE_ENHANCED_JAVA_ACCESS:
+ return false;
+ }
+ // It is a bug to call the method with unknown featureIndex
+ throw new IllegalArgumentException(String.valueOf(featureIndex));
+ }
+
+ private boolean isDom3Present() {
+ Class nodeClass = Kit.classOrNull("org.w3c.dom.Node");
+ if (nodeClass == null) return false;
+ // Check to see whether DOM3 is present; use a new method defined in
+ // DOM3 that is vital to our implementation
+ try {
+ nodeClass.getMethod("getUserData", new Class[] { String.class });
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Provides a default
+ * {@link org.mozilla.javascript.xml.XMLLib.Factory XMLLib.Factory}
+ * to be used by the <code>Context</code> instances produced by this
+ * factory. See {@link Context#getE4xImplementationFactory} for details.
+ *
+ * May return null, in which case E4X functionality is not supported in
+ * Rhino.
+ *
+ * The default implementation now prefers the DOM3 E4X implementation.
+ */
+ protected org.mozilla.javascript.xml.XMLLib.Factory
+ getE4xImplementationFactory()
+ {
+ // Must provide default implementation, rather than abstract method,
+ // so that past implementors of ContextFactory do not fail at runtime
+ // upon invocation of this method.
+ // Note that the default implementation returns null if we
+ // neither have XMLBeans nor a DOM3 implementation present.
+
+ if (isDom3Present()) {
+ return org.mozilla.javascript.xml.XMLLib.Factory.create(
+ "org.mozilla.javascript.xmlimpl.XMLLibImpl"
+ );
+ } else if (Kit.classOrNull("org.apache.xmlbeans.XmlCursor") != null) {
+ return org.mozilla.javascript.xml.XMLLib.Factory.create(
+ "org.mozilla.javascript.xml.impl.xmlbeans.XMLLibImpl"
+ );
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * Create class loader for generated classes.
+ * This method creates an instance of the default implementation
+ * of {@link GeneratedClassLoader}. Rhino uses this interface to load
+ * generated JVM classes when no {@link SecurityController}
+ * is installed.
+ * Application can override the method to provide custom class loading.
+ */
+ protected GeneratedClassLoader createClassLoader(ClassLoader parent)
+ {
+ return new DefiningClassLoader(parent);
+ }
+
+ /**
+ * Get ClassLoader to use when searching for Java classes.
+ * Unless it was explicitly initialized with
+ * {@link #initApplicationClassLoader(ClassLoader)} the method returns
+ * null to indicate that Thread.getContextClassLoader() should be used.
+ */
+ public final ClassLoader getApplicationClassLoader()
+ {
+ return applicationClassLoader;
+ }
+
+ /**
+ * Set explicit class loader to use when searching for Java classes.
+ *
+ * @see #getApplicationClassLoader()
+ */
+ public final void initApplicationClassLoader(ClassLoader loader)
+ {
+ if (loader == null)
+ throw new IllegalArgumentException("loader is null");
+ if (!Kit.testIfCanLoadRhinoClasses(loader))
+ throw new IllegalArgumentException(
+ "Loader can not resolve Rhino classes");
+
+ if (this.applicationClassLoader != null)
+ throw new IllegalStateException(
+ "applicationClassLoader can only be set once");
+ checkNotSealed();
+
+ this.applicationClassLoader = loader;
+ }
+
+ /**
+ * Execute top call to script or function.
+ * When the runtime is about to execute a script or function that will
+ * create the first stack frame with scriptable code, it calls this method
+ * to perform the real call. In this way execution of any script
+ * happens inside this function.
+ */
+ protected Object doTopCall(Callable callable,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ return callable.call(cx, scope, thisObj, args);
+ }
+
+ /**
+ * Implementation of
+ * {@link Context#observeInstructionCount(int instructionCount)}.
+ * This can be used to customize {@link Context} without introducing
+ * additional subclasses.
+ */
+ protected void observeInstructionCount(Context cx, int instructionCount)
+ {
+ }
+
+ protected void onContextCreated(Context cx)
+ {
+ Object listeners = this.listeners;
+ for (int i = 0; ; ++i) {
+ Listener l = (Listener)Kit.getListener(listeners, i);
+ if (l == null)
+ break;
+ l.contextCreated(cx);
+ }
+ }
+
+ protected void onContextReleased(Context cx)
+ {
+ Object listeners = this.listeners;
+ for (int i = 0; ; ++i) {
+ Listener l = (Listener)Kit.getListener(listeners, i);
+ if (l == null)
+ break;
+ l.contextReleased(cx);
+ }
+ }
+
+ public final void addListener(Listener listener)
+ {
+ checkNotSealed();
+ synchronized (listenersLock) {
+ if (disabledListening) {
+ throw new IllegalStateException();
+ }
+ listeners = Kit.addListener(listeners, listener);
+ }
+ }
+
+ public final void removeListener(Listener listener)
+ {
+ checkNotSealed();
+ synchronized (listenersLock) {
+ if (disabledListening) {
+ throw new IllegalStateException();
+ }
+ listeners = Kit.removeListener(listeners, listener);
+ }
+ }
+
+ /**
+ * The method is used only to implement
+ * Context.disableStaticContextListening()
+ */
+ final void disableContextListening()
+ {
+ checkNotSealed();
+ synchronized (listenersLock) {
+ disabledListening = true;
+ listeners = null;
+ }
+ }
+
+ /**
+ * Checks if this is a sealed ContextFactory.
+ * @see #seal()
+ */
+ public final boolean isSealed()
+ {
+ return sealed;
+ }
+
+ /**
+ * Seal this ContextFactory so any attempt to modify it like to add or
+ * remove its listeners will throw an exception.
+ * @see #isSealed()
+ */
+ public final void seal()
+ {
+ checkNotSealed();
+ sealed = true;
+ }
+
+ protected final void checkNotSealed()
+ {
+ if (sealed) throw new IllegalStateException();
+ }
+
+ /**
+ * Call {@link ContextAction#run(Context cx)}
+ * using the {@link Context} instance associated with the current thread.
+ * If no Context is associated with the thread, then
+ * {@link #makeContext()} will be called to construct
+ * new Context instance. The instance will be temporary associated
+ * with the thread during call to {@link ContextAction#run(Context)}.
+ *
+ * @see ContextFactory#call(ContextAction)
+ * @see Context#call(ContextFactory factory, Callable callable,
+ * Scriptable scope, Scriptable thisObj,
+ * Object[] args)
+ */
+ public final Object call(ContextAction action)
+ {
+ return Context.call(this, action);
+ }
+
+ /**
+ * Get a context associated with the current thread, creating one if need
+ * be. The Context stores the execution state of the JavaScript engine, so
+ * it is required that the context be entered before execution may begin.
+ * Once a thread has entered a Context, then getCurrentContext() may be
+ * called to find the context that is associated with the current thread.
+ * <p>
+ * Calling <code>enterContext()</code> will return either the Context
+ * currently associated with the thread, or will create a new context and
+ * associate it with the current thread. Each call to
+ * <code>enterContext()</code> must have a matching call to
+ * {@link Context#exit()}.
+ * <pre>
+ * Context cx = contextFactory.enterContext();
+ * try {
+ * ...
+ * cx.evaluateString(...);
+ * } finally {
+ * Context.exit();
+ * }
+ * </pre>
+ * Instead of using <tt>enterContext()</tt>, <tt>exit()</tt> pair consider
+ * using {@link #call(ContextAction)} which guarantees proper association
+ * of Context instances with the current thread.
+ * With this method the above example becomes:
+ * <pre>
+ * ContextFactory.call(new ContextAction() {
+ * public Object run(Context cx) {
+ * ...
+ * cx.evaluateString(...);
+ * return null;
+ * }
+ * });
+ * </pre>
+ * @return a Context associated with the current thread
+ * @see Context#getCurrentContext()
+ * @see Context#exit()
+ * @see #call(ContextAction)
+ */
+ public Context enterContext()
+ {
+ return enterContext(null);
+ }
+
+ /**
+ * @deprecated use {@link #enterContext()} instead
+ * @return a Context associated with the current thread
+ */
+ public final Context enter()
+ {
+ return enterContext(null);
+ }
+
+ /**
+ * @deprecated Use {@link Context#exit()} instead.
+ */
+ public final void exit()
+ {
+ Context.exit();
+ }
+
+ /**
+ * Get a Context associated with the current thread, using the given
+ * Context if need be.
+ * <p>
+ * The same as <code>enterContext()</code> except that <code>cx</code>
+ * is associated with the current thread and returned if the current thread
+ * has no associated context and <code>cx</code> is not associated with any
+ * other thread.
+ * @param cx a Context to associate with the thread if possible
+ * @return a Context associated with the current thread
+ * @see #enterContext()
+ * @see #call(ContextAction)
+ * @throws IllegalStateException if <code>cx</code> is already associated
+ * with a different thread
+ */
+ public final Context enterContext(Context cx)
+ {
+ return Context.enter(cx, this);
+ }
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java
new file mode 100644
index 0000000..5e17145
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ContextListener.java
@@ -0,0 +1,60 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * @deprecated Embeddings that wish to customize newly created
+ * {@link Context} instances should implement
+ * {@link ContextFactory.Listener}.
+ */
+public interface ContextListener extends ContextFactory.Listener
+{
+
+ /**
+ * @deprecated Rhino runtime never calls the method.
+ */
+ public void contextEntered(Context cx);
+
+ /**
+ * @deprecated Rhino runtime never calls the method.
+ */
+ public void contextExited(Context cx);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java
new file mode 100644
index 0000000..ad2a68a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DToA.java
@@ -0,0 +1,1271 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Waldemar Horwat
+ * Roger Lawrence
+ * Attila Szegedi
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+package org.mozilla.javascript;
+
+import java.math.BigInteger;
+
+class DToA {
+
+
+/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
+ * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of
+ * the output string and malloc fewer bytes depending on d and base, but why bother? */
+
+ private static final int DTOBASESTR_BUFFER_SIZE = 1078;
+
+ private static char BASEDIGIT(int digit) {
+ return (char)((digit >= 10) ? 'a' - 10 + digit : '0' + digit);
+ }
+
+ static final int
+ DTOSTR_STANDARD = 0, /* Either fixed or exponential format; round-trip */
+ DTOSTR_STANDARD_EXPONENTIAL = 1, /* Always exponential format; round-trip */
+ DTOSTR_FIXED = 2, /* Round to <precision> digits after the decimal point; exponential if number is large */
+ DTOSTR_EXPONENTIAL = 3, /* Always exponential format; <precision> significant digits */
+ DTOSTR_PRECISION = 4; /* Either fixed or exponential format; <precision> significant digits */
+
+
+ private static final int Frac_mask = 0xfffff;
+ private static final int Exp_shift = 20;
+ private static final int Exp_msk1 = 0x100000;
+
+ private static final long Frac_maskL = 0xfffffffffffffL;
+ private static final int Exp_shiftL = 52;
+ private static final long Exp_msk1L = 0x10000000000000L;
+
+ private static final int Bias = 1023;
+ private static final int P = 53;
+
+ private static final int Exp_shift1 = 20;
+ private static final int Exp_mask = 0x7ff00000;
+ private static final int Exp_mask_shifted = 0x7ff;
+ private static final int Bndry_mask = 0xfffff;
+ private static final int Log2P = 1;
+
+ private static final int Sign_bit = 0x80000000;
+ private static final int Exp_11 = 0x3ff00000;
+ private static final int Ten_pmax = 22;
+ private static final int Quick_max = 14;
+ private static final int Bletch = 0x10;
+ private static final int Frac_mask1 = 0xfffff;
+ private static final int Int_max = 14;
+ private static final int n_bigtens = 5;
+
+
+ private static final double tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+ };
+
+ private static final double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+
+ private static int lo0bits(int y)
+ {
+ int k;
+ int x = y;
+
+ if ((x & 7) != 0) {
+ if ((x & 1) != 0)
+ return 0;
+ if ((x & 2) != 0) {
+ return 1;
+ }
+ return 2;
+ }
+ k = 0;
+ if ((x & 0xffff) == 0) {
+ k = 16;
+ x >>>= 16;
+ }
+ if ((x & 0xff) == 0) {
+ k += 8;
+ x >>>= 8;
+ }
+ if ((x & 0xf) == 0) {
+ k += 4;
+ x >>>= 4;
+ }
+ if ((x & 0x3) == 0) {
+ k += 2;
+ x >>>= 2;
+ }
+ if ((x & 1) == 0) {
+ k++;
+ x >>>= 1;
+ if ((x & 1) == 0)
+ return 32;
+ }
+ return k;
+ }
+
+ /* Return the number (0 through 32) of most significant zero bits in x. */
+ private static int hi0bits(int x)
+ {
+ int k = 0;
+
+ if ((x & 0xffff0000) == 0) {
+ k = 16;
+ x <<= 16;
+ }
+ if ((x & 0xff000000) == 0) {
+ k += 8;
+ x <<= 8;
+ }
+ if ((x & 0xf0000000) == 0) {
+ k += 4;
+ x <<= 4;
+ }
+ if ((x & 0xc0000000) == 0) {
+ k += 2;
+ x <<= 2;
+ }
+ if ((x & 0x80000000) == 0) {
+ k++;
+ if ((x & 0x40000000) == 0)
+ return 32;
+ }
+ return k;
+ }
+
+ private static void stuffBits(byte bits[], int offset, int val)
+ {
+ bits[offset] = (byte)(val >> 24);
+ bits[offset + 1] = (byte)(val >> 16);
+ bits[offset + 2] = (byte)(val >> 8);
+ bits[offset + 3] = (byte)(val);
+ }
+
+ /* Convert d into the form b*2^e, where b is an odd integer. b is the returned
+ * Bigint and e is the returned binary exponent. Return the number of significant
+ * bits in b in bits. d must be finite and nonzero. */
+ private static BigInteger d2b(double d, int[] e, int[] bits)
+ {
+ byte dbl_bits[];
+ int i, k, y, z, de;
+ long dBits = Double.doubleToLongBits(d);
+ int d0 = (int)(dBits >>> 32);
+ int d1 = (int)(dBits);
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+
+ if ((de = (d0 >>> Exp_shift)) != 0)
+ z |= Exp_msk1;
+
+ if ((y = d1) != 0) {
+ dbl_bits = new byte[8];
+ k = lo0bits(y);
+ y >>>= k;
+ if (k != 0) {
+ stuffBits(dbl_bits, 4, y | z << (32 - k));
+ z >>= k;
+ }
+ else
+ stuffBits(dbl_bits, 4, y);
+ stuffBits(dbl_bits, 0, z);
+ i = (z != 0) ? 2 : 1;
+ }
+ else {
+ // JS_ASSERT(z);
+ dbl_bits = new byte[4];
+ k = lo0bits(z);
+ z >>>= k;
+ stuffBits(dbl_bits, 0, z);
+ k += 32;
+ i = 1;
+ }
+ if (de != 0) {
+ e[0] = de - Bias - (P-1) + k;
+ bits[0] = P - k;
+ }
+ else {
+ e[0] = de - Bias - (P-1) + 1 + k;
+ bits[0] = 32*i - hi0bits(z);
+ }
+ return new BigInteger(dbl_bits);
+ }
+
+ static String JS_dtobasestr(int base, double d)
+ {
+ if (!(2 <= base && base <= 36))
+ throw new IllegalArgumentException("Bad base: "+base);
+
+ /* Check for Infinity and NaN */
+ if (Double.isNaN(d)) {
+ return "NaN";
+ } else if (Double.isInfinite(d)) {
+ return (d > 0.0) ? "Infinity" : "-Infinity";
+ } else if (d == 0) {
+ // ALERT: should it distinguish -0.0 from +0.0 ?
+ return "0";
+ }
+
+ boolean negative;
+ if (d >= 0.0) {
+ negative = false;
+ } else {
+ negative = true;
+ d = -d;
+ }
+
+ /* Get the integer part of d including '-' sign. */
+ String intDigits;
+
+ double dfloor = Math.floor(d);
+ long lfloor = (long)dfloor;
+ if (lfloor == dfloor) {
+ // int part fits long
+ intDigits = Long.toString((negative) ? -lfloor : lfloor, base);
+ } else {
+ // BigInteger should be used
+ long floorBits = Double.doubleToLongBits(dfloor);
+ int exp = (int)(floorBits >> Exp_shiftL) & Exp_mask_shifted;
+ long mantissa;
+ if (exp == 0) {
+ mantissa = (floorBits & Frac_maskL) << 1;
+ } else {
+ mantissa = (floorBits & Frac_maskL) | Exp_msk1L;
+ }
+ if (negative) {
+ mantissa = -mantissa;
+ }
+ exp -= 1075;
+ BigInteger x = BigInteger.valueOf(mantissa);
+ if (exp > 0) {
+ x = x.shiftLeft(exp);
+ } else if (exp < 0) {
+ x = x.shiftRight(-exp);
+ }
+ intDigits = x.toString(base);
+ }
+
+ if (d == dfloor) {
+ // No fraction part
+ return intDigits;
+ } else {
+ /* We have a fraction. */
+
+ char[] buffer; /* The output string */
+ int p; /* index to current position in the buffer */
+ int digit;
+ double df; /* The fractional part of d */
+ BigInteger b;
+
+ buffer = new char[DTOBASESTR_BUFFER_SIZE];
+ p = 0;
+ df = d - dfloor;
+
+ long dBits = Double.doubleToLongBits(d);
+ int word0 = (int)(dBits >> 32);
+ int word1 = (int)(dBits);
+
+ int[] e = new int[1];
+ int[] bbits = new int[1];
+
+ b = d2b(df, e, bbits);
+// JS_ASSERT(e < 0);
+ /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */
+
+ int s2 = -(word0 >>> Exp_shift1 & Exp_mask >> Exp_shift1);
+ if (s2 == 0)
+ s2 = -1;
+ s2 += Bias + P;
+ /* 1/2^s2 = (nextDouble(d) - d)/2 */
+// JS_ASSERT(-s2 < e);
+ BigInteger mlo = BigInteger.valueOf(1);
+ BigInteger mhi = mlo;
+ if ((word1 == 0) && ((word0 & Bndry_mask) == 0)
+ && ((word0 & (Exp_mask & Exp_mask << 1)) != 0)) {
+ /* The special case. Here we want to be within a quarter of the last input
+ significant digit instead of one half of it when the output string's value is less than d. */
+ s2 += Log2P;
+ mhi = BigInteger.valueOf(1<<Log2P);
+ }
+
+ b = b.shiftLeft(e[0] + s2);
+ BigInteger s = BigInteger.valueOf(1);
+ s = s.shiftLeft(s2);
+ /* At this point we have the following:
+ * s = 2^s2;
+ * 1 > df = b/2^s2 > 0;
+ * (d - prevDouble(d))/2 = mlo/2^s2;
+ * (nextDouble(d) - d)/2 = mhi/2^s2. */
+ BigInteger bigBase = BigInteger.valueOf(base);
+
+ boolean done = false;
+ do {
+ b = b.multiply(bigBase);
+ BigInteger[] divResult = b.divideAndRemainder(s);
+ b = divResult[1];
+ digit = (char)(divResult[0].intValue());
+ if (mlo == mhi)
+ mlo = mhi = mlo.multiply(bigBase);
+ else {
+ mlo = mlo.multiply(bigBase);
+ mhi = mhi.multiply(bigBase);
+ }
+
+ /* Do we yet have the shortest string that will round to d? */
+ int j = b.compareTo(mlo);
+ /* j is b/2^s2 compared with mlo/2^s2. */
+ BigInteger delta = s.subtract(mhi);
+ int j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
+ /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
+ if (j1 == 0 && ((word1 & 1) == 0)) {
+ if (j > 0)
+ digit++;
+ done = true;
+ } else
+ if (j < 0 || (j == 0 && ((word1 & 1) == 0))) {
+ if (j1 > 0) {
+ /* Either dig or dig+1 would work here as the least significant digit.
+ Use whichever would produce an output value closer to d. */
+ b = b.shiftLeft(1);
+ j1 = b.compareTo(s);
+ if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
+ * such as 3.5 in base 3. */
+ digit++;
+ }
+ done = true;
+ } else if (j1 > 0) {
+ digit++;
+ done = true;
+ }
+// JS_ASSERT(digit < (uint32)base);
+ buffer[p++] = BASEDIGIT(digit);
+ } while (!done);
+
+ StringBuffer sb = new StringBuffer(intDigits.length() + 1 + p);
+ sb.append(intDigits);
+ sb.append('.');
+ sb.append(buffer, 0, p);
+ return sb.toString();
+ }
+
+ }
+
+ /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+ static int word0(double d)
+ {
+ long dBits = Double.doubleToLongBits(d);
+ return (int)(dBits >> 32);
+ }
+
+ static double setWord0(double d, int i)
+ {
+ long dBits = Double.doubleToLongBits(d);
+ dBits = ((long)i << 32) | (dBits & 0x0FFFFFFFFL);
+ return Double.longBitsToDouble(dBits);
+ }
+
+ static int word1(double d)
+ {
+ long dBits = Double.doubleToLongBits(d);
+ return (int)(dBits);
+ }
+
+ /* Return b * 5^k. k must be nonnegative. */
+ // XXXX the C version built a cache of these
+ static BigInteger pow5mult(BigInteger b, int k)
+ {
+ return b.multiply(BigInteger.valueOf(5).pow(k));
+ }
+
+ static boolean roundOff(StringBuffer buf)
+ {
+ int i = buf.length();
+ while (i != 0) {
+ --i;
+ char c = buf.charAt(i);
+ if (c != '9') {
+ buf.setCharAt(i, (char)(c + 1));
+ buf.setLength(i + 1);
+ return false;
+ }
+ }
+ buf.setLength(0);
+ return true;
+ }
+
+ /* Always emits at least one digit. */
+ /* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
+ * when the number is exactly halfway between two representable values. For example,
+ * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
+ * 2.49 will still round to 2, and 2.51 will still round to 3. */
+ /* bufsize should be at least 20 for modes 0 and 1. For the other modes,
+ * bufsize should be two greater than the maximum number of output characters expected. */
+ static int
+ JS_dtoa(double d, int mode, boolean biasUp, int ndigits,
+ boolean[] sign, StringBuffer buf)
+ {
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int b2, b5, i, ieps, ilim, ilim0, ilim1,
+ j, j1, k, k0, m2, m5, s2, s5;
+ char dig;
+ long L;
+ long x;
+ BigInteger b, b1, delta, mlo, mhi, S;
+ int[] be = new int[1];
+ int[] bbits = new int[1];
+ double d2, ds, eps;
+ boolean spec_case, denorm, k_check, try_quick, leftright;
+
+ if ((word0(d) & Sign_bit) != 0) {
+ /* set sign for everything, including 0's and NaNs */
+ sign[0] = true;
+ // word0(d) &= ~Sign_bit; /* clear sign bit */
+ d = setWord0(d, word0(d) & ~Sign_bit);
+ }
+ else
+ sign[0] = false;
+
+ if ((word0(d) & Exp_mask) == Exp_mask) {
+ /* Infinity or NaN */
+ buf.append(((word1(d) == 0) && ((word0(d) & Frac_mask) == 0)) ? "Infinity" : "NaN");
+ return 9999;
+ }
+ if (d == 0) {
+// no_digits:
+ buf.setLength(0);
+ buf.append('0'); /* copy "0" to buffer */
+ return 1;
+ }
+
+ b = d2b(d, be, bbits);
+ if ((i = (word0(d) >>> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+ d2 = setWord0(d, (word0(d) & Frac_mask1) | Exp_11);
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+ i -= Bias;
+ denorm = false;
+ }
+ else {
+ /* d is denormalized */
+ i = bbits[0] + be[0] + (Bias + (P-1) - 1);
+ x = (i > 32) ? word0(d) << (64 - i) | word1(d) >>> (i - 32) : word1(d) << (32 - i);
+// d2 = x;
+// word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ d2 = setWord0(x, word0(x) - 31*Exp_msk1);
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = true;
+ }
+ /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0.0 && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = true;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = false;
+ }
+ /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
+ If k_check is zero, we're guaranteed that k = floor(log10(d)). */
+ j = bbits[0] - i - 1;
+ /* At this point d = b/2^j, where b is an odd integer. */
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
+ b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = true;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = false;
+ }
+ leftright = true;
+ ilim = ilim1 = 0;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = false;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = false;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
+ /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
+ when it turns out that k was computed too high by one. */
+
+ boolean fast_failed = false;
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if ((j & Bletch) != 0) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; (j != 0); j >>= 1, i++)
+ if ((j & 1) != 0) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k) != 0) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; (j != 0); j >>= 1, i++)
+ if ((j & 1) != 0) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ /* Check that k was computed correctly. */
+ if (k_check && d < 1.0 && ilim > 0) {
+ if (ilim1 <= 0)
+ fast_failed = true;
+ else {
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ }
+ /* eps bounds the cumulative error. */
+// eps = ieps*d + 7.0;
+// word0(eps) -= (P-1)*Exp_msk1;
+ eps = ieps*d + 7.0;
+ eps = setWord0(eps, word0(eps) - (P-1)*Exp_msk1);
+ if (ilim == 0) {
+ S = mhi = null;
+ d -= 5.0;
+ if (d > eps) {
+ buf.append('1');
+ k++;
+ return k + 1;
+ }
+ if (d < -eps) {
+ buf.setLength(0);
+ buf.append('0'); /* copy "0" to buffer */
+ return 1;
+ }
+ fast_failed = true;
+ }
+ if (!fast_failed) {
+ fast_failed = true;
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = (long)d;
+ d -= L;
+ buf.append((char)('0' + L));
+ if (d < eps) {
+ return k + 1;
+ }
+ if (1.0 - d < eps) {
+// goto bump_up;
+ char lastCh;
+ while (true) {
+ lastCh = buf.charAt(buf.length() - 1);
+ buf.setLength(buf.length() - 1);
+ if (lastCh != '9') break;
+ if (buf.length() == 0) {
+ k++;
+ lastCh = '0';
+ break;
+ }
+ }
+ buf.append((char)(lastCh + 1));
+ return k + 1;
+ }
+ if (++i >= ilim)
+ break;
+ eps *= 10.0;
+ d *= 10.0;
+ }
+ }
+ else {
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.0) {
+ L = (long)d;
+ d -= L;
+ buf.append((char)('0' + L));
+ if (i == ilim) {
+ if (d > 0.5 + eps) {
+// goto bump_up;
+ char lastCh;
+ while (true) {
+ lastCh = buf.charAt(buf.length() - 1);
+ buf.setLength(buf.length() - 1);
+ if (lastCh != '9') break;
+ if (buf.length() == 0) {
+ k++;
+ lastCh = '0';
+ break;
+ }
+ }
+ buf.append((char)(lastCh + 1));
+ return k + 1;
+ }
+ else
+ if (d < 0.5 - eps) {
+ stripTrailingZeroes(buf);
+// while(*--s == '0') ;
+// s++;
+ return k + 1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (fast_failed) {
+ buf.setLength(0);
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be[0] >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = null;
+ if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) {
+ buf.setLength(0);
+ buf.append('0'); /* copy "0" to buffer */
+ return 1;
+ }
+ buf.append('1');
+ k++;
+ return k + 1;
+ }
+ for(i = 1;; i++) {
+ L = (long) (d / ds);
+ d -= L*ds;
+ buf.append((char)('0' + L));
+ if (i == ilim) {
+ d += d;
+ if ((d > ds) || (d == ds && (((L & 1) != 0) || biasUp))) {
+// bump_up:
+// while(*--s == '9')
+// if (s == buf) {
+// k++;
+// *s = '0';
+// break;
+// }
+// ++*s++;
+ char lastCh;
+ while (true) {
+ lastCh = buf.charAt(buf.length() - 1);
+ buf.setLength(buf.length() - 1);
+ if (lastCh != '9') break;
+ if (buf.length() == 0) {
+ k++;
+ lastCh = '0';
+ break;
+ }
+ }
+ buf.append((char)(lastCh + 1));
+ }
+ break;
+ }
+ d *= 10.0;
+ if (d == 0)
+ break;
+ }
+ return k + 1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = null;
+ if (leftright) {
+ if (mode < 2) {
+ i = (denorm) ? be[0] + (Bias + (P-1) - 1 + 1) : 1 + P - bbits[0];
+ /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
+ (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
+ }
+ b2 += i;
+ s2 += i;
+ mhi = BigInteger.valueOf(1);
+ /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
+ input (when mode < 2) significant digit, divided by 10^k. */
+ }
+ /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
+ b2, m2, and s2 without changing the equalities. */
+ if (m2 > 0 && s2 > 0) {
+ i = (m2 < s2) ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+
+ /* Fold b5 into b and m5 into mhi. */
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mhi.multiply(b);
+ b = b1;
+ }
+ if ((j = b5 - m5) != 0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
+ (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
+
+ S = BigInteger.valueOf(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+ /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
+ (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
+
+ /* Check for special case that d is a normalized power of 2. */
+ spec_case = false;
+ if (mode < 2) {
+ if ( (word1(d) == 0) && ((word0(d) & Bndry_mask) == 0)
+ && ((word0(d) & (Exp_mask & Exp_mask << 1)) != 0)
+ ) {
+ /* The special case. Here we want to be within a quarter of the last input
+ significant digit instead of one half of it when the decimal output string's value is less than d. */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = true;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+ byte [] S_bytes = S.toByteArray();
+ int S_hiWord = 0;
+ for (int idx = 0; idx < 4; idx++) {
+ S_hiWord = (S_hiWord << 8);
+ if (idx < S_bytes.length)
+ S_hiWord |= (S_bytes[idx] & 0xFF);
+ }
+ if ((i = (((s5 != 0) ? 32 - hi0bits(S_hiWord) : 1) + s2) & 0x1f) != 0)
+ i = 32 - i;
+ /* i is the number of leading zero bits in the most significant word of S*2^s2. */
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
+ if (b2 > 0)
+ b = b.shiftLeft(b2);
+ if (s2 > 0)
+ S = S.shiftLeft(s2);
+ /* Now we have d/10^k = b/S and
+ (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
+ if (k_check) {
+ if (b.compareTo(S) < 0) {
+ k--;
+ b = b.multiply(BigInteger.valueOf(10)); /* we botched the k estimate */
+ if (leftright)
+ mhi = mhi.multiply(BigInteger.valueOf(10));
+ ilim = ilim1;
+ }
+ }
+ /* At this point 1 <= d/10^k = b/S < 10. */
+
+ if (ilim <= 0 && mode > 2) {
+ /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
+ Output either zero or the minimum nonzero output depending on which is closer to d. */
+ if ((ilim < 0 )
+ || ((i = b.compareTo(S = S.multiply(BigInteger.valueOf(5)))) < 0)
+ || ((i == 0 && !biasUp))) {
+ /* Always emit at least one digit. If the number appears to be zero
+ using the current mode, then emit one '0' digit and set decpt to 1. */
+ /*no_digits:
+ k = -1 - ndigits;
+ goto ret; */
+ buf.setLength(0);
+ buf.append('0'); /* copy "0" to buffer */
+ return 1;
+// goto no_digits;
+ }
+// one_digit:
+ buf.append('1');
+ k++;
+ return k + 1;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = mhi.shiftLeft(m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = mlo;
+ mhi = mhi.shiftLeft(Log2P);
+ }
+ /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
+ /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
+
+ for(i = 1;;i++) {
+ BigInteger[] divResult = b.divideAndRemainder(S);
+ b = divResult[1];
+ dig = (char)(divResult[0].intValue() + '0');
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = b.compareTo(mlo);
+ /* j is b/S compared with mlo/S. */
+ delta = S.subtract(mhi);
+ j1 = (delta.signum() <= 0) ? 1 : b.compareTo(delta);
+ /* j1 is b/S compared with 1 - mhi/S. */
+ if ((j1 == 0) && (mode == 0) && ((word1(d) & 1) == 0)) {
+ if (dig == '9') {
+ buf.append('9');
+ if (roundOff(buf)) {
+ k++;
+ buf.append('1');
+ }
+ return k + 1;
+// goto round_9_up;
+ }
+ if (j > 0)
+ dig++;
+ buf.append(dig);
+ return k + 1;
+ }
+ if ((j < 0)
+ || ((j == 0)
+ && (mode == 0)
+ && ((word1(d) & 1) == 0)
+ )) {
+ if (j1 > 0) {
+ /* Either dig or dig+1 would work here as the least significant decimal digit.
+ Use whichever would produce a decimal value closer to d. */
+ b = b.shiftLeft(1);
+ j1 = b.compareTo(S);
+ if (((j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp)))
+ && (dig++ == '9')) {
+ buf.append('9');
+ if (roundOff(buf)) {
+ k++;
+ buf.append('1');
+ }
+ return k + 1;
+// goto round_9_up;
+ }
+ }
+ buf.append(dig);
+ return k + 1;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+// round_9_up:
+// *s++ = '9';
+// goto roundoff;
+ buf.append('9');
+ if (roundOff(buf)) {
+ k++;
+ buf.append('1');
+ }
+ return k + 1;
+ }
+ buf.append((char)(dig + 1));
+ return k + 1;
+ }
+ buf.append(dig);
+ if (i == ilim)
+ break;
+ b = b.multiply(BigInteger.valueOf(10));
+ if (mlo == mhi)
+ mlo = mhi = mhi.multiply(BigInteger.valueOf(10));
+ else {
+ mlo = mlo.multiply(BigInteger.valueOf(10));
+ mhi = mhi.multiply(BigInteger.valueOf(10));
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+// (char)(dig = quorem(b,S) + '0');
+ BigInteger[] divResult = b.divideAndRemainder(S);
+ b = divResult[1];
+ dig = (char)(divResult[0].intValue() + '0');
+ buf.append(dig);
+ if (i >= ilim)
+ break;
+ b = b.multiply(BigInteger.valueOf(10));
+ }
+
+ /* Round off last digit */
+
+ b = b.shiftLeft(1);
+ j = b.compareTo(S);
+ if ((j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp))) {
+// roundoff:
+// while(*--s == '9')
+// if (s == buf) {
+// k++;
+// *s++ = '1';
+// goto ret;
+// }
+// ++*s++;
+ if (roundOff(buf)) {
+ k++;
+ buf.append('1');
+ return k + 1;
+ }
+ }
+ else {
+ stripTrailingZeroes(buf);
+// while(*--s == '0') ;
+// s++;
+ }
+// ret:
+// Bfree(S);
+// if (mhi) {
+// if (mlo && mlo != mhi)
+// Bfree(mlo);
+// Bfree(mhi);
+// }
+// ret1:
+// Bfree(b);
+// JS_ASSERT(s < buf + bufsize);
+ return k + 1;
+ }
+
+ private static void
+ stripTrailingZeroes(StringBuffer buf)
+ {
+// while(*--s == '0') ;
+// s++;
+ int bl = buf.length();
+ while(bl-->0 && buf.charAt(bl) == '0') {
+ // empty
+ }
+ buf.setLength(bl + 1);
+ }
+
+ /* Mapping of JSDToStrMode -> JS_dtoa mode */
+ private static final int dtoaModes[] = {
+ 0, /* DTOSTR_STANDARD */
+ 0, /* DTOSTR_STANDARD_EXPONENTIAL, */
+ 3, /* DTOSTR_FIXED, */
+ 2, /* DTOSTR_EXPONENTIAL, */
+ 2}; /* DTOSTR_PRECISION */
+
+ static void
+ JS_dtostr(StringBuffer buffer, int mode, int precision, double d)
+ {
+ int decPt; /* Position of decimal point relative to first digit returned by JS_dtoa */
+ boolean[] sign = new boolean[1]; /* true if the sign bit was set in d */
+ int nDigits; /* Number of significand digits returned by JS_dtoa */
+
+// JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
+// DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
+
+ if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
+ mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
+
+ decPt = JS_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, sign, buffer);
+ nDigits = buffer.length();
+
+ /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
+ if (decPt != 9999) {
+ boolean exponentialNotation = false;
+ int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */
+ int p;
+
+ switch (mode) {
+ case DTOSTR_STANDARD:
+ if (decPt < -5 || decPt > 21)
+ exponentialNotation = true;
+ else
+ minNDigits = decPt;
+ break;
+
+ case DTOSTR_FIXED:
+ if (precision >= 0)
+ minNDigits = decPt + precision;
+ else
+ minNDigits = decPt;
+ break;
+
+ case DTOSTR_EXPONENTIAL:
+// JS_ASSERT(precision > 0);
+ minNDigits = precision;
+ /* Fall through */
+ case DTOSTR_STANDARD_EXPONENTIAL:
+ exponentialNotation = true;
+ break;
+
+ case DTOSTR_PRECISION:
+// JS_ASSERT(precision > 0);
+ minNDigits = precision;
+ if (decPt < -5 || decPt > precision)
+ exponentialNotation = true;
+ break;
+ }
+
+ /* If the number has fewer than minNDigits, pad it with zeros at the end */
+ if (nDigits < minNDigits) {
+ p = minNDigits;
+ nDigits = minNDigits;
+ do {
+ buffer.append('0');
+ } while (buffer.length() != p);
+ }
+
+ if (exponentialNotation) {
+ /* Insert a decimal point if more than one significand digit */
+ if (nDigits != 1) {
+ buffer.insert(1, '.');
+ }
+ buffer.append('e');
+ if ((decPt - 1) >= 0)
+ buffer.append('+');
+ buffer.append(decPt - 1);
+// JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
+ } else if (decPt != nDigits) {
+ /* Some kind of a fraction in fixed notation */
+// JS_ASSERT(decPt <= nDigits);
+ if (decPt > 0) {
+ /* dd...dd . dd...dd */
+ buffer.insert(decPt, '.');
+ } else {
+ /* 0 . 00...00dd...dd */
+ for (int i = 0; i < 1 - decPt; i++)
+ buffer.insert(0, '0');
+ buffer.insert(1, '.');
+ }
+ }
+ }
+
+ /* If negative and neither -0.0 nor NaN, output a leading '-'. */
+ if (sign[0] &&
+ !(word0(d) == Sign_bit && word1(d) == 0) &&
+ !((word0(d) & Exp_mask) == Exp_mask &&
+ ((word1(d) != 0) || ((word0(d) & Frac_mask) != 0)))) {
+ buffer.insert(0, '-');
+ }
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java
new file mode 100644
index 0000000..8547d37
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Decompiler.java
@@ -0,0 +1,918 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.LET:
+ result.append("let ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.YIELD:
+ result.append("yield ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java
new file mode 100644
index 0000000..c7d93d4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefaultErrorReporter.java
@@ -0,0 +1,113 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This is the default error reporter for JavaScript.
+ *
+ * @author Norris Boyd
+ */
+class DefaultErrorReporter implements ErrorReporter
+{
+ static final DefaultErrorReporter instance = new DefaultErrorReporter();
+
+ private boolean forEval;
+ private ErrorReporter chainedReporter;
+
+ private DefaultErrorReporter() { }
+
+ static ErrorReporter forEval(ErrorReporter reporter)
+ {
+ DefaultErrorReporter r = new DefaultErrorReporter();
+ r.forEval = true;
+ r.chainedReporter = reporter;
+ return r;
+ }
+
+ public void warning(String message, String sourceURI, int line,
+ String lineText, int lineOffset)
+ {
+ if (chainedReporter != null) {
+ chainedReporter.warning(
+ message, sourceURI, line, lineText, lineOffset);
+ } else {
+ // Do nothing
+ }
+ }
+
+ public void error(String message, String sourceURI, int line,
+ String lineText, int lineOffset)
+ {
+ if (forEval) {
+ // Assume error message strings that start with "TypeError: "
+ // should become TypeError exceptions. A bit of a hack, but we
+ // don't want to change the ErrorReporter interface.
+ String error = "SyntaxError";
+ final String TYPE_ERROR_NAME = "TypeError";
+ final String DELIMETER = ": ";
+ final String prefix = TYPE_ERROR_NAME + DELIMETER;
+ if (message.startsWith(prefix)) {
+ error = TYPE_ERROR_NAME;
+ message = message.substring(prefix.length());
+ }
+ throw ScriptRuntime.constructError(error, message, sourceURI,
+ line, lineText, lineOffset);
+ }
+ if (chainedReporter != null) {
+ chainedReporter.error(
+ message, sourceURI, line, lineText, lineOffset);
+ } else {
+ throw runtimeError(
+ message, sourceURI, line, lineText, lineOffset);
+ }
+ }
+
+ public EvaluatorException runtimeError(String message, String sourceURI,
+ int line, String lineText,
+ int lineOffset)
+ {
+ if (chainedReporter != null) {
+ return chainedReporter.runtimeError(
+ message, sourceURI, line, lineText, lineOffset);
+ } else {
+ return new EvaluatorException(
+ message, sourceURI, line, lineText, lineOffset);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java
new file mode 100644
index 0000000..5864b5d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/DefiningClassLoader.java
@@ -0,0 +1,88 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ * Patrick Beard
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * Load generated classes.
+ *
+ * @author Norris Boyd
+ */
+public class DefiningClassLoader extends ClassLoader
+ implements GeneratedClassLoader
+{
+ public DefiningClassLoader() {
+ this.parentLoader = getClass().getClassLoader();
+ }
+
+ public DefiningClassLoader(ClassLoader parentLoader) {
+ this.parentLoader = parentLoader;
+ }
+
+ public Class defineClass(String name, byte[] data) {
+ // Use our own protection domain for the generated classes.
+ // TODO: we might want to use a separate protection domain for classes
+ // compiled from scripts, based on where the script was loaded from.
+ return super.defineClass(name, data, 0, data.length,
+ SecurityUtilities.getProtectionDomain(getClass()));
+ }
+
+ public void linkClass(Class cl) {
+ resolveClass(cl);
+ }
+
+ public Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ Class cl = findLoadedClass(name);
+ if (cl == null) {
+ if (parentLoader != null) {
+ cl = parentLoader.loadClass(name);
+ } else {
+ cl = findSystemClass(name);
+ }
+ }
+ if (resolve) {
+ resolveClass(cl);
+ }
+ return cl;
+ }
+
+ private final ClassLoader parentLoader;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java
new file mode 100644
index 0000000..e044863
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Delegator.java
@@ -0,0 +1,266 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Delegator.java, released
+ * Sep 27, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * Matthias Radestock. <matthias@sorted.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This is a helper class for implementing wrappers around Scriptable
+ * objects. It implements the Function interface and delegates all
+ * invocations to a delegee Scriptable object. The normal use of this
+ * class involves creating a sub-class and overriding one or more of
+ * the methods.
+ *
+ * A useful application is the implementation of interceptors,
+ * pre/post conditions, debugging.
+ *
+ * @see Function
+ * @see Scriptable
+ * @author Matthias Radestock
+ */
+
+public class Delegator implements Function {
+
+ protected Scriptable obj = null;
+
+ /**
+ * Create a Delegator prototype.
+ *
+ * This constructor should only be used for creating prototype
+ * objects of Delegator.
+ *
+ * @see org.mozilla.javascript.Delegator#construct
+ */
+ public Delegator() {
+ }
+
+ /**
+ * Create a new Delegator that forwards requests to a delegee
+ * Scriptable object.
+ *
+ * @param obj the delegee
+ * @see org.mozilla.javascript.Scriptable
+ */
+ public Delegator(Scriptable obj) {
+ this.obj = obj;
+ }
+
+ /**
+ * Crete new Delegator instance.
+ * The default implementation calls this.getClass().newInstance().
+ *
+ * @see #construct(Context cx, Scriptable scope, Object[] args)
+ */
+ protected Delegator newInstance()
+ {
+ try {
+ return this.getClass().newInstance();
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+
+ /**
+ * Retrieve the delegee.
+ *
+ * @return the delegee
+ */
+ public Scriptable getDelegee() {
+ return obj;
+ }
+ /**
+ * Set the delegee.
+ *
+ * @param obj the delegee
+ * @see org.mozilla.javascript.Scriptable
+ */
+ public void setDelegee(Scriptable obj) {
+ this.obj = obj;
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#getClassName
+ */
+ public String getClassName() {
+ return obj.getClassName();
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
+ */
+ public Object get(String name, Scriptable start) {
+ return obj.get(name,start);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
+ */
+ public Object get(int index, Scriptable start) {
+ return obj.get(index,start);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
+ */
+ public boolean has(String name, Scriptable start) {
+ return obj.has(name,start);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#has(int, Scriptable)
+ */
+ public boolean has(int index, Scriptable start) {
+ return obj.has(index,start);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
+ */
+ public void put(String name, Scriptable start, Object value) {
+ obj.put(name,start,value);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#put(int, Scriptable, Object)
+ */
+ public void put(int index, Scriptable start, Object value) {
+ obj.put(index,start,value);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#delete(String)
+ */
+ public void delete(String name) {
+ obj.delete(name);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#delete(int)
+ */
+ public void delete(int index) {
+ obj.delete(index);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#getPrototype
+ */
+ public Scriptable getPrototype() {
+ return obj.getPrototype();
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#setPrototype
+ */
+ public void setPrototype(Scriptable prototype) {
+ obj.setPrototype(prototype);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#getParentScope
+ */
+ public Scriptable getParentScope() {
+ return obj.getParentScope();
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#setParentScope
+ */
+ public void setParentScope(Scriptable parent) {
+ obj.setParentScope(parent);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#getIds
+ */
+ public Object[] getIds() {
+ return obj.getIds();
+ }
+ /**
+ * Note that this method does not get forwarded to the delegee if
+ * the <code>hint</code> parameter is null,
+ * <code>ScriptRuntime.ScriptableClass</code> or
+ * <code>ScriptRuntime.FunctionClass</code>. Instead the object
+ * itself is returned.
+ *
+ * @param hint the type hint
+ * @return the default value
+ *
+ * @see org.mozilla.javascript.Scriptable#getDefaultValue
+ */
+ public Object getDefaultValue(Class hint) {
+ return (hint == null ||
+ hint == ScriptRuntime.ScriptableClass ||
+ hint == ScriptRuntime.FunctionClass) ?
+ this : obj.getDefaultValue(hint);
+ }
+ /**
+ * @see org.mozilla.javascript.Scriptable#hasInstance
+ */
+ public boolean hasInstance(Scriptable instance) {
+ return obj.hasInstance(instance);
+ }
+ /**
+ * @see org.mozilla.javascript.Function#call
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return ((Function)obj).call(cx,scope,thisObj,args);
+ }
+
+ /**
+ * Note that if the <code>delegee</code> is <code>null</code>,
+ * this method creates a new instance of the Delegator itself
+ * rathert than forwarding the call to the
+ * <code>delegee</code>. This permits the use of Delegator
+ * prototypes.
+ *
+ * @param cx the current Context for this thread
+ * @param scope an enclosing scope of the caller except
+ * when the function is called from a closure.
+ * @param args the array of arguments
+ * @return the allocated object
+ *
+ * @see Function#construct(Context, Scriptable, Object[])
+ */
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ if (obj == null) {
+ //this little trick allows us to declare prototype objects for
+ //Delegators
+ Delegator n = newInstance();
+ Scriptable delegee;
+ if (args.length == 0) {
+ delegee = new NativeObject();
+ } else {
+ delegee = ScriptRuntime.toObject(cx, scope, args[0]);
+ }
+ n.setDelegee(delegee);
+ return n;
+ }
+ else {
+ return ((Function)obj).construct(cx,scope,args);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java
new file mode 100644
index 0000000..1fd8f03
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EcmaError.java
@@ -0,0 +1,160 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * The class of exceptions raised by the engine as described in
+ * ECMA edition 3. See section 15.11.6 in particular.
+ */
+public class EcmaError extends RhinoException
+{
+ static final long serialVersionUID = -6261226256957286699L;
+
+ private String errorName;
+ private String errorMessage;
+
+ /**
+ * Create an exception with the specified detail message.
+ *
+ * Errors internal to the JavaScript engine will simply throw a
+ * RuntimeException.
+ *
+ * @param sourceName the name of the source reponsible for the error
+ * @param lineNumber the line number of the source
+ * @param columnNumber the columnNumber of the source (may be zero if
+ * unknown)
+ * @param lineSource the source of the line containing the error (may be
+ * null if unknown)
+ */
+ EcmaError(String errorName, String errorMessage,
+ String sourceName, int lineNumber,
+ String lineSource, int columnNumber)
+ {
+ recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
+ this.errorName = errorName;
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * @deprecated EcmaError error instances should not be constructed
+ * explicitly since they are generated by the engine.
+ */
+ public EcmaError(Scriptable nativeError, String sourceName,
+ int lineNumber, int columnNumber, String lineSource)
+ {
+ this("InternalError", ScriptRuntime.toString(nativeError),
+ sourceName, lineNumber, lineSource, columnNumber);
+ }
+
+ public String details()
+ {
+ return errorName+": "+errorMessage;
+ }
+
+ /**
+ * Gets the name of the error.
+ *
+ * ECMA edition 3 defines the following
+ * errors: EvalError, RangeError, ReferenceError,
+ * SyntaxError, TypeError, and URIError. Additional error names
+ * may be added in the future.
+ *
+ * See ECMA edition 3, 15.11.7.9.
+ *
+ * @return the name of the error.
+ */
+ public String getName()
+ {
+ return errorName;
+ }
+
+ /**
+ * Gets the message corresponding to the error.
+ *
+ * See ECMA edition 3, 15.11.7.10.
+ *
+ * @return an implemenation-defined string describing the error.
+ */
+ public String getErrorMessage()
+ {
+ return errorMessage;
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#sourceName()} from the super class.
+ */
+ public String getSourceName()
+ {
+ return sourceName();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber();
+ }
+
+ /**
+ * @deprecated
+ * Use {@link RhinoException#columnNumber()} from the super class.
+ */
+ public int getColumnNumber() {
+ return columnNumber();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#lineSource()} from the super class.
+ */
+ public String getLineSource() {
+ return lineSource();
+ }
+
+ /**
+ * @deprecated
+ * Always returns <b>null</b>.
+ */
+ public Scriptable getErrorObject()
+ {
+ return null;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java
new file mode 100644
index 0000000..4649370
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ErrorReporter.java
@@ -0,0 +1,106 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This is interface defines a protocol for the reporting of
+ * errors during JavaScript translation or execution.
+ *
+ * @author Norris Boyd
+ */
+
+public interface ErrorReporter {
+
+ /**
+ * Report a warning.
+ *
+ * The implementing class may choose to ignore the warning
+ * if it desires.
+ *
+ * @param message a String describing the warning
+ * @param sourceName a String describing the JavaScript source
+ * where the warning occured; typically a filename or URL
+ * @param line the line number associated with the warning
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ */
+ void warning(String message, String sourceName, int line,
+ String lineSource, int lineOffset);
+
+ /**
+ * Report an error.
+ *
+ * The implementing class is free to throw an exception if
+ * it desires.
+ *
+ * If execution has not yet begun, the JavaScript engine is
+ * free to find additional errors rather than terminating
+ * the translation. It will not execute a script that had
+ * errors, however.
+ *
+ * @param message a String describing the error
+ * @param sourceName a String describing the JavaScript source
+ * where the error occured; typically a filename or URL
+ * @param line the line number associated with the error
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ */
+ void error(String message, String sourceName, int line,
+ String lineSource, int lineOffset);
+
+ /**
+ * Creates an EvaluatorException that may be thrown.
+ *
+ * runtimeErrors, unlike errors, will always terminate the
+ * current script.
+ *
+ * @param message a String describing the error
+ * @param sourceName a String describing the JavaScript source
+ * where the error occured; typically a filename or URL
+ * @param line the line number associated with the error
+ * @param lineSource the text of the line (may be null)
+ * @param lineOffset the offset into lineSource where problem was detected
+ * @return an EvaluatorException that will be thrown.
+ */
+ EvaluatorException runtimeError(String message, String sourceName,
+ int line, String lineSource,
+ int lineOffset);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java
new file mode 100644
index 0000000..e222af3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Evaluator.java
@@ -0,0 +1,118 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.List;
+
+/**
+ * Abstraction of evaluation, which can be implemented either by an
+ * interpreter or compiler.
+ */
+public interface Evaluator {
+
+ /**
+ * Compile the script or function from intermediate representation
+ * tree into an executable form.
+ *
+ * @param compilerEnv Compiler environment
+ * @param tree intermediate representation
+ * @param encodedSource encoding of the source code for decompilation
+ * @param returnFunction if true, compiling a function
+ * @return an opaque object that can be passed to either
+ * createFunctionObject or createScriptObject, depending on the
+ * value of returnFunction
+ */
+ public Object compile(CompilerEnvirons compilerEnv,
+ ScriptOrFnNode tree,
+ String encodedSource,
+ boolean returnFunction);
+
+ /**
+ * Create a function object.
+ *
+ * @param cx Current context
+ * @param scope scope of the function
+ * @param bytecode opaque object returned by compile
+ * @param staticSecurityDomain security domain
+ * @return Function object that can be called
+ */
+ public Function createFunctionObject(Context cx, Scriptable scope,
+ Object bytecode, Object staticSecurityDomain);
+
+ /**
+ * Create a script object.
+ *
+ * @param bytecode opaque object returned by compile
+ * @param staticSecurityDomain security domain
+ * @return Script object that can be evaluated
+ */
+ public Script createScriptObject(Object bytecode,
+ Object staticSecurityDomain);
+
+ /**
+ * Capture stack information from the given exception.
+ * @param ex an exception thrown during execution
+ */
+ public void captureStackInfo(RhinoException ex);
+
+ /**
+ * Get the source position information by examining the stack.
+ * @param cx Context
+ * @param linep Array object of length >= 1; getSourcePositionFromStack
+ * will assign the line number to linep[0].
+ * @return the name of the file or other source container
+ */
+ public String getSourcePositionFromStack(Context cx, int[] linep);
+
+ /**
+ * Given a native stack trace, patch it with script-specific source
+ * and line information
+ * @param ex exception
+ * @param nativeStackTrace the native stack trace
+ * @return patched stack trace
+ */
+ public String getPatchedStack(RhinoException ex,
+ String nativeStackTrace);
+
+ /**
+ * Get the script stack for the given exception
+ * @param ex exception from execution
+ * @return list of strings for the stack trace
+ */
+ public List getScriptStack(RhinoException ex);
+
+ /**
+ * Mark the given script to indicate it was created by a call to
+ * eval() or to a Function constructor.
+ * @param script script to mark as from eval
+ */
+ public void setEvalScriptFlag(Script script);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java
new file mode 100644
index 0000000..7b4e7cc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/EvaluatorException.java
@@ -0,0 +1,123 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript;
+
+/**
+ * The class of exceptions thrown by the JavaScript engine.
+ */
+public class EvaluatorException extends RhinoException
+{
+ static final long serialVersionUID = -8743165779676009808L;
+
+ public EvaluatorException(String detail)
+ {
+ super(detail);
+ }
+
+ /**
+ * Create an exception with the specified detail message.
+ *
+ * Errors internal to the JavaScript engine will simply throw a
+ * RuntimeException.
+ *
+ * @param detail the error message
+ * @param sourceName the name of the source reponsible for the error
+ * @param lineNumber the line number of the source
+ */
+ public EvaluatorException(String detail, String sourceName,
+ int lineNumber)
+ {
+ this(detail, sourceName, lineNumber, null, 0);
+ }
+
+ /**
+ * Create an exception with the specified detail message.
+ *
+ * Errors internal to the JavaScript engine will simply throw a
+ * RuntimeException.
+ *
+ * @param detail the error message
+ * @param sourceName the name of the source responsible for the error
+ * @param lineNumber the line number of the source
+ * @param columnNumber the columnNumber of the source (may be zero if
+ * unknown)
+ * @param lineSource the source of the line containing the error (may be
+ * null if unknown)
+ */
+ public EvaluatorException(String detail, String sourceName, int lineNumber,
+ String lineSource, int columnNumber)
+ {
+ super(detail);
+ recordErrorOrigin(sourceName, lineNumber, lineSource, columnNumber);
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#sourceName()} from the super class.
+ */
+ public String getSourceName()
+ {
+ return sourceName();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#columnNumber()} from the super class.
+ */
+ public int getColumnNumber()
+ {
+ return columnNumber();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#lineSource()} from the super class.
+ */
+ public String getLineSource()
+ {
+ return lineSource();
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java
new file mode 100644
index 0000000..a4377e6
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Function.java
@@ -0,0 +1,84 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This is interface that all functions in JavaScript must implement.
+ * The interface provides for calling functions and constructors.
+ *
+ * @see org.mozilla.javascript.Scriptable
+ * @author Norris Boyd
+ */
+
+public interface Function extends Scriptable, Callable
+{
+ /**
+ * Call the function.
+ *
+ * Note that the array of arguments is not guaranteed to have
+ * length greater than 0.
+ *
+ * @param cx the current Context for this thread
+ * @param scope the scope to execute the function relative to. This is
+ * set to the value returned by getParentScope() except
+ * when the function is called from a closure.
+ * @param thisObj the JavaScript <code>this</code> object
+ * @param args the array of arguments
+ * @return the result of the call
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args);
+
+ /**
+ * Call the function as a constructor.
+ *
+ * This method is invoked by the runtime in order to satisfy a use
+ * of the JavaScript <code>new</code> operator. This method is
+ * expected to create a new object and return it.
+ *
+ * @param cx the current Context for this thread
+ * @param scope an enclosing scope of the caller except
+ * when the function is called from a closure.
+ * @param args the array of arguments
+ * @return the allocated object
+ */
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java
new file mode 100644
index 0000000..484167e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionNode.java
@@ -0,0 +1,117 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class FunctionNode extends ScriptOrFnNode {
+
+ public FunctionNode(String name) {
+ super(Token.FUNCTION);
+ functionName = name;
+ }
+
+ public String getFunctionName() {
+ return functionName;
+ }
+
+ public boolean requiresActivation() {
+ return itsNeedsActivation;
+ }
+
+ public boolean getIgnoreDynamicScope() {
+ return itsIgnoreDynamicScope;
+ }
+
+ public boolean isGenerator() {
+ return itsIsGenerator;
+ }
+
+ public void addResumptionPoint(Node target) {
+ if (generatorResumePoints == null)
+ generatorResumePoints = new ArrayList();
+ generatorResumePoints.add(target);
+ }
+
+ public ArrayList getResumptionPoints() {
+ return generatorResumePoints;
+ }
+
+ public HashMap getLiveLocals() {
+ return liveLocals;
+ }
+
+ public void addLiveLocals(Node node, int[] locals) {
+ if (liveLocals == null)
+ liveLocals = new HashMap();
+ liveLocals.put(node, locals);
+ }
+
+ /**
+ * There are three types of functions that can be defined. The first
+ * is a function statement. This is a function appearing as a top-level
+ * statement (i.e., not nested inside some other statement) in either a
+ * script or a function.
+ *
+ * The second is a function expression, which is a function appearing in
+ * an expression except for the third type, which is...
+ *
+ * The third type is a function expression where the expression is the
+ * top-level expression in an expression statement.
+ *
+ * The three types of functions have different treatment and must be
+ * distinguished.
+ */
+ public static final int FUNCTION_STATEMENT = 1;
+ public static final int FUNCTION_EXPRESSION = 2;
+ public static final int FUNCTION_EXPRESSION_STATEMENT = 3;
+
+ public int getFunctionType() {
+ return itsFunctionType;
+ }
+
+ String functionName;
+ int itsFunctionType;
+ boolean itsNeedsActivation;
+ boolean itsIgnoreDynamicScope;
+ boolean itsIsGenerator;
+ ArrayList generatorResumePoints;
+ HashMap liveLocals;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java
new file mode 100644
index 0000000..8fa4e68
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/FunctionObject.java
@@ -0,0 +1,569 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * David C. Navas
+ * Ted Neward
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+import java.io.*;
+
+public class FunctionObject extends BaseFunction
+{
+ static final long serialVersionUID = -5332312783643935019L;
+
+ /**
+ * Create a JavaScript function object from a Java method.
+ *
+ * <p>The <code>member</code> argument must be either a java.lang.reflect.Method
+ * or a java.lang.reflect.Constructor and must match one of two forms.<p>
+ *
+ * The first form is a member with zero or more parameters
+ * of the following types: Object, String, boolean, Scriptable,
+ * int, or double. The Long type is not supported
+ * because the double representation of a long (which is the
+ * EMCA-mandated storage type for Numbers) may lose precision.
+ * If the member is a Method, the return value must be void or one
+ * of the types allowed for parameters.<p>
+ *
+ * The runtime will perform appropriate conversions based
+ * upon the type of the parameter. A parameter type of
+ * Object specifies that no conversions are to be done. A parameter
+ * of type String will use Context.toString to convert arguments.
+ * Similarly, parameters of type double, boolean, and Scriptable
+ * will cause Context.toNumber, Context.toBoolean, and
+ * Context.toObject, respectively, to be called.<p>
+ *
+ * If the method is not static, the Java 'this' value will
+ * correspond to the JavaScript 'this' value. Any attempt
+ * to call the function with a 'this' value that is not
+ * of the right Java type will result in an error.<p>
+ *
+ * The second form is the variable arguments (or "varargs")
+ * form. If the FunctionObject will be used as a constructor,
+ * the member must have the following parameters
+ * <pre>
+ * (Context cx, Object[] args, Function ctorObj,
+ * boolean inNewExpr)</pre>
+ * and if it is a Method, be static and return an Object result.<p>
+ *
+ * Otherwise, if the FunctionObject will <i>not</i> be used to define a
+ * constructor, the member must be a static Method with parameters
+ * (Context cx, Scriptable thisObj, Object[] args,
+ * Function funObj) </pre>
+ * <pre>
+ * and an Object result.<p>
+ *
+ * When the function varargs form is called as part of a function call,
+ * the <code>args</code> parameter contains the
+ * arguments, with <code>thisObj</code>
+ * set to the JavaScript 'this' value. <code>funObj</code>
+ * is the function object for the invoked function.<p>
+ *
+ * When the constructor varargs form is called or invoked while evaluating
+ * a <code>new</code> expression, <code>args</code> contains the
+ * arguments, <code>ctorObj</code> refers to this FunctionObject, and
+ * <code>inNewExpr</code> is true if and only if a <code>new</code>
+ * expression caused the call. This supports defining a function that
+ * has different behavior when called as a constructor than when
+ * invoked as a normal function call. (For example, the Boolean
+ * constructor, when called as a function,
+ * will convert to boolean rather than creating a new object.)<p>
+ *
+ * @param name the name of the function
+ * @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor
+ * that defines the object
+ * @param scope enclosing scope of function
+ * @see org.mozilla.javascript.Scriptable
+ */
+ public FunctionObject(String name, Member methodOrConstructor,
+ Scriptable scope)
+ {
+ if (methodOrConstructor instanceof Constructor) {
+ member = new MemberBox((Constructor) methodOrConstructor);
+ isStatic = true; // well, doesn't take a 'this'
+ } else {
+ member = new MemberBox((Method) methodOrConstructor);
+ isStatic = member.isStatic();
+ }
+ String methodName = member.getName();
+ this.functionName = name;
+ Class[] types = member.argTypes;
+ int arity = types.length;
+ if (arity == 4 && (types[1].isArray() || types[2].isArray())) {
+ // Either variable args or an error.
+ if (types[1].isArray()) {
+ if (!isStatic ||
+ types[0] != ScriptRuntime.ContextClass ||
+ types[1].getComponentType() != ScriptRuntime.ObjectClass ||
+ types[2] != ScriptRuntime.FunctionClass ||
+ types[3] != Boolean.TYPE)
+ {
+ throw Context.reportRuntimeError1(
+ "msg.varargs.ctor", methodName);
+ }
+ parmsLength = VARARGS_CTOR;
+ } else {
+ if (!isStatic ||
+ types[0] != ScriptRuntime.ContextClass ||
+ types[1] != ScriptRuntime.ScriptableClass ||
+ types[2].getComponentType() != ScriptRuntime.ObjectClass ||
+ types[3] != ScriptRuntime.FunctionClass)
+ {
+ throw Context.reportRuntimeError1(
+ "msg.varargs.fun", methodName);
+ }
+ parmsLength = VARARGS_METHOD;
+ }
+ } else {
+ parmsLength = arity;
+ if (arity > 0) {
+ typeTags = new byte[arity];
+ for (int i = 0; i != arity; ++i) {
+ int tag = getTypeTag(types[i]);
+ if (tag == JAVA_UNSUPPORTED_TYPE) {
+ throw Context.reportRuntimeError2(
+ "msg.bad.parms", types[i].getName(), methodName);
+ }
+ typeTags[i] = (byte)tag;
+ }
+ }
+ }
+
+ if (member.isMethod()) {
+ Method method = member.method();
+ Class returnType = method.getReturnType();
+ if (returnType == Void.TYPE) {
+ hasVoidReturn = true;
+ } else {
+ returnTypeTag = getTypeTag(returnType);
+ }
+ } else {
+ Class ctorType = member.getDeclaringClass();
+ if (!ScriptRuntime.ScriptableClass.isAssignableFrom(ctorType)) {
+ throw Context.reportRuntimeError1(
+ "msg.bad.ctor.return", ctorType.getName());
+ }
+ }
+
+ ScriptRuntime.setFunctionProtoAndParent(this, scope);
+ }
+
+ /**
+ * @return One of <tt>JAVA_*_TYPE</tt> constants to indicate desired type
+ * or {@link #JAVA_UNSUPPORTED_TYPE} if the convertion is not
+ * possible
+ */
+ public static int getTypeTag(Class type)
+ {
+ if (type == ScriptRuntime.StringClass)
+ return JAVA_STRING_TYPE;
+ if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE)
+ return JAVA_INT_TYPE;
+ if (type == ScriptRuntime.BooleanClass || type == Boolean.TYPE)
+ return JAVA_BOOLEAN_TYPE;
+ if (type == ScriptRuntime.DoubleClass || type == Double.TYPE)
+ return JAVA_DOUBLE_TYPE;
+ if (ScriptRuntime.ScriptableClass.isAssignableFrom(type))
+ return JAVA_SCRIPTABLE_TYPE;
+ if (type == ScriptRuntime.ObjectClass)
+ return JAVA_OBJECT_TYPE;
+
+ // Note that the long type is not supported; see the javadoc for
+ // the constructor for this class
+
+ return JAVA_UNSUPPORTED_TYPE;
+ }
+
+ public static Object convertArg(Context cx, Scriptable scope,
+ Object arg, int typeTag)
+ {
+ switch (typeTag) {
+ case JAVA_STRING_TYPE:
+ if (arg instanceof String)
+ return arg;
+ return ScriptRuntime.toString(arg);
+ case JAVA_INT_TYPE:
+ if (arg instanceof Integer)
+ return arg;
+ return new Integer(ScriptRuntime.toInt32(arg));
+ case JAVA_BOOLEAN_TYPE:
+ if (arg instanceof Boolean)
+ return arg;
+ return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE
+ : Boolean.FALSE;
+ case JAVA_DOUBLE_TYPE:
+ if (arg instanceof Double)
+ return arg;
+ return new Double(ScriptRuntime.toNumber(arg));
+ case JAVA_SCRIPTABLE_TYPE:
+ if (arg instanceof Scriptable)
+ return arg;
+ return ScriptRuntime.toObject(cx, scope, arg);
+ case JAVA_OBJECT_TYPE:
+ return arg;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Return the value defined by the method used to construct the object
+ * (number of parameters of the method, or 1 if the method is a "varargs"
+ * form).
+ */
+ public int getArity() {
+ return parmsLength < 0 ? 1 : parmsLength;
+ }
+
+ /**
+ * Return the same value as {@link #getArity()}.
+ */
+ public int getLength() {
+ return getArity();
+ }
+
+ public String getFunctionName()
+ {
+ return (functionName == null) ? "" : functionName;
+ }
+
+ /**
+ * Get Java method or constructor this function represent.
+ */
+ public Member getMethodOrConstructor()
+ {
+ if (member.isMethod()) {
+ return member.method();
+ } else {
+ return member.ctor();
+ }
+ }
+
+ static Method findSingleMethod(Method[] methods, String name)
+ {
+ Method found = null;
+ for (int i = 0, N = methods.length; i != N; ++i) {
+ Method method = methods[i];
+ if (method != null && name.equals(method.getName())) {
+ if (found != null) {
+ throw Context.reportRuntimeError2(
+ "msg.no.overload", name,
+ method.getDeclaringClass().getName());
+ }
+ found = method;
+ }
+ }
+ return found;
+ }
+
+ /**
+ * Returns all public methods declared by the specified class. This excludes
+ * inherited methods.
+ *
+ * @param clazz the class from which to pull public declared methods
+ * @return the public methods declared in the specified class
+ * @see Class#getDeclaredMethods()
+ */
+ static Method[] getMethodList(Class clazz) {
+ Method[] methods = null;
+ try {
+ // getDeclaredMethods may be rejected by the security manager
+ // but getMethods is more expensive
+ if (!sawSecurityException)
+ methods = clazz.getDeclaredMethods();
+ } catch (SecurityException e) {
+ // If we get an exception once, give up on getDeclaredMethods
+ sawSecurityException = true;
+ }
+ if (methods == null) {
+ methods = clazz.getMethods();
+ }
+ int count = 0;
+ for (int i=0; i < methods.length; i++) {
+ if (sawSecurityException
+ ? methods[i].getDeclaringClass() != clazz
+ : !Modifier.isPublic(methods[i].getModifiers()))
+ {
+ methods[i] = null;
+ } else {
+ count++;
+ }
+ }
+ Method[] result = new Method[count];
+ int j=0;
+ for (int i=0; i < methods.length; i++) {
+ if (methods[i] != null)
+ result[j++] = methods[i];
+ }
+ return result;
+ }
+
+ /**
+ * Define this function as a JavaScript constructor.
+ * <p>
+ * Sets up the "prototype" and "constructor" properties. Also
+ * calls setParent and setPrototype with appropriate values.
+ * Then adds the function object as a property of the given scope, using
+ * <code>prototype.getClassName()</code>
+ * as the name of the property.
+ *
+ * @param scope the scope in which to define the constructor (typically
+ * the global object)
+ * @param prototype the prototype object
+ * @see org.mozilla.javascript.Scriptable#setParentScope
+ * @see org.mozilla.javascript.Scriptable#setPrototype
+ * @see org.mozilla.javascript.Scriptable#getClassName
+ */
+ public void addAsConstructor(Scriptable scope, Scriptable prototype)
+ {
+ initAsConstructor(scope, prototype);
+ defineProperty(scope, prototype.getClassName(),
+ this, ScriptableObject.DONTENUM);
+ }
+
+ void initAsConstructor(Scriptable scope, Scriptable prototype)
+ {
+ ScriptRuntime.setFunctionProtoAndParent(this, scope);
+ setImmunePrototypeProperty(prototype);
+
+ prototype.setParentScope(this);
+
+ defineProperty(prototype, "constructor", this,
+ ScriptableObject.DONTENUM |
+ ScriptableObject.PERMANENT |
+ ScriptableObject.READONLY);
+ setParentScope(scope);
+ }
+
+ /**
+ * @deprecated Use {@link #getTypeTag(Class)}
+ * and {@link #convertArg(Context, Scriptable, Object, int)}
+ * for type convertion.
+ */
+ public static Object convertArg(Context cx, Scriptable scope,
+ Object arg, Class desired)
+ {
+ int tag = getTypeTag(desired);
+ if (tag == JAVA_UNSUPPORTED_TYPE) {
+ throw Context.reportRuntimeError1
+ ("msg.cant.convert", desired.getName());
+ }
+ return convertArg(cx, scope, arg, tag);
+ }
+
+ /**
+ * Performs conversions on argument types if needed and
+ * invokes the underlying Java method or constructor.
+ * <p>
+ * Implements Function.call.
+ *
+ * @see org.mozilla.javascript.Function#call(
+ * Context, Scriptable, Scriptable, Object[])
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ Object result;
+ boolean checkMethodResult = false;
+
+ if (parmsLength < 0) {
+ if (parmsLength == VARARGS_METHOD) {
+ Object[] invokeArgs = { cx, thisObj, args, this };
+ result = member.invoke(null, invokeArgs);
+ checkMethodResult = true;
+ } else {
+ boolean inNewExpr = (thisObj == null);
+ Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
+ Object[] invokeArgs = { cx, args, this, b };
+ result = (member.isCtor())
+ ? member.newInstance(invokeArgs)
+ : member.invoke(null, invokeArgs);
+ }
+
+ } else {
+ if (!isStatic) {
+ Class clazz = member.getDeclaringClass();
+ if (!clazz.isInstance(thisObj)) {
+ boolean compatible = false;
+ if (thisObj == scope) {
+ Scriptable parentScope = getParentScope();
+ if (scope != parentScope) {
+ // Call with dynamic scope for standalone function,
+ // use parentScope as thisObj
+ compatible = clazz.isInstance(parentScope);
+ if (compatible) {
+ thisObj = parentScope;
+ }
+ }
+ }
+ if (!compatible) {
+ // Couldn't find an object to call this on.
+ throw ScriptRuntime.typeError1("msg.incompat.call",
+ functionName);
+ }
+ }
+ }
+
+ Object[] invokeArgs;
+ if (parmsLength == args.length) {
+ // Do not allocate new argument array if java arguments are
+ // the same as the original js ones.
+ invokeArgs = args;
+ for (int i = 0; i != parmsLength; ++i) {
+ Object arg = args[i];
+ Object converted = convertArg(cx, scope, arg, typeTags[i]);
+ if (arg != converted) {
+ if (invokeArgs == args) {
+ invokeArgs = args.clone();
+ }
+ invokeArgs[i] = converted;
+ }
+ }
+ } else if (parmsLength == 0) {
+ invokeArgs = ScriptRuntime.emptyArgs;
+ } else {
+ invokeArgs = new Object[parmsLength];
+ for (int i = 0; i != parmsLength; ++i) {
+ Object arg = (i < args.length)
+ ? args[i]
+ : Undefined.instance;
+ invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
+ }
+ }
+
+ if (member.isMethod()) {
+ result = member.invoke(thisObj, invokeArgs);
+ checkMethodResult = true;
+ } else {
+ result = member.newInstance(invokeArgs);
+ }
+
+ }
+
+ if (checkMethodResult) {
+ if (hasVoidReturn) {
+ result = Undefined.instance;
+ } else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
+ result = cx.getWrapFactory().wrap(cx, scope, result, null);
+ }
+ // XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE
+ // then the Java method did a proper job of converting the
+ // result to JS primitive or Scriptable to avoid
+ // potentially costly Context.javaToJS call.
+ }
+
+ return result;
+ }
+
+ /**
+ * Return new {@link Scriptable} instance using the default
+ * constructor for the class of the underlying Java method.
+ * Return null to indicate that the call method should be used to create
+ * new objects.
+ */
+ public Scriptable createObject(Context cx, Scriptable scope) {
+ if (member.isCtor() || parmsLength == VARARGS_CTOR) {
+ return null;
+ }
+ Scriptable result;
+ try {
+ result = (Scriptable) member.getDeclaringClass().newInstance();
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+
+ result.setPrototype(getClassPrototype());
+ result.setParentScope(getParentScope());
+ return result;
+ }
+
+ boolean isVarArgsMethod() {
+ return parmsLength == VARARGS_METHOD;
+ }
+
+ boolean isVarArgsConstructor() {
+ return parmsLength == VARARGS_CTOR;
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ if (parmsLength > 0) {
+ Class[] types = member.argTypes;
+ typeTags = new byte[parmsLength];
+ for (int i = 0; i != parmsLength; ++i) {
+ typeTags[i] = (byte)getTypeTag(types[i]);
+ }
+ }
+ if (member.isMethod()) {
+ Method method = member.method();
+ Class returnType = method.getReturnType();
+ if (returnType == Void.TYPE) {
+ hasVoidReturn = true;
+ } else {
+ returnTypeTag = getTypeTag(returnType);
+ }
+ }
+ }
+
+ private static final short VARARGS_METHOD = -1;
+ private static final short VARARGS_CTOR = -2;
+
+ private static boolean sawSecurityException;
+
+ public static final int JAVA_UNSUPPORTED_TYPE = 0;
+ public static final int JAVA_STRING_TYPE = 1;
+ public static final int JAVA_INT_TYPE = 2;
+ public static final int JAVA_BOOLEAN_TYPE = 3;
+ public static final int JAVA_DOUBLE_TYPE = 4;
+ public static final int JAVA_SCRIPTABLE_TYPE = 5;
+ public static final int JAVA_OBJECT_TYPE = 6;
+
+ MemberBox member;
+ private String functionName;
+ private transient byte[] typeTags;
+ private int parmsLength;
+ private transient boolean hasVoidReturn;
+ private transient int returnTypeTag;
+ private boolean isStatic;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java
new file mode 100644
index 0000000..0f73615
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/GeneratedClassLoader.java
@@ -0,0 +1,66 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Interface to define classes from generated byte code.
+ */
+public interface GeneratedClassLoader {
+
+ /**
+ * Define a new Java class.
+ * Classes created via this method should have the same class loader.
+ *
+ * @param name fully qualified class name
+ * @param data class byte code
+ * @return new class object
+ */
+ public Class defineClass(String name, byte[] data);
+
+ /**
+ * Link the given class.
+ *
+ * @param cl Class instance returned from the previous call to
+ * {@link #defineClass(String, byte[])}
+ * @see java.lang.ClassLoader
+ */
+ public void linkClass(Class cl);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java
new file mode 100644
index 0000000..1f51cb1
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IRFactory.java
@@ -0,0 +1,1607 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * This class allows the creation of nodes, and follows the Factory pattern.
+ *
+ * @see Node
+ * @author Mike McCabe
+ * @author Norris Boyd
+ */
+final class IRFactory
+{
+ IRFactory(Parser parser)
+ {
+ this.parser = parser;
+ }
+
+ ScriptOrFnNode createScript()
+ {
+ return new ScriptOrFnNode(Token.SCRIPT);
+ }
+
+ /**
+ * Script (for associating file/url names with toplevel scripts.)
+ */
+ void initScript(ScriptOrFnNode scriptNode, Node body)
+ {
+ Node children = body.getFirstChild();
+ if (children != null) { scriptNode.addChildrenToBack(children); }
+ }
+
+ /**
+ * Leaf
+ */
+ Node createLeaf(int nodeType)
+ {
+ return new Node(nodeType);
+ }
+
+ /**
+ * Statement leaf nodes.
+ */
+
+ Node createSwitch(Node expr, int lineno)
+ {
+ //
+ // The switch will be rewritten from:
+ //
+ // switch (expr) {
+ // case test1: statements1;
+ // ...
+ // default: statementsDefault;
+ // ...
+ // case testN: statementsN;
+ // }
+ //
+ // to:
+ //
+ // {
+ // switch (expr) {
+ // case test1: goto label1;
+ // ...
+ // case testN: goto labelN;
+ // }
+ // goto labelDefault;
+ // label1:
+ // statements1;
+ // ...
+ // labelDefault:
+ // statementsDefault;
+ // ...
+ // labelN:
+ // statementsN;
+ // breakLabel:
+ // }
+ //
+ // where inside switch each "break;" without label will be replaced
+ // by "goto breakLabel".
+ //
+ // If the original switch does not have the default label, then
+ // the transformed code would contain after the switch instead of
+ // goto labelDefault;
+ // the following goto:
+ // goto breakLabel;
+ //
+
+ Node.Jump switchNode = new Node.Jump(Token.SWITCH, expr, lineno);
+ Node block = new Node(Token.BLOCK, switchNode);
+ return block;
+ }
+
+ /**
+ * If caseExpression argument is null it indicate default label.
+ */
+ void addSwitchCase(Node switchBlock, Node caseExpression, Node statements)
+ {
+ if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();
+ Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
+ if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
+
+ Node gotoTarget = Node.newTarget();
+ if (caseExpression != null) {
+ Node.Jump caseNode = new Node.Jump(Token.CASE, caseExpression);
+ caseNode.target = gotoTarget;
+ switchNode.addChildToBack(caseNode);
+ } else {
+ switchNode.setDefault(gotoTarget);
+ }
+ switchBlock.addChildToBack(gotoTarget);
+ switchBlock.addChildToBack(statements);
+ }
+
+ void closeSwitch(Node switchBlock)
+ {
+ if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();
+ Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
+ if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
+
+ Node switchBreakTarget = Node.newTarget();
+ // switchNode.target is only used by NodeTransformer
+ // to detect switch end
+ switchNode.target = switchBreakTarget;
+
+ Node defaultTarget = switchNode.getDefault();
+ if (defaultTarget == null) {
+ defaultTarget = switchBreakTarget;
+ }
+
+ switchBlock.addChildAfter(makeJump(Token.GOTO, defaultTarget),
+ switchNode);
+ switchBlock.addChildToBack(switchBreakTarget);
+ }
+
+ Node createVariables(int token, int lineno)
+ {
+ return new Node(token, lineno);
+ }
+
+ Node createExprStatement(Node expr, int lineno)
+ {
+ int type;
+ if (parser.insideFunction()) {
+ type = Token.EXPR_VOID;
+ } else {
+ type = Token.EXPR_RESULT;
+ }
+ return new Node(type, expr, lineno);
+ }
+
+ Node createExprStatementNoReturn(Node expr, int lineno)
+ {
+ return new Node(Token.EXPR_VOID, expr, lineno);
+ }
+
+ Node createDefaultNamespace(Node expr, int lineno)
+ {
+ // default xml namespace requires activation
+ setRequiresActivation();
+ Node n = createUnary(Token.DEFAULTNAMESPACE, expr);
+ Node result = createExprStatement(n, lineno);
+ return result;
+ }
+
+ /**
+ * Name
+ */
+ Node createName(String name)
+ {
+ checkActivationName(name, Token.NAME);
+ return Node.newString(Token.NAME, name);
+ }
+
+ private Node createName(int type, String name, Node child)
+ {
+ Node result = createName(name);
+ result.setType(type);
+ if (child != null)
+ result.addChildToBack(child);
+ return result;
+ }
+
+ /**
+ * String (for literals)
+ */
+ Node createString(String string)
+ {
+ return Node.newString(string);
+ }
+
+ /**
+ * Number (for literals)
+ */
+ Node createNumber(double number)
+ {
+ return Node.newNumber(number);
+ }
+
+ /**
+ * Catch clause of try/catch/finally
+ * @param varName the name of the variable to bind to the exception
+ * @param catchCond the condition under which to catch the exception.
+ * May be null if no condition is given.
+ * @param stmts the statements in the catch clause
+ * @param lineno the starting line number of the catch clause
+ */
+ Node createCatch(String varName, Node catchCond, Node stmts, int lineno)
+ {
+ if (catchCond == null) {
+ catchCond = new Node(Token.EMPTY);
+ }
+ return new Node(Token.CATCH, createName(varName),
+ catchCond, stmts, lineno);
+ }
+
+ /**
+ * Throw
+ */
+ Node createThrow(Node expr, int lineno)
+ {
+ return new Node(Token.THROW, expr, lineno);
+ }
+
+ /**
+ * Return
+ */
+ Node createReturn(Node expr, int lineno)
+ {
+ return expr == null
+ ? new Node(Token.RETURN, lineno)
+ : new Node(Token.RETURN, expr, lineno);
+ }
+
+ /**
+ * Debugger
+ */
+ Node createDebugger(int lineno)
+ {
+ return new Node(Token.DEBUGGER, lineno);
+ }
+
+ /**
+ * Label
+ */
+ Node createLabel(int lineno)
+ {
+ return new Node.Jump(Token.LABEL, lineno);
+ }
+
+ Node getLabelLoop(Node label)
+ {
+ return ((Node.Jump)label).getLoop();
+ }
+
+ /**
+ * Label
+ */
+ Node createLabeledStatement(Node labelArg, Node statement)
+ {
+ Node.Jump label = (Node.Jump)labelArg;
+
+ // Make a target and put it _after_ the statement
+ // node. And in the LABEL node, so breaks get the
+ // right target.
+
+ Node breakTarget = Node.newTarget();
+ Node block = new Node(Token.BLOCK, label, statement, breakTarget);
+ label.target = breakTarget;
+
+ return block;
+ }
+
+ /**
+ * Break (possibly labeled)
+ */
+ Node createBreak(Node breakStatement, int lineno)
+ {
+ Node.Jump n = new Node.Jump(Token.BREAK, lineno);
+ Node.Jump jumpStatement;
+ int t = breakStatement.getType();
+ if (t == Token.LOOP || t == Token.LABEL) {
+ jumpStatement = (Node.Jump)breakStatement;
+ } else if (t == Token.BLOCK
+ && breakStatement.getFirstChild().getType() == Token.SWITCH)
+ {
+ jumpStatement = (Node.Jump)breakStatement.getFirstChild();
+ } else {
+ throw Kit.codeBug();
+ }
+ n.setJumpStatement(jumpStatement);
+ return n;
+ }
+
+ /**
+ * Continue (possibly labeled)
+ */
+ Node createContinue(Node loop, int lineno)
+ {
+ if (loop.getType() != Token.LOOP) Kit.codeBug();
+ Node.Jump n = new Node.Jump(Token.CONTINUE, lineno);
+ n.setJumpStatement((Node.Jump)loop);
+ return n;
+ }
+
+ /**
+ * Statement block
+ * Creates the empty statement block
+ * Must make subsequent calls to add statements to the node
+ */
+ Node createBlock(int lineno)
+ {
+ return new Node(Token.BLOCK, lineno);
+ }
+
+ FunctionNode createFunction(String name)
+ {
+ return new FunctionNode(name);
+ }
+
+ Node initFunction(FunctionNode fnNode, int functionIndex,
+ Node statements, int functionType)
+ {
+ fnNode.itsFunctionType = functionType;
+ fnNode.addChildToBack(statements);
+
+ int functionCount = fnNode.getFunctionCount();
+ if (functionCount != 0) {
+ // Functions containing other functions require activation objects
+ fnNode.itsNeedsActivation = true;
+ }
+
+ if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
+ String name = fnNode.getFunctionName();
+ if (name != null && name.length() != 0) {
+ // A function expression needs to have its name as a
+ // variable (if it isn't already allocated as a variable).
+ // See ECMA Ch. 13. We add code to the beginning of the
+ // function to initialize a local variable of the
+ // function's name to the function value.
+ Node setFn = new Node(Token.EXPR_VOID,
+ new Node(Token.SETNAME,
+ Node.newString(Token.BINDNAME, name),
+ new Node(Token.THISFN)));
+ statements.addChildrenToFront(setFn);
+ }
+ }
+
+ // Add return to end if needed.
+ Node lastStmt = statements.getLastChild();
+ if (lastStmt == null || lastStmt.getType() != Token.RETURN) {
+ statements.addChildToBack(new Node(Token.RETURN));
+ }
+
+ Node result = Node.newString(Token.FUNCTION,
+ fnNode.getFunctionName());
+ result.putIntProp(Node.FUNCTION_PROP, functionIndex);
+ return result;
+ }
+
+ /**
+ * Add a child to the back of the given node. This function
+ * breaks the Factory abstraction, but it removes a requirement
+ * from implementors of Node.
+ */
+ void addChildToBack(Node parent, Node child)
+ {
+ parent.addChildToBack(child);
+ }
+
+ /**
+ * Create a node that can be used to hold lexically scoped variable
+ * definitions (via let declarations).
+ *
+ * @param token the token of the node to create
+ * @param lineno line number of source
+ * @return the created node
+ */
+ Node createScopeNode(int token, int lineno) {
+ return new Node.Scope(token, lineno);
+ }
+
+ /**
+ * Create loop node. The parser will later call
+ * createWhile|createDoWhile|createFor|createForIn
+ * to finish loop generation.
+ */
+ Node createLoopNode(Node loopLabel, int lineno)
+ {
+ Node.Jump result = new Node.Scope(Token.LOOP, lineno);
+ if (loopLabel != null) {
+ ((Node.Jump)loopLabel).setLoop(result);
+ }
+ return result;
+ }
+
+ /**
+ * While
+ */
+ Node createWhile(Node loop, Node cond, Node body)
+ {
+ return createLoop((Node.Jump)loop, LOOP_WHILE, body, cond,
+ null, null);
+ }
+
+ /**
+ * DoWhile
+ */
+ Node createDoWhile(Node loop, Node body, Node cond)
+ {
+ return createLoop((Node.Jump)loop, LOOP_DO_WHILE, body, cond,
+ null, null);
+ }
+
+ /**
+ * For
+ */
+ Node createFor(Node loop, Node init, Node test, Node incr, Node body)
+ {
+ if (init.getType() == Token.LET) {
+ // rewrite "for (let i=s; i < N; i++)..." as
+ // "let (i=s) { for (; i < N; i++)..." so that "s" is evaluated
+ // outside the scope of the for.
+ Node.Scope let = Node.Scope.splitScope((Node.Scope)loop);
+ let.setType(Token.LET);
+ let.addChildrenToBack(init);
+ let.addChildToBack(createLoop((Node.Jump)loop, LOOP_FOR, body, test,
+ new Node(Token.EMPTY), incr));
+ return let;
+ }
+ return createLoop((Node.Jump)loop, LOOP_FOR, body, test, init, incr);
+ }
+
+ private Node createLoop(Node.Jump loop, int loopType, Node body, Node cond,
+ Node init, Node incr)
+ {
+ Node bodyTarget = Node.newTarget();
+ Node condTarget = Node.newTarget();
+ if (loopType == LOOP_FOR && cond.getType() == Token.EMPTY) {
+ cond = new Node(Token.TRUE);
+ }
+ Node.Jump IFEQ = new Node.Jump(Token.IFEQ, cond);
+ IFEQ.target = bodyTarget;
+ Node breakTarget = Node.newTarget();
+
+ loop.addChildToBack(bodyTarget);
+ loop.addChildrenToBack(body);
+ if (loopType == LOOP_WHILE || loopType == LOOP_FOR) {
+ // propagate lineno to condition
+ loop.addChildrenToBack(new Node(Token.EMPTY, loop.getLineno()));
+ }
+ loop.addChildToBack(condTarget);
+ loop.addChildToBack(IFEQ);
+ loop.addChildToBack(breakTarget);
+
+ loop.target = breakTarget;
+ Node continueTarget = condTarget;
+
+ if (loopType == LOOP_WHILE || loopType == LOOP_FOR) {
+ // Just add a GOTO to the condition in the do..while
+ loop.addChildToFront(makeJump(Token.GOTO, condTarget));
+
+ if (loopType == LOOP_FOR) {
+ int initType = init.getType();
+ if (initType != Token.EMPTY) {
+ if (initType != Token.VAR && initType != Token.LET) {
+ init = new Node(Token.EXPR_VOID, init);
+ }
+ loop.addChildToFront(init);
+ }
+ Node incrTarget = Node.newTarget();
+ loop.addChildAfter(incrTarget, body);
+ if (incr.getType() != Token.EMPTY) {
+ incr = new Node(Token.EXPR_VOID, incr);
+ loop.addChildAfter(incr, incrTarget);
+ }
+ continueTarget = incrTarget;
+ }
+ }
+
+ loop.setContinue(continueTarget);
+
+ return loop;
+ }
+
+ /**
+ * For .. In
+ *
+ */
+ Node createForIn(int declType, Node loop, Node lhs, Node obj, Node body,
+ boolean isForEach)
+ {
+ int destructuring = -1;
+ int destructuringLen = 0;
+ Node lvalue;
+ int type = lhs.getType();
+ if (type == Token.VAR || type == Token.LET) {
+ Node lastChild = lhs.getLastChild();
+ if (lhs.getFirstChild() != lastChild) {
+ /*
+ * check that there was only one variable given.
+ * we can't do this in the parser, because then the
+ * parser would have to know something about the
+ * 'init' node of the for-in loop.
+ */
+ parser.reportError("msg.mult.index");
+ }
+ if (lastChild.getType() == Token.ARRAYLIT ||
+ lastChild.getType() == Token.OBJECTLIT)
+ {
+ type = destructuring = lastChild.getType();
+ lvalue = lastChild;
+ destructuringLen = lastChild.getIntProp(
+ Node.DESTRUCTURING_ARRAY_LENGTH, 0);
+ } else if (lastChild.getType() == Token.NAME) {
+ lvalue = Node.newString(Token.NAME, lastChild.getString());
+ } else {
+ parser.reportError("msg.bad.for.in.lhs");
+ return obj;
+ }
+ } else if (type == Token.ARRAYLIT || type == Token.OBJECTLIT) {
+ destructuring = type;
+ lvalue = lhs;
+ destructuringLen = lhs.getIntProp(Node.DESTRUCTURING_ARRAY_LENGTH, 0);
+ } else {
+ lvalue = makeReference(lhs);
+ if (lvalue == null) {
+ parser.reportError("msg.bad.for.in.lhs");
+ return obj;
+ }
+ }
+
+ Node localBlock = new Node(Token.LOCAL_BLOCK);
+ int initType = (isForEach) ? Token.ENUM_INIT_VALUES :
+ (destructuring != -1) ? Token.ENUM_INIT_ARRAY :
+ Token.ENUM_INIT_KEYS;
+ Node init = new Node(initType, obj);
+ init.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
+ Node cond = new Node(Token.ENUM_NEXT);
+ cond.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
+ Node id = new Node(Token.ENUM_ID);
+ id.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
+
+ Node newBody = new Node(Token.BLOCK);
+ Node assign;
+ if (destructuring != -1) {
+ assign = createDestructuringAssignment(declType, lvalue, id);
+ if (!isForEach && (destructuring == Token.OBJECTLIT ||
+ destructuringLen != 2))
+ {
+ // destructuring assignment is only allowed in for..each or
+ // with an array type of length 2 (to hold key and value)
+ parser.reportError("msg.bad.for.in.destruct");
+ }
+ } else {
+ assign = simpleAssignment(lvalue, id);
+ }
+ newBody.addChildToBack(new Node(Token.EXPR_VOID, assign));
+ newBody.addChildToBack(body);
+
+ loop = createWhile(loop, cond, newBody);
+ loop.addChildToFront(init);
+ if (type == Token.VAR || type == Token.LET)
+ loop.addChildToFront(lhs);
+ localBlock.addChildToBack(loop);
+
+ return localBlock;
+ }
+
+ /**
+ * Try/Catch/Finally
+ *
+ * The IRFactory tries to express as much as possible in the tree;
+ * the responsibilities remaining for Codegen are to add the Java
+ * handlers: (Either (but not both) of TARGET and FINALLY might not
+ * be defined)
+
+ * - a catch handler for javascript exceptions that unwraps the
+ * exception onto the stack and GOTOes to the catch target
+
+ * - a finally handler
+
+ * ... and a goto to GOTO around these handlers.
+ */
+ Node createTryCatchFinally(Node tryBlock, Node catchBlocks,
+ Node finallyBlock, int lineno)
+ {
+ boolean hasFinally = (finallyBlock != null)
+ && (finallyBlock.getType() != Token.BLOCK
+ || finallyBlock.hasChildren());
+
+ // short circuit
+ if (tryBlock.getType() == Token.BLOCK && !tryBlock.hasChildren()
+ && !hasFinally)
+ {
+ return tryBlock;
+ }
+
+ boolean hasCatch = catchBlocks.hasChildren();
+
+ // short circuit
+ if (!hasFinally && !hasCatch) {
+ // bc finally might be an empty block...
+ return tryBlock;
+ }
+
+
+ Node handlerBlock = new Node(Token.LOCAL_BLOCK);
+ Node.Jump pn = new Node.Jump(Token.TRY, tryBlock, lineno);
+ pn.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
+
+ if (hasCatch) {
+ // jump around catch code
+ Node endCatch = Node.newTarget();
+ pn.addChildToBack(makeJump(Token.GOTO, endCatch));
+
+ // make a TARGET for the catch that the tcf node knows about
+ Node catchTarget = Node.newTarget();
+ pn.target = catchTarget;
+ // mark it
+ pn.addChildToBack(catchTarget);
+
+ //
+ // Given
+ //
+ // try {
+ // tryBlock;
+ // } catch (e if condition1) {
+ // something1;
+ // ...
+ //
+ // } catch (e if conditionN) {
+ // somethingN;
+ // } catch (e) {
+ // somethingDefault;
+ // }
+ //
+ // rewrite as
+ //
+ // try {
+ // tryBlock;
+ // goto after_catch:
+ // } catch (x) {
+ // with (newCatchScope(e, x)) {
+ // if (condition1) {
+ // something1;
+ // goto after_catch;
+ // }
+ // }
+ // ...
+ // with (newCatchScope(e, x)) {
+ // if (conditionN) {
+ // somethingN;
+ // goto after_catch;
+ // }
+ // }
+ // with (newCatchScope(e, x)) {
+ // somethingDefault;
+ // goto after_catch;
+ // }
+ // }
+ // after_catch:
+ //
+ // If there is no default catch, then the last with block
+ // arround "somethingDefault;" is replaced by "rethrow;"
+
+ // It is assumed that catch handler generation will store
+ // exeception object in handlerBlock register
+
+ // Block with local for exception scope objects
+ Node catchScopeBlock = new Node(Token.LOCAL_BLOCK);
+
+ // expects catchblocks children to be (cond block) pairs.
+ Node cb = catchBlocks.getFirstChild();
+ boolean hasDefault = false;
+ int scopeIndex = 0;
+ while (cb != null) {
+ int catchLineNo = cb.getLineno();
+
+ Node name = cb.getFirstChild();
+ Node cond = name.getNext();
+ Node catchStatement = cond.getNext();
+ cb.removeChild(name);
+ cb.removeChild(cond);
+ cb.removeChild(catchStatement);
+
+ // Add goto to the catch statement to jump out of catch
+ // but prefix it with LEAVEWITH since try..catch produces
+ // "with"code in order to limit the scope of the exception
+ // object.
+ catchStatement.addChildToBack(new Node(Token.LEAVEWITH));
+ catchStatement.addChildToBack(makeJump(Token.GOTO, endCatch));
+
+ // Create condition "if" when present
+ Node condStmt;
+ if (cond.getType() == Token.EMPTY) {
+ condStmt = catchStatement;
+ hasDefault = true;
+ } else {
+ condStmt = createIf(cond, catchStatement, null,
+ catchLineNo);
+ }
+
+ // Generate code to create the scope object and store
+ // it in catchScopeBlock register
+ Node catchScope = new Node(Token.CATCH_SCOPE, name,
+ createUseLocal(handlerBlock));
+ catchScope.putProp(Node.LOCAL_BLOCK_PROP, catchScopeBlock);
+ catchScope.putIntProp(Node.CATCH_SCOPE_PROP, scopeIndex);
+ catchScopeBlock.addChildToBack(catchScope);
+
+ // Add with statement based on catch scope object
+ catchScopeBlock.addChildToBack(
+ createWith(createUseLocal(catchScopeBlock), condStmt,
+ catchLineNo));
+
+ // move to next cb
+ cb = cb.getNext();
+ ++scopeIndex;
+ }
+ pn.addChildToBack(catchScopeBlock);
+ if (!hasDefault) {
+ // Generate code to rethrow if no catch clause was executed
+ Node rethrow = new Node(Token.RETHROW);
+ rethrow.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
+ pn.addChildToBack(rethrow);
+ }
+
+ pn.addChildToBack(endCatch);
+ }
+
+ if (hasFinally) {
+ Node finallyTarget = Node.newTarget();
+ pn.setFinally(finallyTarget);
+
+ // add jsr finally to the try block
+ pn.addChildToBack(makeJump(Token.JSR, finallyTarget));
+
+ // jump around finally code
+ Node finallyEnd = Node.newTarget();
+ pn.addChildToBack(makeJump(Token.GOTO, finallyEnd));
+
+ pn.addChildToBack(finallyTarget);
+ Node fBlock = new Node(Token.FINALLY, finallyBlock);
+ fBlock.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock);
+ pn.addChildToBack(fBlock);
+
+ pn.addChildToBack(finallyEnd);
+ }
+ handlerBlock.addChildToBack(pn);
+ return handlerBlock;
+ }
+
+ /**
+ * Throw, Return, Label, Break and Continue are defined in ASTFactory.
+ */
+
+ /**
+ * With
+ */
+ Node createWith(Node obj, Node body, int lineno)
+ {
+ setRequiresActivation();
+ Node result = new Node(Token.BLOCK, lineno);
+ result.addChildToBack(new Node(Token.ENTERWITH, obj));
+ Node bodyNode = new Node(Token.WITH, body, lineno);
+ result.addChildrenToBack(bodyNode);
+ result.addChildToBack(new Node(Token.LEAVEWITH));
+ return result;
+ }
+
+ /**
+ * DOTQUERY
+ */
+ public Node createDotQuery (Node obj, Node body, int lineno)
+ {
+ setRequiresActivation();
+ Node result = new Node(Token.DOTQUERY, obj, body, lineno);
+ return result;
+ }
+
+ Node createArrayLiteral(ObjArray elems, int skipCount, int destructuringLen)
+ {
+ int length = elems.size();
+ int[] skipIndexes = null;
+ if (skipCount != 0) {
+ skipIndexes = new int[skipCount];
+ }
+ Node array = new Node(Token.ARRAYLIT);
+ for (int i = 0, j = 0; i != length; ++i) {
+ Node elem = (Node)elems.get(i);
+ if (elem != null) {
+ array.addChildToBack(elem);
+ } else {
+ skipIndexes[j] = i;
+ ++j;
+ }
+ }
+ if (skipCount != 0) {
+ array.putProp(Node.SKIP_INDEXES_PROP, skipIndexes);
+ }
+ array.putIntProp(Node.DESTRUCTURING_ARRAY_LENGTH, destructuringLen);
+ return array;
+ }
+
+ /**
+ * Object Literals
+ * <BR> createObjectLiteral rewrites its argument as object
+ * creation plus object property entries, so later compiler
+ * stages don't need to know about object literals.
+ */
+ Node createObjectLiteral(ObjArray elems)
+ {
+ int size = elems.size() / 2;
+ Node object = new Node(Token.OBJECTLIT);
+ Object[] properties;
+ if (size == 0) {
+ properties = ScriptRuntime.emptyArgs;
+ } else {
+ properties = new Object[size];
+ for (int i = 0; i != size; ++i) {
+ properties[i] = elems.get(2 * i);
+ Node value = (Node)elems.get(2 * i + 1);
+ object.addChildToBack(value);
+ }
+ }
+ object.putProp(Node.OBJECT_IDS_PROP, properties);
+ return object;
+ }
+
+ /**
+ * Regular expressions
+ */
+ Node createRegExp(int regexpIndex)
+ {
+ Node n = new Node(Token.REGEXP);
+ n.putIntProp(Node.REGEXP_PROP, regexpIndex);
+ return n;
+ }
+
+ /**
+ * If statement
+ */
+ Node createIf(Node cond, Node ifTrue, Node ifFalse, int lineno)
+ {
+ int condStatus = isAlwaysDefinedBoolean(cond);
+ if (condStatus == ALWAYS_TRUE_BOOLEAN) {
+ return ifTrue;
+ } else if (condStatus == ALWAYS_FALSE_BOOLEAN) {
+ if (ifFalse != null) {
+ return ifFalse;
+ }
+ // Replace if (false) xxx by empty block
+ return new Node(Token.BLOCK, lineno);
+ }
+
+ Node result = new Node(Token.BLOCK, lineno);
+ Node ifNotTarget = Node.newTarget();
+ Node.Jump IFNE = new Node.Jump(Token.IFNE, cond);
+ IFNE.target = ifNotTarget;
+
+ result.addChildToBack(IFNE);
+ result.addChildrenToBack(ifTrue);
+
+ if (ifFalse != null) {
+ Node endTarget = Node.newTarget();
+ result.addChildToBack(makeJump(Token.GOTO, endTarget));
+ result.addChildToBack(ifNotTarget);
+ result.addChildrenToBack(ifFalse);
+ result.addChildToBack(endTarget);
+ } else {
+ result.addChildToBack(ifNotTarget);
+ }
+
+ return result;
+ }
+
+ Node createCondExpr(Node cond, Node ifTrue, Node ifFalse)
+ {
+ int condStatus = isAlwaysDefinedBoolean(cond);
+ if (condStatus == ALWAYS_TRUE_BOOLEAN) {
+ return ifTrue;
+ } else if (condStatus == ALWAYS_FALSE_BOOLEAN) {
+ return ifFalse;
+ }
+ return new Node(Token.HOOK, cond, ifTrue, ifFalse);
+ }
+
+ /**
+ * Unary
+ */
+ Node createUnary(int nodeType, Node child)
+ {
+ int childType = child.getType();
+ switch (nodeType) {
+ case Token.DELPROP: {
+ Node n;
+ if (childType == Token.NAME) {
+ // Transform Delete(Name "a")
+ // to Delete(Bind("a"), String("a"))
+ child.setType(Token.BINDNAME);
+ Node left = child;
+ Node right = Node.newString(child.getString());
+ n = new Node(nodeType, left, right);
+ } else if (childType == Token.GETPROP ||
+ childType == Token.GETELEM)
+ {
+ Node left = child.getFirstChild();
+ Node right = child.getLastChild();
+ child.removeChild(left);
+ child.removeChild(right);
+ n = new Node(nodeType, left, right);
+ } else if (childType == Token.GET_REF) {
+ Node ref = child.getFirstChild();
+ child.removeChild(ref);
+ n = new Node(Token.DEL_REF, ref);
+ } else {
+ n = new Node(Token.TRUE);
+ }
+ return n;
+ }
+ case Token.TYPEOF:
+ if (childType == Token.NAME) {
+ child.setType(Token.TYPEOFNAME);
+ return child;
+ }
+ break;
+ case Token.BITNOT:
+ if (childType == Token.NUMBER) {
+ int value = ScriptRuntime.toInt32(child.getDouble());
+ child.setDouble(~value);
+ return child;
+ }
+ break;
+ case Token.NEG:
+ if (childType == Token.NUMBER) {
+ child.setDouble(-child.getDouble());
+ return child;
+ }
+ break;
+ case Token.NOT: {
+ int status = isAlwaysDefinedBoolean(child);
+ if (status != 0) {
+ int type;
+ if (status == ALWAYS_TRUE_BOOLEAN) {
+ type = Token.FALSE;
+ } else {
+ type = Token.TRUE;
+ }
+ if (childType == Token.TRUE || childType == Token.FALSE) {
+ child.setType(type);
+ return child;
+ }
+ return new Node(type);
+ }
+ break;
+ }
+ }
+ return new Node(nodeType, child);
+ }
+
+ Node createYield(Node child, int lineno)
+ {
+ if (!parser.insideFunction()) {
+ parser.reportError("msg.bad.yield");
+ }
+ setRequiresActivation();
+ setIsGenerator();
+ if (child != null)
+ return new Node(Token.YIELD, child, lineno);
+ else
+ return new Node(Token.YIELD, lineno);
+ }
+
+ Node createCallOrNew(int nodeType, Node child)
+ {
+ int type = Node.NON_SPECIALCALL;
+ if (child.getType() == Token.NAME) {
+ String name = child.getString();
+ if (name.equals("eval")) {
+ type = Node.SPECIALCALL_EVAL;
+ } else if (name.equals("With")) {
+ type = Node.SPECIALCALL_WITH;
+ }
+ } else if (child.getType() == Token.GETPROP) {
+ String name = child.getLastChild().getString();
+ if (name.equals("eval")) {
+ type = Node.SPECIALCALL_EVAL;
+ }
+ }
+ Node node = new Node(nodeType, child);
+ if (type != Node.NON_SPECIALCALL) {
+ // Calls to these functions require activation objects.
+ setRequiresActivation();
+ node.putIntProp(Node.SPECIALCALL_PROP, type);
+ }
+ return node;
+ }
+
+ Node createIncDec(int nodeType, boolean post, Node child)
+ {
+ child = makeReference(child);
+ if (child == null) {
+ String msg;
+ if (nodeType == Token.DEC) {
+ msg = "msg.bad.decr";
+ } else {
+ msg = "msg.bad.incr";
+ }
+ parser.reportError(msg);
+ return null;
+ }
+
+ int childType = child.getType();
+
+ switch (childType) {
+ case Token.NAME:
+ case Token.GETPROP:
+ case Token.GETELEM:
+ case Token.GET_REF: {
+ Node n = new Node(nodeType, child);
+ int incrDecrMask = 0;
+ if (nodeType == Token.DEC) {
+ incrDecrMask |= Node.DECR_FLAG;
+ }
+ if (post) {
+ incrDecrMask |= Node.POST_FLAG;
+ }
+ n.putIntProp(Node.INCRDECR_PROP, incrDecrMask);
+ return n;
+ }
+ }
+ throw Kit.codeBug();
+ }
+
+ Node createPropertyGet(Node target, String namespace, String name,
+ int memberTypeFlags)
+ {
+ if (namespace == null && memberTypeFlags == 0) {
+ if (target == null) {
+ return createName(name);
+ }
+ checkActivationName(name, Token.GETPROP);
+ if (ScriptRuntime.isSpecialProperty(name)) {
+ Node ref = new Node(Token.REF_SPECIAL, target);
+ ref.putProp(Node.NAME_PROP, name);
+ return new Node(Token.GET_REF, ref);
+ }
+ return new Node(Token.GETPROP, target, createString(name));
+ }
+ Node elem = createString(name);
+ memberTypeFlags |= Node.PROPERTY_FLAG;
+ return createMemberRefGet(target, namespace, elem, memberTypeFlags);
+ }
+
+ Node createElementGet(Node target, String namespace, Node elem,
+ int memberTypeFlags)
+ {
+ // OPT: could optimize to createPropertyGet
+ // iff elem is string that can not be number
+ if (namespace == null && memberTypeFlags == 0) {
+ // stand-alone [aaa] as primary expression is array literal
+ // declaration and should not come here!
+ if (target == null) throw Kit.codeBug();
+ return new Node(Token.GETELEM, target, elem);
+ }
+ return createMemberRefGet(target, namespace, elem, memberTypeFlags);
+ }
+
+ private Node createMemberRefGet(Node target, String namespace, Node elem,
+ int memberTypeFlags)
+ {
+ Node nsNode = null;
+ if (namespace != null) {
+ // See 11.1.2 in ECMA 357
+ if (namespace.equals("*")) {
+ nsNode = new Node(Token.NULL);
+ } else {
+ nsNode = createName(namespace);
+ }
+ }
+ Node ref;
+ if (target == null) {
+ if (namespace == null) {
+ ref = new Node(Token.REF_NAME, elem);
+ } else {
+ ref = new Node(Token.REF_NS_NAME, nsNode, elem);
+ }
+ } else {
+ if (namespace == null) {
+ ref = new Node(Token.REF_MEMBER, target, elem);
+ } else {
+ ref = new Node(Token.REF_NS_MEMBER, target, nsNode, elem);
+ }
+ }
+ if (memberTypeFlags != 0) {
+ ref.putIntProp(Node.MEMBER_TYPE_PROP, memberTypeFlags);
+ }
+ return new Node(Token.GET_REF, ref);
+ }
+
+ /**
+ * Binary
+ */
+ Node createBinary(int nodeType, Node left, Node right)
+ {
+ switch (nodeType) {
+
+ case Token.ADD:
+ // numerical addition and string concatenation
+ if (left.type == Token.STRING) {
+ String s2;
+ if (right.type == Token.STRING) {
+ s2 = right.getString();
+ } else if (right.type == Token.NUMBER) {
+ s2 = ScriptRuntime.numberToString(right.getDouble(), 10);
+ } else {
+ break;
+ }
+ String s1 = left.getString();
+ left.setString(s1.concat(s2));
+ return left;
+ } else if (left.type == Token.NUMBER) {
+ if (right.type == Token.NUMBER) {
+ left.setDouble(left.getDouble() + right.getDouble());
+ return left;
+ } else if (right.type == Token.STRING) {
+ String s1, s2;
+ s1 = ScriptRuntime.numberToString(left.getDouble(), 10);
+ s2 = right.getString();
+ right.setString(s1.concat(s2));
+ return right;
+ }
+ }
+ // can't do anything if we don't know both types - since
+ // 0 + object is supposed to call toString on the object and do
+ // string concantenation rather than addition
+ break;
+
+ case Token.SUB:
+ // numerical subtraction
+ if (left.type == Token.NUMBER) {
+ double ld = left.getDouble();
+ if (right.type == Token.NUMBER) {
+ //both numbers
+ left.setDouble(ld - right.getDouble());
+ return left;
+ } else if (ld == 0.0) {
+ // first 0: 0-x -> -x
+ return new Node(Token.NEG, right);
+ }
+ } else if (right.type == Token.NUMBER) {
+ if (right.getDouble() == 0.0) {
+ //second 0: x - 0 -> +x
+ // can not make simply x because x - 0 must be number
+ return new Node(Token.POS, left);
+ }
+ }
+ break;
+
+ case Token.MUL:
+ // numerical multiplication
+ if (left.type == Token.NUMBER) {
+ double ld = left.getDouble();
+ if (right.type == Token.NUMBER) {
+ //both numbers
+ left.setDouble(ld * right.getDouble());
+ return left;
+ } else if (ld == 1.0) {
+ // first 1: 1 * x -> +x
+ return new Node(Token.POS, right);
+ }
+ } else if (right.type == Token.NUMBER) {
+ if (right.getDouble() == 1.0) {
+ //second 1: x * 1 -> +x
+ // can not make simply x because x - 0 must be number
+ return new Node(Token.POS, left);
+ }
+ }
+ // can't do x*0: Infinity * 0 gives NaN, not 0
+ break;
+
+ case Token.DIV:
+ // number division
+ if (right.type == Token.NUMBER) {
+ double rd = right.getDouble();
+ if (left.type == Token.NUMBER) {
+ // both constants -- just divide, trust Java to handle x/0
+ left.setDouble(left.getDouble() / rd);
+ return left;
+ } else if (rd == 1.0) {
+ // second 1: x/1 -> +x
+ // not simply x to force number convertion
+ return new Node(Token.POS, left);
+ }
+ }
+ break;
+
+ case Token.AND: {
+ // Since x && y gives x, not false, when Boolean(x) is false,
+ // and y, not Boolean(y), when Boolean(x) is true, x && y
+ // can only be simplified if x is defined. See bug 309957.
+
+ int leftStatus = isAlwaysDefinedBoolean(left);
+ if (leftStatus == ALWAYS_FALSE_BOOLEAN) {
+ // if the first one is false, just return it
+ return left;
+ } else if (leftStatus == ALWAYS_TRUE_BOOLEAN) {
+ // if first is true, set to second
+ return right;
+ }
+ break;
+ }
+
+ case Token.OR: {
+ // Since x || y gives x, not true, when Boolean(x) is true,
+ // and y, not Boolean(y), when Boolean(x) is false, x || y
+ // can only be simplified if x is defined. See bug 309957.
+
+ int leftStatus = isAlwaysDefinedBoolean(left);
+ if (leftStatus == ALWAYS_TRUE_BOOLEAN) {
+ // if the first one is true, just return it
+ return left;
+ } else if (leftStatus == ALWAYS_FALSE_BOOLEAN) {
+ // if first is false, set to second
+ return right;
+ }
+ break;
+ }
+ }
+
+ return new Node(nodeType, left, right);
+ }
+
+ private Node simpleAssignment(Node left, Node right)
+ {
+ int nodeType = left.getType();
+ switch (nodeType) {
+ case Token.NAME:
+ left.setType(Token.BINDNAME);
+ return new Node(Token.SETNAME, left, right);
+
+ case Token.GETPROP:
+ case Token.GETELEM: {
+ Node obj = left.getFirstChild();
+ Node id = left.getLastChild();
+ int type;
+ if (nodeType == Token.GETPROP) {
+ type = Token.SETPROP;
+ } else {
+ type = Token.SETELEM;
+ }
+ return new Node(type, obj, id, right);
+ }
+ case Token.GET_REF: {
+ Node ref = left.getFirstChild();
+ checkMutableReference(ref);
+ return new Node(Token.SET_REF, ref, right);
+ }
+ }
+
+ throw Kit.codeBug();
+ }
+
+ private void checkMutableReference(Node n)
+ {
+ int memberTypeFlags = n.getIntProp(Node.MEMBER_TYPE_PROP, 0);
+ if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
+ parser.reportError("msg.bad.assign.left");
+ }
+ }
+
+ Node createAssignment(int assignType, Node left, Node right)
+ {
+ Node ref = makeReference(left);
+ if (ref == null) {
+ if (left.getType() == Token.ARRAYLIT ||
+ left.getType() == Token.OBJECTLIT)
+ {
+ if (assignType != Token.ASSIGN) {
+ parser.reportError("msg.bad.destruct.op");
+ return right;
+ }
+ return createDestructuringAssignment(-1, left, right);
+ }
+ parser.reportError("msg.bad.assign.left");
+ return right;
+ }
+ left = ref;
+
+ int assignOp;
+ switch (assignType) {
+ case Token.ASSIGN:
+ return simpleAssignment(left, right);
+ case Token.ASSIGN_BITOR: assignOp = Token.BITOR; break;
+ case Token.ASSIGN_BITXOR: assignOp = Token.BITXOR; break;
+ case Token.ASSIGN_BITAND: assignOp = Token.BITAND; break;
+ case Token.ASSIGN_LSH: assignOp = Token.LSH; break;
+ case Token.ASSIGN_RSH: assignOp = Token.RSH; break;
+ case Token.ASSIGN_URSH: assignOp = Token.URSH; break;
+ case Token.ASSIGN_ADD: assignOp = Token.ADD; break;
+ case Token.ASSIGN_SUB: assignOp = Token.SUB; break;
+ case Token.ASSIGN_MUL: assignOp = Token.MUL; break;
+ case Token.ASSIGN_DIV: assignOp = Token.DIV; break;
+ case Token.ASSIGN_MOD: assignOp = Token.MOD; break;
+ default: throw Kit.codeBug();
+ }
+
+ int nodeType = left.getType();
+ switch (nodeType) {
+ case Token.NAME: {
+ Node op = new Node(assignOp, left, right);
+ Node lvalueLeft = Node.newString(Token.BINDNAME, left.getString());
+ return new Node(Token.SETNAME, lvalueLeft, op);
+ }
+ case Token.GETPROP:
+ case Token.GETELEM: {
+ Node obj = left.getFirstChild();
+ Node id = left.getLastChild();
+
+ int type = nodeType == Token.GETPROP
+ ? Token.SETPROP_OP
+ : Token.SETELEM_OP;
+
+ Node opLeft = new Node(Token.USE_STACK);
+ Node op = new Node(assignOp, opLeft, right);
+ return new Node(type, obj, id, op);
+ }
+ case Token.GET_REF: {
+ ref = left.getFirstChild();
+ checkMutableReference(ref);
+ Node opLeft = new Node(Token.USE_STACK);
+ Node op = new Node(assignOp, opLeft, right);
+ return new Node(Token.SET_REF_OP, ref, op);
+ }
+ }
+
+ throw Kit.codeBug();
+ }
+
+ /**
+ * Given a destructuring assignment with a left hand side parsed
+ * as an array or object literal and a right hand side expression,
+ * rewrite as a series of assignments to the variables defined in
+ * left from property accesses to the expression on the right.
+ * @param type declaration type: Token.VAR or Token.LET or -1
+ * @param left array or object literal containing NAME nodes for
+ * variables to assign
+ * @param right expression to assign from
+ * @return expression that performs a series of assignments to
+ * the variables defined in left
+ */
+ Node createDestructuringAssignment(int type, Node left, Node right)
+ {
+ String tempName = parser.currentScriptOrFn.getNextTempName();
+ Node result = destructuringAssignmentHelper(type, left, right,
+ tempName);
+ Node comma = result.getLastChild();
+ comma.addChildToBack(createName(tempName));
+ return result;
+ }
+
+ private Node destructuringAssignmentHelper(int variableType, Node left,
+ Node right, String tempName)
+ {
+ Node result = createScopeNode(Token.LETEXPR,
+ parser.getCurrentLineNumber());
+ result.addChildToFront(new Node(Token.LET,
+ createName(Token.NAME, tempName, right)));
+ try {
+ parser.pushScope(result);
+ parser.defineSymbol(Token.LET, tempName);
+ } finally {
+ parser.popScope();
+ }
+ Node comma = new Node(Token.COMMA);
+ result.addChildToBack(comma);
+ final int setOp = variableType == Token.CONST ? Token.SETCONST
+ : Token.SETNAME;
+ List<String> destructuringNames = new ArrayList<String>();
+ boolean empty = true;
+ int type = left.getType();
+ if (type == Token.ARRAYLIT) {
+ int index = 0;
+ int[] skipIndices = (int[])left.getProp(Node.SKIP_INDEXES_PROP);
+ int skip = 0;
+ Node n = left.getFirstChild();
+ for (;;) {
+ if (skipIndices != null) {
+ while (skip < skipIndices.length &&
+ skipIndices[skip] == index) {
+ skip++;
+ index++;
+ }
+ }
+ if (n == null)
+ break;
+ Node rightElem = new Node(Token.GETELEM,
+ createName(tempName),
+ createNumber(index));
+ if (n.getType() == Token.NAME) {
+ String name = n.getString();
+ comma.addChildToBack(new Node(setOp,
+ createName(Token.BINDNAME, name, null),
+ rightElem));
+ if (variableType != -1) {
+ parser.defineSymbol(variableType, name);
+ destructuringNames.add(name);
+ }
+ } else {
+ comma.addChildToBack(
+ destructuringAssignmentHelper(variableType, n,
+ rightElem,
+ parser.currentScriptOrFn.getNextTempName()));
+ }
+ index++;
+ empty = false;
+ n = n.getNext();
+ }
+ } else if (type == Token.OBJECTLIT) {
+ int index = 0;
+ Object[] propertyIds = (Object[])
+ left.getProp(Node.OBJECT_IDS_PROP);
+ for (Node n = left.getFirstChild(); n != null; n = n.getNext())
+ {
+ Object id = propertyIds[index];
+ Node rightElem = id instanceof String
+ ? new Node(Token.GETPROP,
+ createName(tempName),
+ createString((String)id))
+ : new Node(Token.GETELEM,
+ createName(tempName),
+ createNumber(((Number)id).intValue()));
+ if (n.getType() == Token.NAME) {
+ String name = n.getString();
+ comma.addChildToBack(new Node(setOp,
+ createName(Token.BINDNAME, name, null),
+ rightElem));
+ if (variableType != -1) {
+ parser.defineSymbol(variableType, name);
+ destructuringNames.add(name);
+ }
+ } else {
+ comma.addChildToBack(
+ destructuringAssignmentHelper(variableType, n,
+ rightElem,
+ parser.currentScriptOrFn.getNextTempName()));
+ }
+ index++;
+ empty = false;
+ }
+ } else if (type == Token.GETPROP || type == Token.GETELEM) {
+ comma.addChildToBack(simpleAssignment(left, createName(tempName)));
+ } else {
+ parser.reportError("msg.bad.assign.left");
+ }
+ if (empty) {
+ // Don't want a COMMA node with no children. Just add a zero.
+ comma.addChildToBack(createNumber(0));
+ }
+ result.putProp(Node.DESTRUCTURING_NAMES, destructuringNames);
+ return result;
+ }
+
+ Node createUseLocal(Node localBlock)
+ {
+ if (Token.LOCAL_BLOCK != localBlock.getType()) throw Kit.codeBug();
+ Node result = new Node(Token.LOCAL_LOAD);
+ result.putProp(Node.LOCAL_BLOCK_PROP, localBlock);
+ return result;
+ }
+
+ private Node.Jump makeJump(int type, Node target)
+ {
+ Node.Jump n = new Node.Jump(type);
+ n.target = target;
+ return n;
+ }
+
+ private Node makeReference(Node node)
+ {
+ int type = node.getType();
+ switch (type) {
+ case Token.NAME:
+ case Token.GETPROP:
+ case Token.GETELEM:
+ case Token.GET_REF:
+ return node;
+ case Token.CALL:
+ node.setType(Token.REF_CALL);
+ return new Node(Token.GET_REF, node);
+ }
+ // Signal caller to report error
+ return null;
+ }
+
+ // Check if Node always mean true or false in boolean context
+ private static int isAlwaysDefinedBoolean(Node node)
+ {
+ switch (node.getType()) {
+ case Token.FALSE:
+ case Token.NULL:
+ return ALWAYS_FALSE_BOOLEAN;
+ case Token.TRUE:
+ return ALWAYS_TRUE_BOOLEAN;
+ case Token.NUMBER: {
+ double num = node.getDouble();
+ if (num == num && num != 0.0) {
+ return ALWAYS_TRUE_BOOLEAN;
+ } else {
+ return ALWAYS_FALSE_BOOLEAN;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private void checkActivationName(String name, int token)
+ {
+ if (parser.insideFunction()) {
+ boolean activation = false;
+ if ("arguments".equals(name)
+ || (parser.compilerEnv.activationNames != null
+ && parser.compilerEnv.activationNames.containsKey(name)))
+ {
+ activation = true;
+ } else if ("length".equals(name)) {
+ if (token == Token.GETPROP
+ && parser.compilerEnv.getLanguageVersion()
+ == Context.VERSION_1_2)
+ {
+ // Use of "length" in 1.2 requires an activation object.
+ activation = true;
+ }
+ }
+ if (activation) {
+ setRequiresActivation();
+ }
+ }
+ }
+
+ private void setRequiresActivation()
+ {
+ if (parser.insideFunction()) {
+ ((FunctionNode)parser.currentScriptOrFn).itsNeedsActivation = true;
+ }
+ }
+
+ private void setIsGenerator()
+ {
+ if (parser.insideFunction()) {
+ ((FunctionNode)parser.currentScriptOrFn).itsIsGenerator = true;
+ }
+ }
+
+ private Parser parser;
+
+ private static final int LOOP_DO_WHILE = 0;
+ private static final int LOOP_WHILE = 1;
+ private static final int LOOP_FOR = 2;
+
+ private static final int ALWAYS_TRUE_BOOLEAN = 1;
+ private static final int ALWAYS_FALSE_BOOLEAN = -1;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java
new file mode 100644
index 0000000..713fabf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionCall.java
@@ -0,0 +1,55 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * Master for id-based functions that knows their properties and how to
+ * execute them.
+ */
+public interface IdFunctionCall
+{
+ /**
+ * 'thisObj' will be null if invoked as constructor, in which case
+ * instance of Scriptable should be returned
+ */
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args);
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java
new file mode 100644
index 0000000..c578dfa
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdFunctionObject.java
@@ -0,0 +1,189 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+public class IdFunctionObject extends BaseFunction
+{
+
+ static final long serialVersionUID = -5332312783643935019L;
+
+ public IdFunctionObject(IdFunctionCall idcall, Object tag, int id, int arity)
+ {
+ if (arity < 0)
+ throw new IllegalArgumentException();
+
+ this.idcall = idcall;
+ this.tag = tag;
+ this.methodId = id;
+ this.arity = arity;
+ if (arity < 0) throw new IllegalArgumentException();
+ }
+
+ public IdFunctionObject(IdFunctionCall idcall, Object tag, int id,
+ String name, int arity, Scriptable scope)
+ {
+ super(scope, null);
+
+ if (arity < 0)
+ throw new IllegalArgumentException();
+ if (name == null)
+ throw new IllegalArgumentException();
+
+ this.idcall = idcall;
+ this.tag = tag;
+ this.methodId = id;
+ this.arity = arity;
+ this.functionName = name;
+ }
+
+ public void initFunction(String name, Scriptable scope)
+ {
+ if (name == null) throw new IllegalArgumentException();
+ if (scope == null) throw new IllegalArgumentException();
+ this.functionName = name;
+ setParentScope(scope);
+ }
+
+ public final boolean hasTag(Object tag)
+ {
+ return this.tag == tag;
+ }
+
+ public final int methodId()
+ {
+ return methodId;
+ }
+
+ public final void markAsConstructor(Scriptable prototypeProperty)
+ {
+ useCallAsConstructor = true;
+ setImmunePrototypeProperty(prototypeProperty);
+ }
+
+ public final void addAsProperty(Scriptable target)
+ {
+ ScriptableObject.defineProperty(target, functionName, this,
+ ScriptableObject.DONTENUM);
+ }
+
+ public void exportAsScopeProperty()
+ {
+ addAsProperty(getParentScope());
+ }
+
+ public Scriptable getPrototype()
+ {
+ // Lazy initialization of prototype: for native functions this
+ // may not be called at all
+ Scriptable proto = super.getPrototype();
+ if (proto == null) {
+ proto = getFunctionPrototype(getParentScope());
+ setPrototype(proto);
+ }
+ return proto;
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return idcall.execIdCall(this, cx, scope, thisObj, args);
+ }
+
+ public Scriptable createObject(Context cx, Scriptable scope)
+ {
+ if (useCallAsConstructor) {
+ return null;
+ }
+ // Throw error if not explicitly coded to be used as constructor,
+ // to satisfy ECMAScript standard (see bugzilla 202019).
+ // To follow current (2003-05-01) SpiderMonkey behavior, change it to:
+ // return super.createObject(cx, scope);
+ throw ScriptRuntime.typeError1("msg.not.ctor", functionName);
+ }
+
+ String decompile(int indent, int flags)
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ if (!justbody) {
+ sb.append("function ");
+ sb.append(getFunctionName());
+ sb.append("() { ");
+ }
+ sb.append("[native code for ");
+ if (idcall instanceof Scriptable) {
+ Scriptable sobj = (Scriptable)idcall;
+ sb.append(sobj.getClassName());
+ sb.append('.');
+ }
+ sb.append(getFunctionName());
+ sb.append(", arity=");
+ sb.append(getArity());
+ sb.append(justbody ? "]\n" : "] }\n");
+ return sb.toString();
+ }
+
+ public int getArity()
+ {
+ return arity;
+ }
+
+ public int getLength() { return getArity(); }
+
+ public String getFunctionName()
+ {
+ return (functionName == null) ? "" : functionName;
+ }
+
+ public final RuntimeException unknown()
+ {
+ // It is program error to call id-like methods for unknown function
+ return new IllegalArgumentException(
+ "BAD FUNCTION ID="+methodId+" MASTER="+idcall);
+ }
+
+ private final IdFunctionCall idcall;
+ private final Object tag;
+ private final int methodId;
+ private int arity;
+ private boolean useCallAsConstructor;
+ private String functionName;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java
new file mode 100644
index 0000000..2b3ecf3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/IdScriptableObject.java
@@ -0,0 +1,734 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+Base class for native object implementation that uses IdFunctionObject to export its methods to script via <class-name>.prototype object.
+
+Any descendant should implement at least the following methods:
+ findInstanceIdInfo
+ getInstanceIdName
+ execIdCall
+ methodArity
+
+To define non-function properties, the descendant should override
+ getInstanceIdValue
+ setInstanceIdValue
+to get/set property value and provide its default attributes.
+
+
+To customize initializition of constructor and protype objects, descendant
+may override scopeInit or fillConstructorProperties methods.
+
+*/
+public abstract class IdScriptableObject extends ScriptableObject
+ implements IdFunctionCall
+{
+ private transient volatile PrototypeValues prototypeValues;
+
+ private static final class PrototypeValues implements Serializable
+ {
+ static final long serialVersionUID = 3038645279153854371L;
+
+ private static final int VALUE_SLOT = 0;
+ private static final int NAME_SLOT = 1;
+ private static final int SLOT_SPAN = 2;
+
+ private IdScriptableObject obj;
+ private int maxId;
+ private volatile Object[] valueArray;
+ private volatile short[] attributeArray;
+ private volatile int lastFoundId = 1;
+
+ // The following helps to avoid creation of valueArray during runtime
+ // initialization for common case of "constructor" property
+ int constructorId;
+ private IdFunctionObject constructor;
+ private short constructorAttrs;
+
+ PrototypeValues(IdScriptableObject obj, int maxId)
+ {
+ if (obj == null) throw new IllegalArgumentException();
+ if (maxId < 1) throw new IllegalArgumentException();
+ this.obj = obj;
+ this.maxId = maxId;
+ }
+
+ final int getMaxId()
+ {
+ return maxId;
+ }
+
+ final void initValue(int id, String name, Object value, int attributes)
+ {
+ if (!(1 <= id && id <= maxId))
+ throw new IllegalArgumentException();
+ if (name == null)
+ throw new IllegalArgumentException();
+ if (value == NOT_FOUND)
+ throw new IllegalArgumentException();
+ ScriptableObject.checkValidAttributes(attributes);
+ if (obj.findPrototypeId(name) != id)
+ throw new IllegalArgumentException(name);
+
+ if (id == constructorId) {
+ if (!(value instanceof IdFunctionObject)) {
+ throw new IllegalArgumentException("consructor should be initialized with IdFunctionObject");
+ }
+ constructor = (IdFunctionObject)value;
+ constructorAttrs = (short)attributes;
+ return;
+ }
+
+ initSlot(id, name, value, attributes);
+ }
+
+ private void initSlot(int id, String name, Object value,
+ int attributes)
+ {
+ Object[] array = valueArray;
+ if (array == null)
+ throw new IllegalStateException();
+
+ if (value == null) {
+ value = UniqueTag.NULL_VALUE;
+ }
+ int index = (id - 1) * SLOT_SPAN;
+ synchronized (this) {
+ Object value2 = array[index + VALUE_SLOT];
+ if (value2 == null) {
+ array[index + VALUE_SLOT] = value;
+ array[index + NAME_SLOT] = name;
+ attributeArray[id - 1] = (short)attributes;
+ } else {
+ if (!name.equals(array[index + NAME_SLOT]))
+ throw new IllegalStateException();
+ }
+ }
+ }
+
+ final IdFunctionObject createPrecachedConstructor()
+ {
+ if (constructorId != 0) throw new IllegalStateException();
+ constructorId = obj.findPrototypeId("constructor");
+ if (constructorId == 0) {
+ throw new IllegalStateException(
+ "No id for constructor property");
+ }
+ obj.initPrototypeId(constructorId);
+ if (constructor == null) {
+ throw new IllegalStateException(
+ obj.getClass().getName()+".initPrototypeId() did not "
+ +"initialize id="+constructorId);
+ }
+ constructor.initFunction(obj.getClassName(),
+ ScriptableObject.getTopLevelScope(obj));
+ constructor.markAsConstructor(obj);
+ return constructor;
+ }
+
+ final int findId(String name)
+ {
+ Object[] array = valueArray;
+ if (array == null) {
+ return obj.findPrototypeId(name);
+ }
+ int id = lastFoundId;
+ if (name == array[(id - 1) * SLOT_SPAN + NAME_SLOT]) {
+ return id;
+ }
+ id = obj.findPrototypeId(name);
+ if (id != 0) {
+ int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
+ // Make cache to work!
+ array[nameSlot] = name;
+ lastFoundId = id;
+ }
+ return id;
+ }
+
+ final boolean has(int id)
+ {
+ Object[] array = valueArray;
+ if (array == null) {
+ // Not yet initialized, assume all exists
+ return true;
+ }
+ int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
+ Object value = array[valueSlot];
+ if (value == null) {
+ // The particular entry has not been yet initialized
+ return true;
+ }
+ return value != NOT_FOUND;
+ }
+
+ final Object get(int id)
+ {
+ Object value = ensureId(id);
+ if (value == UniqueTag.NULL_VALUE) {
+ value = null;
+ }
+ return value;
+ }
+
+ final void set(int id, Scriptable start, Object value)
+ {
+ if (value == NOT_FOUND) throw new IllegalArgumentException();
+ ensureId(id);
+ int attr = attributeArray[id - 1];
+ if ((attr & READONLY) == 0) {
+ if (start == obj) {
+ if (value == null) {
+ value = UniqueTag.NULL_VALUE;
+ }
+ int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
+ synchronized (this) {
+ valueArray[valueSlot] = value;
+ }
+ }
+ else {
+ int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
+ String name = (String)valueArray[nameSlot];
+ start.put(name, start, value);
+ }
+ }
+ }
+
+ final void delete(int id)
+ {
+ ensureId(id);
+ int attr = attributeArray[id - 1];
+ if ((attr & PERMANENT) == 0) {
+ int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
+ synchronized (this) {
+ valueArray[valueSlot] = NOT_FOUND;
+ attributeArray[id - 1] = EMPTY;
+ }
+ }
+ }
+
+ final int getAttributes(int id)
+ {
+ ensureId(id);
+ return attributeArray[id - 1];
+ }
+
+ final void setAttributes(int id, int attributes)
+ {
+ ScriptableObject.checkValidAttributes(attributes);
+ ensureId(id);
+ synchronized (this) {
+ attributeArray[id - 1] = (short)attributes;
+ }
+ }
+
+ final Object[] getNames(boolean getAll, Object[] extraEntries)
+ {
+ Object[] names = null;
+ int count = 0;
+ for (int id = 1; id <= maxId; ++id) {
+ Object value = ensureId(id);
+ if (getAll || (attributeArray[id - 1] & DONTENUM) == 0) {
+ if (value != NOT_FOUND) {
+ int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
+ String name = (String)valueArray[nameSlot];
+ if (names == null) {
+ names = new Object[maxId];
+ }
+ names[count++] = name;
+ }
+ }
+ }
+ if (count == 0) {
+ return extraEntries;
+ } else if (extraEntries == null || extraEntries.length == 0) {
+ if (count != names.length) {
+ Object[] tmp = new Object[count];
+ System.arraycopy(names, 0, tmp, 0, count);
+ names = tmp;
+ }
+ return names;
+ } else {
+ int extra = extraEntries.length;
+ Object[] tmp = new Object[extra + count];
+ System.arraycopy(extraEntries, 0, tmp, 0, extra);
+ System.arraycopy(names, 0, tmp, extra, count);
+ return tmp;
+ }
+ }
+
+ private Object ensureId(int id)
+ {
+ Object[] array = valueArray;
+ if (array == null) {
+ synchronized (this) {
+ array = valueArray;
+ if (array == null) {
+ array = new Object[maxId * SLOT_SPAN];
+ valueArray = array;
+ attributeArray = new short[maxId];
+ }
+ }
+ }
+ int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
+ Object value = array[valueSlot];
+ if (value == null) {
+ if (id == constructorId) {
+ initSlot(constructorId, "constructor",
+ constructor, constructorAttrs);
+ constructor = null; // no need to refer it any longer
+ } else {
+ obj.initPrototypeId(id);
+ }
+ value = array[valueSlot];
+ if (value == null) {
+ throw new IllegalStateException(
+ obj.getClass().getName()+".initPrototypeId(int id) "
+ +"did not initialize id="+id);
+ }
+ }
+ return value;
+ }
+ }
+
+ public IdScriptableObject()
+ {
+ }
+
+ public IdScriptableObject(Scriptable scope, Scriptable prototype)
+ {
+ super(scope, prototype);
+ }
+
+ protected final Object defaultGet(String name)
+ {
+ return super.get(name, this);
+ }
+
+ protected final void defaultPut(String name, Object value)
+ {
+ super.put(name, this, value);
+ }
+
+ public boolean has(String name, Scriptable start)
+ {
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ int attr = (info >>> 16);
+ if ((attr & PERMANENT) != 0) {
+ return true;
+ }
+ int id = (info & 0xFFFF);
+ return NOT_FOUND != getInstanceIdValue(id);
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ return prototypeValues.has(id);
+ }
+ }
+ return super.has(name, start);
+ }
+
+ public Object get(String name, Scriptable start)
+ {
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ int id = (info & 0xFFFF);
+ return getInstanceIdValue(id);
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ return prototypeValues.get(id);
+ }
+ }
+ return super.get(name, start);
+ }
+
+ public void put(String name, Scriptable start, Object value)
+ {
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ if (start == this && isSealed()) {
+ throw Context.reportRuntimeError1("msg.modify.sealed",
+ name);
+ }
+ int attr = (info >>> 16);
+ if ((attr & READONLY) == 0) {
+ if (start == this) {
+ int id = (info & 0xFFFF);
+ setInstanceIdValue(id, value);
+ }
+ else {
+ start.put(name, start, value);
+ }
+ }
+ return;
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ if (start == this && isSealed()) {
+ throw Context.reportRuntimeError1("msg.modify.sealed",
+ name);
+ }
+ prototypeValues.set(id, start, value);
+ return;
+ }
+ }
+ super.put(name, start, value);
+ }
+
+ public void delete(String name)
+ {
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ // Let the super class to throw exceptions for sealed objects
+ if (!isSealed()) {
+ int attr = (info >>> 16);
+ if ((attr & PERMANENT) == 0) {
+ int id = (info & 0xFFFF);
+ setInstanceIdValue(id, NOT_FOUND);
+ }
+ return;
+ }
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ if (!isSealed()) {
+ prototypeValues.delete(id);
+ }
+ return;
+ }
+ }
+ super.delete(name);
+ }
+
+ public int getAttributes(String name)
+ {
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ int attr = (info >>> 16);
+ return attr;
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ return prototypeValues.getAttributes(id);
+ }
+ }
+ return super.getAttributes(name);
+ }
+
+ public void setAttributes(String name, int attributes)
+ {
+ ScriptableObject.checkValidAttributes(attributes);
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ int currentAttributes = (info >>> 16);
+ if (attributes != currentAttributes) {
+ throw new RuntimeException(
+ "Change of attributes for this id is not supported");
+ }
+ return;
+ }
+ if (prototypeValues != null) {
+ int id = prototypeValues.findId(name);
+ if (id != 0) {
+ prototypeValues.setAttributes(id, attributes);
+ return;
+ }
+ }
+ super.setAttributes(name, attributes);
+ }
+
+ Object[] getIds(boolean getAll)
+ {
+ Object[] result = super.getIds(getAll);
+
+ if (prototypeValues != null) {
+ result = prototypeValues.getNames(getAll, result);
+ }
+
+ int maxInstanceId = getMaxInstanceId();
+ if (maxInstanceId != 0) {
+ Object[] ids = null;
+ int count = 0;
+
+ for (int id = maxInstanceId; id != 0; --id) {
+ String name = getInstanceIdName(id);
+ int info = findInstanceIdInfo(name);
+ if (info != 0) {
+ int attr = (info >>> 16);
+ if ((attr & PERMANENT) == 0) {
+ if (NOT_FOUND == getInstanceIdValue(id)) {
+ continue;
+ }
+ }
+ if (getAll || (attr & DONTENUM) == 0) {
+ if (count == 0) {
+ // Need extra room for no more then [1..id] names
+ ids = new Object[id];
+ }
+ ids[count++] = name;
+ }
+ }
+ }
+ if (count != 0) {
+ if (result.length == 0 && ids.length == count) {
+ result = ids;
+ }
+ else {
+ Object[] tmp = new Object[result.length + count];
+ System.arraycopy(result, 0, tmp, 0, result.length);
+ System.arraycopy(ids, 0, tmp, result.length, count);
+ result = tmp;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get maximum id findInstanceIdInfo can generate.
+ */
+ protected int getMaxInstanceId()
+ {
+ return 0;
+ }
+
+ protected static int instanceIdInfo(int attributes, int id)
+ {
+ return (attributes << 16) | id;
+ }
+
+ /**
+ * Map name to id of instance property.
+ * Should return 0 if not found or the result of
+ * {@link #instanceIdInfo(int, int)}.
+ */
+ protected int findInstanceIdInfo(String name)
+ {
+ return 0;
+ }
+
+ /** Map id back to property name it defines.
+ */
+ protected String getInstanceIdName(int id)
+ {
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ /** Get id value.
+ ** If id value is constant, descendant can call cacheIdValue to store
+ ** value in the permanent cache.
+ ** Default implementation creates IdFunctionObject instance for given id
+ ** and cache its value
+ */
+ protected Object getInstanceIdValue(int id)
+ {
+ throw new IllegalStateException(String.valueOf(id));
+ }
+
+ /**
+ * Set or delete id value. If value == NOT_FOUND , the implementation
+ * should make sure that the following getInstanceIdValue return NOT_FOUND.
+ */
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ throw new IllegalStateException(String.valueOf(id));
+ }
+
+ /** 'thisObj' will be null if invoked as constructor, in which case
+ ** instance of Scriptable should be returned. */
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ throw f.unknown();
+ }
+
+ public final IdFunctionObject exportAsJSClass(int maxPrototypeId,
+ Scriptable scope,
+ boolean sealed)
+ {
+ // Set scope and prototype unless this is top level scope itself
+ if (scope != this && scope != null) {
+ setParentScope(scope);
+ setPrototype(getObjectPrototype(scope));
+ }
+
+ activatePrototypeMap(maxPrototypeId);
+ IdFunctionObject ctor = prototypeValues.createPrecachedConstructor();
+ if (sealed) {
+ sealObject();
+ }
+ fillConstructorProperties(ctor);
+ if (sealed) {
+ ctor.sealObject();
+ }
+ ctor.exportAsScopeProperty();
+ return ctor;
+ }
+
+ public final boolean hasPrototypeMap()
+ {
+ return prototypeValues != null;
+ }
+
+ public final void activatePrototypeMap(int maxPrototypeId)
+ {
+ PrototypeValues values = new PrototypeValues(this, maxPrototypeId);
+ synchronized (this) {
+ if (prototypeValues != null)
+ throw new IllegalStateException();
+ prototypeValues = values;
+ }
+ }
+
+ public final void initPrototypeMethod(Object tag, int id, String name,
+ int arity)
+ {
+ Scriptable scope = ScriptableObject.getTopLevelScope(this);
+ IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
+ prototypeValues.initValue(id, name, f, DONTENUM);
+ }
+
+ public final void initPrototypeConstructor(IdFunctionObject f)
+ {
+ int id = prototypeValues.constructorId;
+ if (id == 0)
+ throw new IllegalStateException();
+ if (f.methodId() != id)
+ throw new IllegalArgumentException();
+ if (isSealed()) { f.sealObject(); }
+ prototypeValues.initValue(id, "constructor", f, DONTENUM);
+ }
+
+ public final void initPrototypeValue(int id, String name, Object value,
+ int attributes)
+ {
+ prototypeValues.initValue(id, name, value, attributes);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ throw new IllegalStateException(String.valueOf(id));
+ }
+
+ protected int findPrototypeId(String name)
+ {
+ throw new IllegalStateException(name);
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ }
+
+ protected void addIdFunctionProperty(Scriptable obj, Object tag, int id,
+ String name, int arity)
+ {
+ Scriptable scope = ScriptableObject.getTopLevelScope(obj);
+ IdFunctionObject f = newIdFunction(tag, id, name, arity, scope);
+ f.addAsProperty(obj);
+ }
+
+ /**
+ * Utility method to construct type error to indicate incompatible call
+ * when converting script thisObj to a particular type is not possible.
+ * Possible usage would be to have a private function like realThis:
+ * <pre>
+ * private static NativeSomething realThis(Scriptable thisObj,
+ * IdFunctionObject f)
+ * {
+ * if (!(thisObj instanceof NativeSomething))
+ * throw incompatibleCallError(f);
+ * return (NativeSomething)thisObj;
+ * }
+ * </pre>
+ * Note that although such function can be implemented universally via
+ * java.lang.Class.isInstance(), it would be much more slower.
+ * @param f function that is attempting to convert 'this'
+ * object.
+ * @return Scriptable object suitable for a check by the instanceof
+ * operator.
+ * @throws RuntimeException if no more instanceof target can be found
+ */
+ protected static EcmaError incompatibleCallError(IdFunctionObject f)
+ {
+ throw ScriptRuntime.typeError1("msg.incompat.call",
+ f.getFunctionName());
+ }
+
+ private IdFunctionObject newIdFunction(Object tag, int id, String name,
+ int arity, Scriptable scope)
+ {
+ IdFunctionObject f = new IdFunctionObject(this, tag, id, name, arity,
+ scope);
+ if (isSealed()) { f.sealObject(); }
+ return f;
+ }
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException
+ {
+ stream.defaultReadObject();
+ int maxPrototypeId = stream.readInt();
+ if (maxPrototypeId != 0) {
+ activatePrototypeMap(maxPrototypeId);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream stream)
+ throws IOException
+ {
+ stream.defaultWriteObject();
+ int maxPrototypeId = 0;
+ if (prototypeValues != null) {
+ maxPrototypeId = prototypeValues.getMaxId();
+ }
+ stream.writeInt(maxPrototypeId);
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java
new file mode 100644
index 0000000..294deab
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ImporterTopLevel.java
@@ -0,0 +1,318 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Matthias Radestock
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Class ImporterTopLevel
+ *
+ * This class defines a ScriptableObject that can be instantiated
+ * as a top-level ("global") object to provide functionality similar
+ * to Java's "import" statement.
+ * <p>
+ * This class can be used to create a top-level scope using the following code:
+ * <pre>
+ * Scriptable scope = new ImporterTopLevel(cx);
+ * </pre>
+ * Then JavaScript code will have access to the following methods:
+ * <ul>
+ * <li>importClass - will "import" a class by making its unqualified name
+ * available as a property of the top-level scope
+ * <li>importPackage - will "import" all the classes of the package by
+ * searching for unqualified names as classes qualified
+ * by the given package.
+ * </ul>
+ * The following code from the shell illustrates this use:
+ * <pre>
+ * js> importClass(java.io.File)
+ * js> f = new File('help.txt')
+ * help.txt
+ * js> importPackage(java.util)
+ * js> v = new Vector()
+ * []
+ *
+ * @author Norris Boyd
+ */
+public class ImporterTopLevel extends IdScriptableObject
+{
+ static final long serialVersionUID = -9095380847465315412L;
+
+ private static final Object IMPORTER_TAG = new Object();
+
+ public ImporterTopLevel() { }
+
+ public ImporterTopLevel(Context cx) {
+ this(cx, false);
+ }
+
+ public ImporterTopLevel(Context cx, boolean sealed)
+ {
+ initStandardObjects(cx, sealed);
+ }
+
+ public String getClassName()
+ {
+ return (topScopeFlag) ? "global" : "JavaImporter";
+ }
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+ ImporterTopLevel obj = new ImporterTopLevel();
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ public void initStandardObjects(Context cx, boolean sealed)
+ {
+ // Assume that Context.initStandardObjects initialize JavaImporter
+ // property lazily so the above init call is not yet called
+ cx.initStandardObjects(this, sealed);
+ topScopeFlag = true;
+ // If seal is true then exportAsJSClass(cx, seal) would seal
+ // this obj. Since this is scope as well, it would not allow
+ // to add variables.
+ IdFunctionObject ctor = exportAsJSClass(MAX_PROTOTYPE_ID, this, false);
+ if (sealed) {
+ ctor.sealObject();
+ }
+ // delete "constructor" defined by exportAsJSClass so "constructor"
+ // name would refer to Object.constructor
+ // and not to JavaImporter.prototype.constructor.
+ delete("constructor");
+ }
+
+ public boolean has(String name, Scriptable start) {
+ return super.has(name, start)
+ || getPackageProperty(name, start) != NOT_FOUND;
+ }
+
+ public Object get(String name, Scriptable start) {
+ Object result = super.get(name, start);
+ if (result != NOT_FOUND)
+ return result;
+ result = getPackageProperty(name, start);
+ return result;
+ }
+
+ private Object getPackageProperty(String name, Scriptable start) {
+ Object result = NOT_FOUND;
+ Object[] elements;
+ synchronized (importedPackages) {
+ elements = importedPackages.toArray();
+ }
+ for (int i=0; i < elements.length; i++) {
+ NativeJavaPackage p = (NativeJavaPackage) elements[i];
+ Object v = p.getPkgProperty(name, start, false);
+ if (v != null && !(v instanceof NativeJavaPackage)) {
+ if (result == NOT_FOUND) {
+ result = v;
+ } else {
+ throw Context.reportRuntimeError2(
+ "msg.ambig.import", result.toString(), v.toString());
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @deprecated Kept only for compatibility.
+ */
+ public void importPackage(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ {
+ js_importPackage(args);
+ }
+
+ private Object js_construct(Scriptable scope, Object[] args)
+ {
+ ImporterTopLevel result = new ImporterTopLevel();
+ for (int i = 0; i != args.length; ++i) {
+ Object arg = args[i];
+ if (arg instanceof NativeJavaClass) {
+ result.importClass((NativeJavaClass)arg);
+ } else if (arg instanceof NativeJavaPackage) {
+ result.importPackage((NativeJavaPackage)arg);
+ } else {
+ throw Context.reportRuntimeError1(
+ "msg.not.class.not.pkg", Context.toString(arg));
+ }
+ }
+ // set explicitly prototype and scope
+ // as otherwise in top scope mode BaseFunction.construct
+ // would keep them set to null. It also allow to use
+ // JavaImporter without new and still get properly
+ // initialized object.
+ result.setParentScope(scope);
+ result.setPrototype(this);
+ return result;
+ }
+
+ private Object js_importClass(Object[] args)
+ {
+ for (int i = 0; i != args.length; i++) {
+ Object arg = args[i];
+ if (!(arg instanceof NativeJavaClass)) {
+ throw Context.reportRuntimeError1(
+ "msg.not.class", Context.toString(arg));
+ }
+ importClass((NativeJavaClass)arg);
+ }
+ return Undefined.instance;
+ }
+
+ private Object js_importPackage(Object[] args)
+ {
+ for (int i = 0; i != args.length; i++) {
+ Object arg = args[i];
+ if (!(arg instanceof NativeJavaPackage)) {
+ throw Context.reportRuntimeError1(
+ "msg.not.pkg", Context.toString(arg));
+ }
+ importPackage((NativeJavaPackage)arg);
+ }
+ return Undefined.instance;
+ }
+
+ private void importPackage(NativeJavaPackage pkg)
+ {
+ if(pkg == null) {
+ return;
+ }
+ synchronized (importedPackages) {
+ for (int j = 0; j != importedPackages.size(); j++) {
+ if (pkg.equals(importedPackages.get(j))) {
+ return;
+ }
+ }
+ importedPackages.add(pkg);
+ }
+ }
+
+ private void importClass(NativeJavaClass cl)
+ {
+ String s = cl.getClassObject().getName();
+ String n = s.substring(s.lastIndexOf('.')+1);
+ Object val = get(n, this);
+ if (val != NOT_FOUND && val != cl) {
+ throw Context.reportRuntimeError1("msg.prop.defined", n);
+ }
+ //defineProperty(n, cl, DONTENUM);
+ put(n, this, cl);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=0; s="constructor"; break;
+ case Id_importClass: arity=1; s="importClass"; break;
+ case Id_importPackage: arity=1; s="importPackage"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(IMPORTER_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(IMPORTER_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return js_construct(scope, args);
+
+ case Id_importClass:
+ return realThis(thisObj, f).js_importClass(args);
+
+ case Id_importPackage:
+ return realThis(thisObj, f).js_importPackage(args);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private ImporterTopLevel realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if (topScopeFlag) {
+ // when used as top scope importPackage and importClass are global
+ // function that ignore thisObj
+ return this;
+ }
+ if (!(thisObj instanceof ImporterTopLevel))
+ throw incompatibleCallError(f);
+ return (ImporterTopLevel)thisObj;
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:24 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==11) {
+ c=s.charAt(0);
+ if (c=='c') { X="constructor";id=Id_constructor; }
+ else if (c=='i') { X="importClass";id=Id_importClass; }
+ }
+ else if (s_length==13) { X="importPackage";id=Id_importPackage; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_importClass = 2,
+ Id_importPackage = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+// #/string_id_map#
+
+ private ObjArray importedPackages = new ObjArray();
+ private boolean topScopeFlag;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java
new file mode 100644
index 0000000..c73db34
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InformativeParser.java
@@ -0,0 +1,225 @@
+package org.mozilla.javascript;
+
+import java.io.IOException;
+
+/**
+ * Subclass of Rhino's Parser that saves information about the token stream
+ * and error message to allow more helpful error messages.
+ *
+ * @author David Greenspan for AppJet
+ */
+
+/*
+ This class is written with speed in mind, to some extent. Rhino's tokenizer
+ is pretty efficient, and we wouldn't want to slow it down by, for example,
+ creating a TokenInfo object on the heap for every token seen.
+ */
+
+/*APPJET*/
+public class InformativeParser extends Parser {
+
+ public static class InformativeEvaluatorException extends EvaluatorException {
+ final ParseErrorInfo pei;
+
+ InformativeEvaluatorException(String errorMessage,
+ String sourceName, int lineNumber,
+ String lineSource, int columnNumber,
+ ParseErrorInfo peInfo) {
+ super(errorMessage, sourceName,
+ lineNumber, lineSource, columnNumber);
+ pei = peInfo;
+ }
+
+ public ParseErrorInfo getParseErrorInfo() {
+ return pei;
+ }
+ }
+
+ public static class ParseErrorInfo {
+ ParseErrorInfo() {}
+
+ String messageId = null;
+ String messageArg = null;
+
+ final int tokenMaxHistory = 10;
+ // ring buffers
+ final int[] tokenTypes = new int[tokenMaxHistory];
+ final String[] tokenStrings = new String[tokenMaxHistory];
+ final double[] tokenNumbers = new double[tokenMaxHistory];
+ final int[] tokenLineNumbers = new int[tokenMaxHistory];
+ final int[] tokenLineOffsets = new int[tokenMaxHistory];
+ int nextBufPos = 0;
+ int historyLength = 0;
+ boolean tokenPeeking = false;
+ int peekSlot;
+
+ void reportPeekToken(int type, String str, double num, int lineno,
+ int lineOffset) {
+ if (! tokenPeeking) {
+ peekSlot = nextBufPos;
+ tokenTypes[nextBufPos] = type;
+ tokenStrings[nextBufPos] = str;
+ tokenNumbers[nextBufPos] = num;
+ tokenLineNumbers[nextBufPos] = lineno;
+ tokenLineOffsets[nextBufPos] = lineOffset;
+
+ nextBufPos++;
+ if (nextBufPos == tokenMaxHistory) nextBufPos = 0;
+ if (historyLength < tokenMaxHistory) historyLength++;
+ tokenPeeking = true;
+ }
+ }
+
+ void reportConsumeToken() {
+ tokenPeeking = false;
+ }
+
+ private TokenInfo backToken(int n) {
+ // 0 is most recent token added to history
+ if (n >= historyLength) return null;
+ int i = (nextBufPos - 1 - n);
+ while (i < 0) i += tokenMaxHistory;
+ return new TokenInfo(tokenTypes[i], tokenStrings[i],
+ tokenNumbers[i], tokenLineNumbers[i],
+ tokenLineOffsets[i]);
+ }
+
+ public String getMessageId() { return messageId; }
+ public String getMessageArg() { return messageArg; }
+ public TokenInfo getPeekToken() {
+ if (tokenPeeking) return backToken(0);
+ return null;
+ }
+ public TokenInfo getPrevToken(int n) {
+ // 1 = last non-peek token seen, 2 = before that, etc.
+ if (! tokenPeeking) n--;
+ return backToken(n);
+ }
+ public TokenInfo getPrevToken() {
+ return getPrevToken(1);
+ }
+ }
+
+ public static class TokenInfo {
+ private int type, lineno, lineOffset;
+ private String str;
+ private double num;
+ TokenInfo(int type, String str, double num, int lineno,
+ int lineOffset) {
+ this.type = type; this.str = str; this.num = num;
+ this.lineno = lineno; this.lineOffset = lineOffset;
+ }
+ public int getType() { return type; }
+ public int getLineNumber() { return lineno; }
+ public int getLineOffset() { return lineOffset; }
+ public double getNumber() { return num; }
+ public String getString() { return str; }
+ }
+
+ ParseErrorInfo info = new ParseErrorInfo();
+
+ void doErrorReporterError(String message, String sourceURI, int line,
+ String lineText, int lineOffset) {
+
+ throw new InformativeEvaluatorException(message, sourceURI, line,
+ lineText, lineOffset, info);
+
+ }
+
+ public InformativeParser(CompilerEnvirons compilerEnv) {
+ // we override most calls to the parent's ErrorReporter anyway
+ super(compilerEnv, DefaultErrorReporter.instance);
+ }
+
+ @Override int peekToken() throws IOException {
+ int tt = super.peekToken();
+ info.reportPeekToken(tt, ts.getString(), ts.getNumber(),
+ ts.getLineno(), ts.getOffset());
+ return tt;
+ }
+ @Override void consumeToken() {
+ super.consumeToken();
+ info.reportConsumeToken();
+ }
+
+ @Override void addWarning(String messageId, String messageArg)
+ {
+ info.messageId = messageId;
+ info.messageArg = messageArg;
+
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ doErrorReporterError(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+ else { /* don't report */ }
+ }
+
+ @Override void addError(String messageId)
+ {
+ info.messageId = messageId;
+
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ doErrorReporterError(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ @Override void addError(String messageId, String messageArg)
+ {
+ info.messageId = messageId;
+ info.messageArg = messageArg;
+
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ doErrorReporterError(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ @Override protected Decompiler createDecompiler(CompilerEnvirons env) {
+ return new MyDecompiler();
+ }
+
+ public static final ErrorReporter THROW_INFORMATIVE_ERRORS
+ = new ErrorReporter() {
+ public void warning(String message, String sourceURI, int line,
+ String lineText, int lineOffset) {
+ DefaultErrorReporter.instance.warning
+ (message, sourceURI, line, lineText, lineOffset);
+ }
+ public void error(String message, String sourceURI, int line,
+ String lineText, int lineOffset) {
+ DefaultErrorReporter.instance.error
+ (message, sourceURI, line, lineText, lineOffset);
+ }
+ public EvaluatorException runtimeError(String message,
+ String sourceURI,
+ int line, String lineText,
+ int lineOffset) {
+ return DefaultErrorReporter.instance.runtimeError
+ (message, sourceURI, line, lineText, lineOffset);
+ }
+
+ };
+
+ public static Parser makeParser(CompilerEnvirons compilerEnv,
+ ErrorReporter errorReporter) {
+ if (errorReporter == THROW_INFORMATIVE_ERRORS) {
+ return new InformativeParser(compilerEnv);
+ }
+ else {
+ return new Parser(compilerEnv, errorReporter);
+ }
+ }
+
+ private class MyDecompiler extends Decompiler {
+ @Override void addRegexp(String regexp, String flags) {
+ super.addRegexp(regexp, flags);
+ String str = '/'+regexp+'/'+flags;
+ info.reportPeekToken(Token.REGEXP, str, ts.getNumber(),
+ ts.getLineno(), ts.getOffset());
+ info.reportConsumeToken();
+ }
+ }
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java
new file mode 100644
index 0000000..877e6a2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterfaceAdapter.java
@@ -0,0 +1,156 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.Method;
+
+/**
+ * Adapter to use JS function as implementation of Java interfaces with
+ * single method or multiple methods with the same signature.
+ */
+public class InterfaceAdapter
+{
+ private final Object proxyHelper;
+
+ /**
+ * Make glue object implementing interface cl that will
+ * call the supplied JS function when called.
+ * Only interfaces were all methods have the same signature is supported.
+ *
+ * @return The glue object or null if <tt>cl</tt> is not interface or
+ * has methods with different signatures.
+ */
+ static Object create(Context cx, Class cl, Callable function)
+ {
+ if (!cl.isInterface()) throw new IllegalArgumentException();
+
+ Scriptable topScope = ScriptRuntime.getTopCallScope(cx);
+ ClassCache cache = ClassCache.get(topScope);
+ InterfaceAdapter adapter;
+ adapter = (InterfaceAdapter)cache.getInterfaceAdapter(cl);
+ ContextFactory cf = cx.getFactory();
+ if (adapter == null) {
+ Method[] methods = cl.getMethods();
+ if (methods.length == 0) {
+ throw Context.reportRuntimeError2(
+ "msg.no.empty.interface.conversion",
+ String.valueOf(function),
+ cl.getClass().getName());
+ }
+ boolean canCallFunction = false;
+ canCallFunctionChecks: {
+ Class[] argTypes = methods[0].getParameterTypes();
+ // check that the rest of methods has the same signature
+ for (int i = 1; i != methods.length; ++i) {
+ Class[] types2 = methods[i].getParameterTypes();
+ if (types2.length != argTypes.length) {
+ break canCallFunctionChecks;
+ }
+ for (int j = 0; j != argTypes.length; ++j) {
+ if (types2[j] != argTypes[j]) {
+ break canCallFunctionChecks;
+ }
+ }
+ }
+ canCallFunction= true;
+ }
+ if (!canCallFunction) {
+ throw Context.reportRuntimeError2(
+ "msg.no.function.interface.conversion",
+ String.valueOf(function),
+ cl.getClass().getName());
+ }
+ adapter = new InterfaceAdapter(cf, cl);
+ cache.cacheInterfaceAdapter(cl, adapter);
+ }
+ return VMBridge.instance.newInterfaceProxy(
+ adapter.proxyHelper, cf, adapter, function, topScope);
+ }
+
+ private InterfaceAdapter(ContextFactory cf, Class cl)
+ {
+ this.proxyHelper
+ = VMBridge.instance.getInterfaceProxyHelper(
+ cf, new Class[] { cl });
+ }
+
+ public Object invoke(ContextFactory cf,
+ final Object target,
+ final Scriptable topScope,
+ final Method method,
+ final Object[] args)
+ {
+ ContextAction action = new ContextAction() {
+ public Object run(Context cx)
+ {
+ return invokeImpl(cx, target, topScope, method, args);
+ }
+ };
+ return cf.call(action);
+ }
+
+ Object invokeImpl(Context cx,
+ Object target,
+ Scriptable topScope,
+ Method method,
+ Object[] args)
+ {
+ int N = (args == null) ? 0 : args.length;
+
+ Callable function = (Callable)target;
+ Scriptable thisObj = topScope;
+ Object[] jsargs = new Object[N + 1];
+ jsargs[N] = method.getName();
+ if (N != 0) {
+ WrapFactory wf = cx.getWrapFactory();
+ for (int i = 0; i != N; ++i) {
+ jsargs[i] = wf.wrap(cx, topScope, args[i], null);
+ }
+ }
+
+ Object result = function.call(cx, topScope, thisObj, jsargs);
+ Class javaResultType = method.getReturnType();
+ if (javaResultType == Void.TYPE) {
+ result = null;
+ } else {
+ result = Context.jsToJava(result, javaResultType);
+ }
+ return result;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java
new file mode 100644
index 0000000..db84299
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpretedFunction.java
@@ -0,0 +1,221 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Bob Jervis
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import org.mozilla.javascript.debug.DebuggableScript;
+
+final class InterpretedFunction extends NativeFunction implements Script
+{
+ static final long serialVersionUID = 541475680333911468L;
+
+ InterpreterData idata;
+ SecurityController securityController;
+ Object securityDomain;
+ Scriptable[] functionRegExps;
+
+ private InterpretedFunction(InterpreterData idata,
+ Object staticSecurityDomain)
+ {
+ this.idata = idata;
+
+ // Always get Context from the current thread to
+ // avoid security breaches via passing mangled Context instances
+ // with bogus SecurityController
+ Context cx = Context.getContext();
+ SecurityController sc = cx.getSecurityController();
+ Object dynamicDomain;
+ if (sc != null) {
+ dynamicDomain = sc.getDynamicSecurityDomain(staticSecurityDomain);
+ } else {
+ if (staticSecurityDomain != null) {
+ throw new IllegalArgumentException();
+ }
+ dynamicDomain = null;
+ }
+
+ this.securityController = sc;
+ this.securityDomain = dynamicDomain;
+ }
+
+ private InterpretedFunction(InterpretedFunction parent, int index)
+ {
+ this.idata = parent.idata.itsNestedFunctions[index];
+ this.securityController = parent.securityController;
+ this.securityDomain = parent.securityDomain;
+ }
+
+ /**
+ * Create script from compiled bytecode.
+ */
+ static InterpretedFunction createScript(InterpreterData idata,
+ Object staticSecurityDomain)
+ {
+ InterpretedFunction f;
+ f = new InterpretedFunction(idata, staticSecurityDomain);
+ return f;
+ }
+
+ /**
+ * Create function compiled from Function(...) constructor.
+ */
+ static InterpretedFunction createFunction(Context cx,Scriptable scope,
+ InterpreterData idata,
+ Object staticSecurityDomain)
+ {
+ InterpretedFunction f;
+ f = new InterpretedFunction(idata, staticSecurityDomain);
+ f.initInterpretedFunction(cx, scope);
+ return f;
+ }
+
+ /**
+ * Create function embedded in script or another function.
+ */
+ static InterpretedFunction createFunction(Context cx, Scriptable scope,
+ InterpretedFunction parent,
+ int index)
+ {
+ InterpretedFunction f = new InterpretedFunction(parent, index);
+ f.initInterpretedFunction(cx, scope);
+ return f;
+ }
+
+ Scriptable[] createRegExpWraps(Context cx, Scriptable scope)
+ {
+ if (idata.itsRegExpLiterals == null) Kit.codeBug();
+
+ RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
+ int N = idata.itsRegExpLiterals.length;
+ Scriptable[] array = new Scriptable[N];
+ for (int i = 0; i != N; ++i) {
+ array[i] = rep.wrapRegExp(cx, scope, idata.itsRegExpLiterals[i]);
+ }
+ return array;
+ }
+
+ private void initInterpretedFunction(Context cx, Scriptable scope)
+ {
+ initScriptFunction(cx, scope);
+ if (idata.itsRegExpLiterals != null) {
+ functionRegExps = createRegExpWraps(cx, scope);
+ }
+ }
+
+ public String getFunctionName()
+ {
+ return (idata.itsName == null) ? "" : idata.itsName;
+ }
+
+ /**
+ * Calls the function.
+ * @param cx the current context
+ * @param scope the scope used for the call
+ * @param thisObj the value of "this"
+ * @param args function arguments. Must not be null. You can use
+ * {@link ScriptRuntime#emptyArgs} to pass empty arguments.
+ * @return the result of the function call.
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ if (!ScriptRuntime.hasTopCall(cx)) {
+ return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
+ }
+ return Interpreter.interpret(this, cx, scope, thisObj, args);
+ }
+
+ public Object exec(Context cx, Scriptable scope)
+ {
+ if (idata.itsFunctionType != 0) {
+ // Can only be applied to scripts
+ throw new IllegalStateException();
+ }
+ if (!ScriptRuntime.hasTopCall(cx)) {
+ // It will go through "call" path. but they are equivalent
+ return ScriptRuntime.doTopCall(
+ this, cx, scope, scope, ScriptRuntime.emptyArgs);
+ }
+ return Interpreter.interpret(
+ this, cx, scope, scope, ScriptRuntime.emptyArgs);
+ }
+
+ public String getEncodedSource()
+ {
+ return Interpreter.getEncodedSource(idata);
+ }
+
+ public DebuggableScript getDebuggableView()
+ {
+ return idata;
+ }
+
+ public Object resumeGenerator(Context cx, Scriptable scope, int operation,
+ Object state, Object value)
+ {
+ return Interpreter.resumeGenerator(cx, scope, operation, state, value);
+ }
+
+ protected int getLanguageVersion()
+ {
+ return idata.languageVersion;
+ }
+
+ protected int getParamCount()
+ {
+ return idata.argCount;
+ }
+
+ protected int getParamAndVarCount()
+ {
+ return idata.argNames.length;
+ }
+
+ protected String getParamOrVarName(int index)
+ {
+ return idata.argNames[index];
+ }
+
+ protected boolean getParamOrVarConst(int index)
+ {
+ return idata.argIsConst[index];
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java
new file mode 100644
index 0000000..a68c025
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Interpreter.java
@@ -0,0 +1,4643 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ * Norris Boyd
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Roger Lawrence
+ * Milen Nankov
+ * Hannes Wallnoefer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.PrintStream;
+import java.io.Serializable;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.mozilla.javascript.continuations.Continuation;
+import org.mozilla.javascript.debug.DebugFrame;
+
+public class Interpreter implements Evaluator
+{
+
+// Additional interpreter-specific codes
+
+ private static final int
+
+ // Stack: ... value1 -> ... value1 value1
+ Icode_DUP = -1,
+
+ // Stack: ... value2 value1 -> ... value2 value1 value2 value1
+ Icode_DUP2 = -2,
+
+ // Stack: ... value2 value1 -> ... value1 value2
+ Icode_SWAP = -3,
+
+ // Stack: ... value1 -> ...
+ Icode_POP = -4,
+
+ // Store stack top into return register and then pop it
+ Icode_POP_RESULT = -5,
+
+ // To jump conditionally and pop additional stack value
+ Icode_IFEQ_POP = -6,
+
+ // various types of ++/--
+ Icode_VAR_INC_DEC = -7,
+ Icode_NAME_INC_DEC = -8,
+ Icode_PROP_INC_DEC = -9,
+ Icode_ELEM_INC_DEC = -10,
+ Icode_REF_INC_DEC = -11,
+
+ // load/save scope from/to local
+ Icode_SCOPE_LOAD = -12,
+ Icode_SCOPE_SAVE = -13,
+
+ Icode_TYPEOFNAME = -14,
+
+ // helper for function calls
+ Icode_NAME_AND_THIS = -15,
+ Icode_PROP_AND_THIS = -16,
+ Icode_ELEM_AND_THIS = -17,
+ Icode_VALUE_AND_THIS = -18,
+
+ // Create closure object for nested functions
+ Icode_CLOSURE_EXPR = -19,
+ Icode_CLOSURE_STMT = -20,
+
+ // Special calls
+ Icode_CALLSPECIAL = -21,
+
+ // To return undefined value
+ Icode_RETUNDEF = -22,
+
+ // Exception handling implementation
+ Icode_GOSUB = -23,
+ Icode_STARTSUB = -24,
+ Icode_RETSUB = -25,
+
+ // To indicating a line number change in icodes.
+ Icode_LINE = -26,
+
+ // To store shorts and ints inline
+ Icode_SHORTNUMBER = -27,
+ Icode_INTNUMBER = -28,
+
+ // To create and populate array to hold values for [] and {} literals
+ Icode_LITERAL_NEW = -29,
+ Icode_LITERAL_SET = -30,
+
+ // Array literal with skipped index like [1,,2]
+ Icode_SPARE_ARRAYLIT = -31,
+
+ // Load index register to prepare for the following index operation
+ Icode_REG_IND_C0 = -32,
+ Icode_REG_IND_C1 = -33,
+ Icode_REG_IND_C2 = -34,
+ Icode_REG_IND_C3 = -35,
+ Icode_REG_IND_C4 = -36,
+ Icode_REG_IND_C5 = -37,
+ Icode_REG_IND1 = -38,
+ Icode_REG_IND2 = -39,
+ Icode_REG_IND4 = -40,
+
+ // Load string register to prepare for the following string operation
+ Icode_REG_STR_C0 = -41,
+ Icode_REG_STR_C1 = -42,
+ Icode_REG_STR_C2 = -43,
+ Icode_REG_STR_C3 = -44,
+ Icode_REG_STR1 = -45,
+ Icode_REG_STR2 = -46,
+ Icode_REG_STR4 = -47,
+
+ // Version of getvar/setvar that read var index directly from bytecode
+ Icode_GETVAR1 = -48,
+ Icode_SETVAR1 = -49,
+
+ // Load unefined
+ Icode_UNDEF = -50,
+ Icode_ZERO = -51,
+ Icode_ONE = -52,
+
+ // entrance and exit from .()
+ Icode_ENTERDQ = -53,
+ Icode_LEAVEDQ = -54,
+
+ Icode_TAIL_CALL = -55,
+
+ // Clear local to allow GC its context
+ Icode_LOCAL_CLEAR = -56,
+
+ // Literal get/set
+ Icode_LITERAL_GETTER = -57,
+ Icode_LITERAL_SETTER = -58,
+
+ // const
+ Icode_SETCONST = -59,
+ Icode_SETCONSTVAR = -60,
+ Icode_SETCONSTVAR1 = -61,
+
+ // Generator opcodes (along with Token.YIELD)
+ Icode_GENERATOR = -62,
+ Icode_GENERATOR_END = -63,
+
+ Icode_DEBUGGER = -64,
+
+ // Last icode
+ MIN_ICODE = -64;
+
+ // data for parsing
+
+ private CompilerEnvirons compilerEnv;
+
+ private boolean itsInFunctionFlag;
+ private boolean itsInTryFlag;
+
+ private InterpreterData itsData;
+ private ScriptOrFnNode scriptOrFn;
+ private int itsICodeTop;
+ private int itsStackDepth;
+ private int itsLineNumber;
+ private int itsDoubleTableTop;
+ private ObjToIntMap itsStrings = new ObjToIntMap(20);
+ private int itsLocalTop;
+
+ private static final int MIN_LABEL_TABLE_SIZE = 32;
+ private static final int MIN_FIXUP_TABLE_SIZE = 40;
+ private int[] itsLabelTable;
+ private int itsLabelTableTop;
+// itsFixupTable[i] = (label_index << 32) | fixup_site
+ private long[] itsFixupTable;
+ private int itsFixupTableTop;
+ private ObjArray itsLiteralIds = new ObjArray();
+
+ private int itsExceptionTableTop;
+ private static final int EXCEPTION_TRY_START_SLOT = 0;
+ private static final int EXCEPTION_TRY_END_SLOT = 1;
+ private static final int EXCEPTION_HANDLER_SLOT = 2;
+ private static final int EXCEPTION_TYPE_SLOT = 3;
+ private static final int EXCEPTION_LOCAL_SLOT = 4;
+ private static final int EXCEPTION_SCOPE_SLOT = 5;
+ // SLOT_SIZE: space for try start/end, handler, start, handler type,
+ // exception local and scope local
+ private static final int EXCEPTION_SLOT_SIZE = 6;
+
+// ECF_ or Expression Context Flags constants: for now only TAIL is available
+ private static final int ECF_TAIL = 1 << 0;
+
+ /**
+ * Class to hold data corresponding to one interpreted call stack frame.
+ */
+ private static class CallFrame implements Cloneable, Serializable
+ {
+ static final long serialVersionUID = -2843792508994958978L;
+
+ CallFrame parentFrame;
+ // amount of stack frames before this one on the interpretation stack
+ int frameIndex;
+ // If true indicates read-only frame that is a part of continuation
+ boolean frozen;
+
+ InterpretedFunction fnOrScript;
+ InterpreterData idata;
+
+// Stack structure
+// stack[0 <= i < localShift]: arguments and local variables
+// stack[localShift <= i <= emptyStackTop]: used for local temporaries
+// stack[emptyStackTop < i < stack.length]: stack data
+// sDbl[i]: if stack[i] is UniqueTag.DOUBLE_MARK, sDbl[i] holds the number value
+
+ Object[] stack;
+ int[] stackAttributes;
+ double[] sDbl;
+ CallFrame varSource; // defaults to this unless continuation frame
+ int localShift;
+ int emptyStackTop;
+
+ DebugFrame debuggerFrame;
+ boolean useActivation;
+
+ Scriptable thisObj;
+ Scriptable[] scriptRegExps;
+
+// The values that change during interpretation
+
+ Object result;
+ double resultDbl;
+ int pc;
+ int pcPrevBranch;
+ int pcSourceLineStart;
+ Scriptable scope;
+
+ int savedStackTop;
+ int savedCallOp;
+ Object throwable;
+
+ CallFrame cloneFrozen()
+ {
+ if (!frozen) Kit.codeBug();
+
+ CallFrame copy;
+ try {
+ copy = (CallFrame)clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new IllegalStateException();
+ }
+
+ // clone stack but keep varSource to point to values
+ // from this frame to share variables.
+
+ copy.stack = stack.clone();
+ copy.stackAttributes = stackAttributes.clone();
+ copy.sDbl = sDbl.clone();
+
+ copy.frozen = false;
+ return copy;
+ }
+ }
+
+ private static final class ContinuationJump implements Serializable
+ {
+ static final long serialVersionUID = 7687739156004308247L;
+
+ CallFrame capturedFrame;
+ CallFrame branchFrame;
+ Object result;
+ double resultDbl;
+
+ ContinuationJump(Continuation c, CallFrame current)
+ {
+ this.capturedFrame = (CallFrame)c.getImplementation();
+ if (this.capturedFrame == null || current == null) {
+ // Continuation and current execution does not share
+ // any frames if there is nothing to capture or
+ // if there is no currently executed frames
+ this.branchFrame = null;
+ } else {
+ // Search for branch frame where parent frame chains starting
+ // from captured and current meet.
+ CallFrame chain1 = this.capturedFrame;
+ CallFrame chain2 = current;
+
+ // First work parents of chain1 or chain2 until the same
+ // frame depth.
+ int diff = chain1.frameIndex - chain2.frameIndex;
+ if (diff != 0) {
+ if (diff < 0) {
+ // swap to make sure that
+ // chain1.frameIndex > chain2.frameIndex and diff > 0
+ chain1 = current;
+ chain2 = this.capturedFrame;
+ diff = -diff;
+ }
+ do {
+ chain1 = chain1.parentFrame;
+ } while (--diff != 0);
+ if (chain1.frameIndex != chain2.frameIndex) Kit.codeBug();
+ }
+
+ // Now walk parents in parallel until a shared frame is found
+ // or until the root is reached.
+ while (chain1 != chain2 && chain1 != null) {
+ chain1 = chain1.parentFrame;
+ chain2 = chain2.parentFrame;
+ }
+
+ this.branchFrame = chain1;
+ if (this.branchFrame != null && !this.branchFrame.frozen)
+ Kit.codeBug();
+ }
+ }
+ }
+
+ private static CallFrame captureFrameForGenerator(CallFrame frame) {
+ frame.frozen = true;
+ CallFrame result = frame.cloneFrozen();
+ frame.frozen = false;
+
+ // now isolate this frame from its previous context
+ result.parentFrame = null;
+ result.frameIndex = 0;
+
+ return result;
+ }
+
+ static {
+ // Checks for byte code consistencies, good compiler can eliminate them
+
+ if (Token.LAST_BYTECODE_TOKEN > 127) {
+ String str = "Violation of Token.LAST_BYTECODE_TOKEN <= 127";
+ System.err.println(str);
+ throw new IllegalStateException(str);
+ }
+ if (MIN_ICODE < -128) {
+ String str = "Violation of Interpreter.MIN_ICODE >= -128";
+ System.err.println(str);
+ throw new IllegalStateException(str);
+ }
+ }
+
+ private static String bytecodeName(int bytecode)
+ {
+ if (!validBytecode(bytecode)) {
+ throw new IllegalArgumentException(String.valueOf(bytecode));
+ }
+
+ if (!Token.printICode) {
+ return String.valueOf(bytecode);
+ }
+
+ if (validTokenCode(bytecode)) {
+ return Token.name(bytecode);
+ }
+
+ switch (bytecode) {
+ case Icode_DUP: return "DUP";
+ case Icode_DUP2: return "DUP2";
+ case Icode_SWAP: return "SWAP";
+ case Icode_POP: return "POP";
+ case Icode_POP_RESULT: return "POP_RESULT";
+ case Icode_IFEQ_POP: return "IFEQ_POP";
+ case Icode_VAR_INC_DEC: return "VAR_INC_DEC";
+ case Icode_NAME_INC_DEC: return "NAME_INC_DEC";
+ case Icode_PROP_INC_DEC: return "PROP_INC_DEC";
+ case Icode_ELEM_INC_DEC: return "ELEM_INC_DEC";
+ case Icode_REF_INC_DEC: return "REF_INC_DEC";
+ case Icode_SCOPE_LOAD: return "SCOPE_LOAD";
+ case Icode_SCOPE_SAVE: return "SCOPE_SAVE";
+ case Icode_TYPEOFNAME: return "TYPEOFNAME";
+ case Icode_NAME_AND_THIS: return "NAME_AND_THIS";
+ case Icode_PROP_AND_THIS: return "PROP_AND_THIS";
+ case Icode_ELEM_AND_THIS: return "ELEM_AND_THIS";
+ case Icode_VALUE_AND_THIS: return "VALUE_AND_THIS";
+ case Icode_CLOSURE_EXPR: return "CLOSURE_EXPR";
+ case Icode_CLOSURE_STMT: return "CLOSURE_STMT";
+ case Icode_CALLSPECIAL: return "CALLSPECIAL";
+ case Icode_RETUNDEF: return "RETUNDEF";
+ case Icode_GOSUB: return "GOSUB";
+ case Icode_STARTSUB: return "STARTSUB";
+ case Icode_RETSUB: return "RETSUB";
+ case Icode_LINE: return "LINE";
+ case Icode_SHORTNUMBER: return "SHORTNUMBER";
+ case Icode_INTNUMBER: return "INTNUMBER";
+ case Icode_LITERAL_NEW: return "LITERAL_NEW";
+ case Icode_LITERAL_SET: return "LITERAL_SET";
+ case Icode_SPARE_ARRAYLIT: return "SPARE_ARRAYLIT";
+ case Icode_REG_IND_C0: return "REG_IND_C0";
+ case Icode_REG_IND_C1: return "REG_IND_C1";
+ case Icode_REG_IND_C2: return "REG_IND_C2";
+ case Icode_REG_IND_C3: return "REG_IND_C3";
+ case Icode_REG_IND_C4: return "REG_IND_C4";
+ case Icode_REG_IND_C5: return "REG_IND_C5";
+ case Icode_REG_IND1: return "LOAD_IND1";
+ case Icode_REG_IND2: return "LOAD_IND2";
+ case Icode_REG_IND4: return "LOAD_IND4";
+ case Icode_REG_STR_C0: return "REG_STR_C0";
+ case Icode_REG_STR_C1: return "REG_STR_C1";
+ case Icode_REG_STR_C2: return "REG_STR_C2";
+ case Icode_REG_STR_C3: return "REG_STR_C3";
+ case Icode_REG_STR1: return "LOAD_STR1";
+ case Icode_REG_STR2: return "LOAD_STR2";
+ case Icode_REG_STR4: return "LOAD_STR4";
+ case Icode_GETVAR1: return "GETVAR1";
+ case Icode_SETVAR1: return "SETVAR1";
+ case Icode_UNDEF: return "UNDEF";
+ case Icode_ZERO: return "ZERO";
+ case Icode_ONE: return "ONE";
+ case Icode_ENTERDQ: return "ENTERDQ";
+ case Icode_LEAVEDQ: return "LEAVEDQ";
+ case Icode_TAIL_CALL: return "TAIL_CALL";
+ case Icode_LOCAL_CLEAR: return "LOCAL_CLEAR";
+ case Icode_LITERAL_GETTER: return "LITERAL_GETTER";
+ case Icode_LITERAL_SETTER: return "LITERAL_SETTER";
+ case Icode_SETCONST: return "SETCONST";
+ case Icode_SETCONSTVAR: return "SETCONSTVAR";
+ case Icode_SETCONSTVAR1: return "SETCONSTVAR1";
+ case Icode_GENERATOR: return "GENERATOR";
+ case Icode_GENERATOR_END: return "GENERATOR_END";
+ case Icode_DEBUGGER: return "DEBUGGER";
+ }
+
+ // icode without name
+ throw new IllegalStateException(String.valueOf(bytecode));
+ }
+
+ private static boolean validIcode(int icode)
+ {
+ return MIN_ICODE <= icode && icode <= -1;
+ }
+
+ private static boolean validTokenCode(int token)
+ {
+ return Token.FIRST_BYTECODE_TOKEN <= token
+ && token <= Token.LAST_BYTECODE_TOKEN;
+ }
+
+ private static boolean validBytecode(int bytecode)
+ {
+ return validIcode(bytecode) || validTokenCode(bytecode);
+ }
+
+ public Object compile(CompilerEnvirons compilerEnv,
+ ScriptOrFnNode tree,
+ String encodedSource,
+ boolean returnFunction)
+ {
+ this.compilerEnv = compilerEnv;
+ new NodeTransformer().transform(tree);
+
+ if (Token.printTrees) {
+ /*APPJET*///System.out.println(tree.toStringTree(tree));
+ }
+
+ if (returnFunction) {
+ tree = tree.getFunctionNode(0);
+ }
+
+ scriptOrFn = tree;
+ itsData = new InterpreterData(compilerEnv.getLanguageVersion(),
+ scriptOrFn.getSourceName(),
+ encodedSource);
+ itsData.topLevel = true;
+
+ if (returnFunction) {
+ generateFunctionICode();
+ } else {
+ generateICodeFromTree(scriptOrFn);
+ }
+
+ return itsData;
+ }
+
+ public Script createScriptObject(Object bytecode, Object staticSecurityDomain)
+ {
+ if(bytecode != itsData)
+ {
+ Kit.codeBug();
+ }
+ return InterpretedFunction.createScript(itsData,
+ staticSecurityDomain);
+ }
+
+ public void setEvalScriptFlag(Script script) {
+ ((InterpretedFunction)script).idata.evalScriptFlag = true;
+ }
+
+
+ public Function createFunctionObject(Context cx, Scriptable scope,
+ Object bytecode, Object staticSecurityDomain)
+ {
+ if(bytecode != itsData)
+ {
+ Kit.codeBug();
+ }
+ return InterpretedFunction.createFunction(cx, scope, itsData,
+ staticSecurityDomain);
+ }
+
+ private void generateFunctionICode()
+ {
+ itsInFunctionFlag = true;
+
+ FunctionNode theFunction = (FunctionNode)scriptOrFn;
+
+ itsData.itsFunctionType = theFunction.getFunctionType();
+ itsData.itsNeedsActivation = theFunction.requiresActivation();
+ itsData.itsName = theFunction.getFunctionName();
+ if (!theFunction.getIgnoreDynamicScope()) {
+ if (compilerEnv.isUseDynamicScope()) {
+ itsData.useDynamicScope = true;
+ }
+ }
+ if (theFunction.isGenerator()) {
+ addIcode(Icode_GENERATOR);
+ addUint16(theFunction.getBaseLineno() & 0xFFFF);
+ }
+
+ generateICodeFromTree(theFunction.getLastChild());
+ }
+
+ private void generateICodeFromTree(Node tree)
+ {
+ generateNestedFunctions();
+
+ generateRegExpLiterals();
+
+ visitStatement(tree, 0);
+ fixLabelGotos();
+ // add RETURN_RESULT only to scripts as function always ends with RETURN
+ if (itsData.itsFunctionType == 0) {
+ addToken(Token.RETURN_RESULT);
+ }
+
+ if (itsData.itsICode.length != itsICodeTop) {
+ // Make itsData.itsICode length exactly itsICodeTop to save memory
+ // and catch bugs with jumps beyond icode as early as possible
+ byte[] tmp = new byte[itsICodeTop];
+ System.arraycopy(itsData.itsICode, 0, tmp, 0, itsICodeTop);
+ itsData.itsICode = tmp;
+ }
+ if (itsStrings.size() == 0) {
+ itsData.itsStringTable = null;
+ } else {
+ itsData.itsStringTable = new String[itsStrings.size()];
+ ObjToIntMap.Iterator iter = itsStrings.newIterator();
+ for (iter.start(); !iter.done(); iter.next()) {
+ String str = (String)iter.getKey();
+ int index = iter.getValue();
+ if (itsData.itsStringTable[index] != null) Kit.codeBug();
+ itsData.itsStringTable[index] = str;
+ }
+ }
+ if (itsDoubleTableTop == 0) {
+ itsData.itsDoubleTable = null;
+ } else if (itsData.itsDoubleTable.length != itsDoubleTableTop) {
+ double[] tmp = new double[itsDoubleTableTop];
+ System.arraycopy(itsData.itsDoubleTable, 0, tmp, 0,
+ itsDoubleTableTop);
+ itsData.itsDoubleTable = tmp;
+ }
+ if (itsExceptionTableTop != 0
+ && itsData.itsExceptionTable.length != itsExceptionTableTop)
+ {
+ int[] tmp = new int[itsExceptionTableTop];
+ System.arraycopy(itsData.itsExceptionTable, 0, tmp, 0,
+ itsExceptionTableTop);
+ itsData.itsExceptionTable = tmp;
+ }
+
+ itsData.itsMaxVars = scriptOrFn.getParamAndVarCount();
+ // itsMaxFrameArray: interpret method needs this amount for its
+ // stack and sDbl arrays
+ itsData.itsMaxFrameArray = itsData.itsMaxVars
+ + itsData.itsMaxLocals
+ + itsData.itsMaxStack;
+
+ itsData.argNames = scriptOrFn.getParamAndVarNames();
+ itsData.argIsConst = scriptOrFn.getParamAndVarConst();
+ itsData.argCount = scriptOrFn.getParamCount();
+
+ itsData.encodedSourceStart = scriptOrFn.getEncodedSourceStart();
+ itsData.encodedSourceEnd = scriptOrFn.getEncodedSourceEnd();
+
+ if (itsLiteralIds.size() != 0) {
+ itsData.literalIds = itsLiteralIds.toArray();
+ }
+
+ if (Token.printICode) dumpICode(itsData);
+ }
+
+ private void generateNestedFunctions()
+ {
+ int functionCount = scriptOrFn.getFunctionCount();
+ if (functionCount == 0) return;
+
+ InterpreterData[] array = new InterpreterData[functionCount];
+ for (int i = 0; i != functionCount; i++) {
+ FunctionNode def = scriptOrFn.getFunctionNode(i);
+ Interpreter jsi = new Interpreter();
+ jsi.compilerEnv = compilerEnv;
+ jsi.scriptOrFn = def;
+ jsi.itsData = new InterpreterData(itsData);
+ jsi.generateFunctionICode();
+ array[i] = jsi.itsData;
+ }
+ itsData.itsNestedFunctions = array;
+ }
+
+ private void generateRegExpLiterals()
+ {
+ int N = scriptOrFn.getRegexpCount();
+ if (N == 0) return;
+
+ Context cx = Context.getContext();
+ RegExpProxy rep = ScriptRuntime.checkRegExpProxy(cx);
+ Object[] array = new Object[N];
+ for (int i = 0; i != N; i++) {
+ String string = scriptOrFn.getRegexpString(i);
+ String flags = scriptOrFn.getRegexpFlags(i);
+ array[i] = rep.compileRegExp(cx, string, flags);
+ }
+ itsData.itsRegExpLiterals = array;
+ }
+
+ private void updateLineNumber(Node node)
+ {
+ int lineno = node.getLineno();
+ if (lineno != itsLineNumber && lineno >= 0) {
+ if (itsData.firstLinePC < 0) {
+ itsData.firstLinePC = lineno;
+ }
+ itsLineNumber = lineno;
+ addIcode(Icode_LINE);
+ addUint16(lineno & 0xFFFF);
+ }
+ }
+
+ private RuntimeException badTree(Node node)
+ {
+ throw new RuntimeException(node.toString());
+ }
+
+ private void visitStatement(Node node, int initialStackDepth)
+ {
+ int type = node.getType();
+ Node child = node.getFirstChild();
+ switch (type) {
+
+ case Token.FUNCTION:
+ {
+ int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
+ int fnType = scriptOrFn.getFunctionNode(fnIndex).
+ getFunctionType();
+ // Only function expressions or function expression
+ // statements need closure code creating new function
+ // object on stack as function statements are initialized
+ // at script/function start.
+ // In addition, function expressions can not be present here
+ // at statement level, they must only be present as expressions.
+ if (fnType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
+ addIndexOp(Icode_CLOSURE_STMT, fnIndex);
+ } else {
+ if (fnType != FunctionNode.FUNCTION_STATEMENT) {
+ throw Kit.codeBug();
+ }
+ }
+ // For function statements or function expression statements
+ // in scripts, we need to ensure that the result of the script
+ // is the function if it is the last statement in the script.
+ // For example, eval("function () {}") should return a
+ // function, not undefined.
+ if (!itsInFunctionFlag) {
+ addIndexOp(Icode_CLOSURE_EXPR, fnIndex);
+ stackChange(1);
+ addIcode(Icode_POP_RESULT);
+ stackChange(-1);
+ }
+ }
+ break;
+
+ case Token.LABEL:
+ case Token.LOOP:
+ case Token.BLOCK:
+ case Token.EMPTY:
+ case Token.WITH:
+ updateLineNumber(node);
+ case Token.SCRIPT:
+ // fall through
+ while (child != null) {
+ visitStatement(child, initialStackDepth);
+ child = child.getNext();
+ }
+ break;
+
+ case Token.ENTERWITH:
+ visitExpression(child, 0);
+ addToken(Token.ENTERWITH);
+ stackChange(-1);
+ break;
+
+ case Token.LEAVEWITH:
+ addToken(Token.LEAVEWITH);
+ break;
+
+ case Token.LOCAL_BLOCK:
+ {
+ int local = allocLocal();
+ node.putIntProp(Node.LOCAL_PROP, local);
+ updateLineNumber(node);
+ while (child != null) {
+ visitStatement(child, initialStackDepth);
+ child = child.getNext();
+ }
+ addIndexOp(Icode_LOCAL_CLEAR, local);
+ releaseLocal(local);
+ }
+ break;
+
+ case Token.DEBUGGER:
+ addIcode(Icode_DEBUGGER);
+ break;
+
+ case Token.SWITCH:
+ updateLineNumber(node);
+ // See comments in IRFactory.createSwitch() for description
+ // of SWITCH node
+ {
+ visitExpression(child, 0);
+ for (Node.Jump caseNode = (Node.Jump)child.getNext();
+ caseNode != null;
+ caseNode = (Node.Jump)caseNode.getNext())
+ {
+ if (caseNode.getType() != Token.CASE)
+ throw badTree(caseNode);
+ Node test = caseNode.getFirstChild();
+ addIcode(Icode_DUP);
+ stackChange(1);
+ visitExpression(test, 0);
+ addToken(Token.SHEQ);
+ stackChange(-1);
+ // If true, Icode_IFEQ_POP will jump and remove case
+ // value from stack
+ addGoto(caseNode.target, Icode_IFEQ_POP);
+ stackChange(-1);
+ }
+ addIcode(Icode_POP);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.TARGET:
+ markTargetLabel(node);
+ break;
+
+ case Token.IFEQ :
+ case Token.IFNE :
+ {
+ Node target = ((Node.Jump)node).target;
+ visitExpression(child, 0);
+ addGoto(target, type);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.GOTO:
+ {
+ Node target = ((Node.Jump)node).target;
+ addGoto(target, type);
+ }
+ break;
+
+ case Token.JSR:
+ {
+ Node target = ((Node.Jump)node).target;
+ addGoto(target, Icode_GOSUB);
+ }
+ break;
+
+ case Token.FINALLY:
+ {
+ // Account for incomming GOTOSUB address
+ stackChange(1);
+ int finallyRegister = getLocalBlockRef(node);
+ addIndexOp(Icode_STARTSUB, finallyRegister);
+ stackChange(-1);
+ while (child != null) {
+ visitStatement(child, initialStackDepth);
+ child = child.getNext();
+ }
+ addIndexOp(Icode_RETSUB, finallyRegister);
+ }
+ break;
+
+ case Token.EXPR_VOID:
+ case Token.EXPR_RESULT:
+ updateLineNumber(node);
+ visitExpression(child, 0);
+ addIcode((type == Token.EXPR_VOID) ? Icode_POP : Icode_POP_RESULT);
+ stackChange(-1);
+ break;
+
+ case Token.TRY:
+ {
+ Node.Jump tryNode = (Node.Jump)node;
+ int exceptionObjectLocal = getLocalBlockRef(tryNode);
+ int scopeLocal = allocLocal();
+
+ addIndexOp(Icode_SCOPE_SAVE, scopeLocal);
+
+ int tryStart = itsICodeTop;
+ boolean savedFlag = itsInTryFlag;
+ itsInTryFlag = true;
+ while (child != null) {
+ visitStatement(child, initialStackDepth);
+ child = child.getNext();
+ }
+ itsInTryFlag = savedFlag;
+
+ Node catchTarget = tryNode.target;
+ if (catchTarget != null) {
+ int catchStartPC
+ = itsLabelTable[getTargetLabel(catchTarget)];
+ addExceptionHandler(
+ tryStart, catchStartPC, catchStartPC,
+ false, exceptionObjectLocal, scopeLocal);
+ }
+ Node finallyTarget = tryNode.getFinally();
+ if (finallyTarget != null) {
+ int finallyStartPC
+ = itsLabelTable[getTargetLabel(finallyTarget)];
+ addExceptionHandler(
+ tryStart, finallyStartPC, finallyStartPC,
+ true, exceptionObjectLocal, scopeLocal);
+ }
+
+ addIndexOp(Icode_LOCAL_CLEAR, scopeLocal);
+ releaseLocal(scopeLocal);
+ }
+ break;
+
+ case Token.CATCH_SCOPE:
+ {
+ int localIndex = getLocalBlockRef(node);
+ int scopeIndex = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);
+ String name = child.getString();
+ child = child.getNext();
+ visitExpression(child, 0); // load expression object
+ addStringPrefix(name);
+ addIndexPrefix(localIndex);
+ addToken(Token.CATCH_SCOPE);
+ addUint8(scopeIndex != 0 ? 1 : 0);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.THROW:
+ updateLineNumber(node);
+ visitExpression(child, 0);
+ addToken(Token.THROW);
+ addUint16(itsLineNumber & 0xFFFF);
+ stackChange(-1);
+ break;
+
+ case Token.RETHROW:
+ updateLineNumber(node);
+ addIndexOp(Token.RETHROW, getLocalBlockRef(node));
+ break;
+
+ case Token.RETURN:
+ updateLineNumber(node);
+ if (node.getIntProp(Node.GENERATOR_END_PROP, 0) != 0) {
+ // We're in a generator, so change RETURN to GENERATOR_END
+ addIcode(Icode_GENERATOR_END);
+ addUint16(itsLineNumber & 0xFFFF);
+ } else if (child != null) {
+ visitExpression(child, ECF_TAIL);
+ addToken(Token.RETURN);
+ stackChange(-1);
+ } else {
+ addIcode(Icode_RETUNDEF);
+ }
+ break;
+
+ case Token.RETURN_RESULT:
+ updateLineNumber(node);
+ addToken(Token.RETURN_RESULT);
+ break;
+
+ case Token.ENUM_INIT_KEYS:
+ case Token.ENUM_INIT_VALUES:
+ case Token.ENUM_INIT_ARRAY:
+ visitExpression(child, 0);
+ addIndexOp(type, getLocalBlockRef(node));
+ stackChange(-1);
+ break;
+
+ case Icode_GENERATOR:
+ break;
+
+ default:
+ throw badTree(node);
+ }
+
+ if (itsStackDepth != initialStackDepth) {
+ throw Kit.codeBug();
+ }
+ }
+
+ private void visitExpression(Node node, int contextFlags)
+ {
+ int type = node.getType();
+ Node child = node.getFirstChild();
+ int savedStackDepth = itsStackDepth;
+ switch (type) {
+
+ case Token.FUNCTION:
+ {
+ int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = scriptOrFn.getFunctionNode(fnIndex);
+ // See comments in visitStatement for Token.FUNCTION case
+ if (fn.getFunctionType() != FunctionNode.FUNCTION_EXPRESSION) {
+ throw Kit.codeBug();
+ }
+ addIndexOp(Icode_CLOSURE_EXPR, fnIndex);
+ stackChange(1);
+ }
+ break;
+
+ case Token.LOCAL_LOAD:
+ {
+ int localIndex = getLocalBlockRef(node);
+ addIndexOp(Token.LOCAL_LOAD, localIndex);
+ stackChange(1);
+ }
+ break;
+
+ case Token.COMMA:
+ {
+ Node lastChild = node.getLastChild();
+ while (child != lastChild) {
+ visitExpression(child, 0);
+ addIcode(Icode_POP);
+ stackChange(-1);
+ child = child.getNext();
+ }
+ // Preserve tail context flag if any
+ visitExpression(child, contextFlags & ECF_TAIL);
+ }
+ break;
+
+ case Token.USE_STACK:
+ // Indicates that stack was modified externally,
+ // like placed catch object
+ stackChange(1);
+ break;
+
+ case Token.REF_CALL:
+ case Token.CALL:
+ case Token.NEW:
+ {
+ if (type == Token.NEW) {
+ visitExpression(child, 0);
+ } else {
+ generateCallFunAndThis(child);
+ }
+ int argCount = 0;
+ while ((child = child.getNext()) != null) {
+ visitExpression(child, 0);
+ ++argCount;
+ }
+ int callType = node.getIntProp(Node.SPECIALCALL_PROP,
+ Node.NON_SPECIALCALL);
+ if (callType != Node.NON_SPECIALCALL) {
+ // embed line number and source filename
+ addIndexOp(Icode_CALLSPECIAL, argCount);
+ addUint8(callType);
+ addUint8(type == Token.NEW ? 1 : 0);
+ addUint16(itsLineNumber & 0xFFFF);
+ } else {
+ // Only use the tail call optimization if we're not in a try
+ // or we're not generating debug info (since the
+ // optimization will confuse the debugger)
+ if (type == Token.CALL && (contextFlags & ECF_TAIL) != 0 &&
+ !compilerEnv.isGenerateDebugInfo() && !itsInTryFlag)
+ {
+ type = Icode_TAIL_CALL;
+ }
+ addIndexOp(type, argCount);
+ }
+ // adjust stack
+ if (type == Token.NEW) {
+ // new: f, args -> result
+ stackChange(-argCount);
+ } else {
+ // call: f, thisObj, args -> result
+ // ref_call: f, thisObj, args -> ref
+ stackChange(-1 - argCount);
+ }
+ if (argCount > itsData.itsMaxCalleeArgs) {
+ itsData.itsMaxCalleeArgs = argCount;
+ }
+ }
+ break;
+
+ case Token.AND:
+ case Token.OR:
+ {
+ visitExpression(child, 0);
+ addIcode(Icode_DUP);
+ stackChange(1);
+ int afterSecondJumpStart = itsICodeTop;
+ int jump = (type == Token.AND) ? Token.IFNE : Token.IFEQ;
+ addGotoOp(jump);
+ stackChange(-1);
+ addIcode(Icode_POP);
+ stackChange(-1);
+ child = child.getNext();
+ // Preserve tail context flag if any
+ visitExpression(child, contextFlags & ECF_TAIL);
+ resolveForwardGoto(afterSecondJumpStart);
+ }
+ break;
+
+ case Token.HOOK:
+ {
+ Node ifThen = child.getNext();
+ Node ifElse = ifThen.getNext();
+ visitExpression(child, 0);
+ int elseJumpStart = itsICodeTop;
+ addGotoOp(Token.IFNE);
+ stackChange(-1);
+ // Preserve tail context flag if any
+ visitExpression(ifThen, contextFlags & ECF_TAIL);
+ int afterElseJumpStart = itsICodeTop;
+ addGotoOp(Token.GOTO);
+ resolveForwardGoto(elseJumpStart);
+ itsStackDepth = savedStackDepth;
+ // Preserve tail context flag if any
+ visitExpression(ifElse, contextFlags & ECF_TAIL);
+ resolveForwardGoto(afterElseJumpStart);
+ }
+ break;
+
+ case Token.GETPROP:
+ case Token.GETPROPNOWARN:
+ visitExpression(child, 0);
+ child = child.getNext();
+ addStringOp(type, child.getString());
+ break;
+
+ case Token.GETELEM:
+ case Token.DELPROP:
+ case Token.BITAND:
+ case Token.BITOR:
+ case Token.BITXOR:
+ case Token.LSH:
+ case Token.RSH:
+ case Token.URSH:
+ case Token.ADD:
+ case Token.SUB:
+ case Token.MOD:
+ case Token.DIV:
+ case Token.MUL:
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ case Token.IN:
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ visitExpression(child, 0);
+ child = child.getNext();
+ visitExpression(child, 0);
+ addToken(type);
+ stackChange(-1);
+ break;
+
+ case Token.POS:
+ case Token.NEG:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ case Token.VOID:
+ visitExpression(child, 0);
+ if (type == Token.VOID) {
+ addIcode(Icode_POP);
+ addIcode(Icode_UNDEF);
+ } else {
+ addToken(type);
+ }
+ break;
+
+ case Token.GET_REF:
+ case Token.DEL_REF:
+ visitExpression(child, 0);
+ addToken(type);
+ break;
+
+ case Token.SETPROP:
+ case Token.SETPROP_OP:
+ {
+ visitExpression(child, 0);
+ child = child.getNext();
+ String property = child.getString();
+ child = child.getNext();
+ if (type == Token.SETPROP_OP) {
+ addIcode(Icode_DUP);
+ stackChange(1);
+ addStringOp(Token.GETPROP, property);
+ // Compensate for the following USE_STACK
+ stackChange(-1);
+ }
+ visitExpression(child, 0);
+ addStringOp(Token.SETPROP, property);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.SETELEM:
+ case Token.SETELEM_OP:
+ visitExpression(child, 0);
+ child = child.getNext();
+ visitExpression(child, 0);
+ child = child.getNext();
+ if (type == Token.SETELEM_OP) {
+ addIcode(Icode_DUP2);
+ stackChange(2);
+ addToken(Token.GETELEM);
+ stackChange(-1);
+ // Compensate for the following USE_STACK
+ stackChange(-1);
+ }
+ visitExpression(child, 0);
+ addToken(Token.SETELEM);
+ stackChange(-2);
+ break;
+
+ case Token.SET_REF:
+ case Token.SET_REF_OP:
+ visitExpression(child, 0);
+ child = child.getNext();
+ if (type == Token.SET_REF_OP) {
+ addIcode(Icode_DUP);
+ stackChange(1);
+ addToken(Token.GET_REF);
+ // Compensate for the following USE_STACK
+ stackChange(-1);
+ }
+ visitExpression(child, 0);
+ addToken(Token.SET_REF);
+ stackChange(-1);
+ break;
+
+ case Token.SETNAME:
+ {
+ String name = child.getString();
+ visitExpression(child, 0);
+ child = child.getNext();
+ visitExpression(child, 0);
+ addStringOp(Token.SETNAME, name);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.SETCONST:
+ {
+ String name = child.getString();
+ visitExpression(child, 0);
+ child = child.getNext();
+ visitExpression(child, 0);
+ addStringOp(Icode_SETCONST, name);
+ stackChange(-1);
+ }
+ break;
+
+ case Token.TYPEOFNAME:
+ {
+ int index = -1;
+ // use typeofname if an activation frame exists
+ // since the vars all exist there instead of in jregs
+ if (itsInFunctionFlag && !itsData.itsNeedsActivation)
+ index = scriptOrFn.getIndexForNameNode(node);
+ if (index == -1) {
+ addStringOp(Icode_TYPEOFNAME, node.getString());
+ stackChange(1);
+ } else {
+ addVarOp(Token.GETVAR, index);
+ stackChange(1);
+ addToken(Token.TYPEOF);
+ }
+ }
+ break;
+
+ case Token.BINDNAME:
+ case Token.NAME:
+ case Token.STRING:
+ addStringOp(type, node.getString());
+ stackChange(1);
+ break;
+
+ case Token.INC:
+ case Token.DEC:
+ visitIncDec(node, child);
+ break;
+
+ case Token.NUMBER:
+ {
+ double num = node.getDouble();
+ int inum = (int)num;
+ if (inum == num) {
+ if (inum == 0) {
+ addIcode(Icode_ZERO);
+ // Check for negative zero
+ if (1.0 / num < 0.0) {
+ addToken(Token.NEG);
+ }
+ } else if (inum == 1) {
+ addIcode(Icode_ONE);
+ } else if ((short)inum == inum) {
+ addIcode(Icode_SHORTNUMBER);
+ // write short as uin16 bit pattern
+ addUint16(inum & 0xFFFF);
+ } else {
+ addIcode(Icode_INTNUMBER);
+ addInt(inum);
+ }
+ } else {
+ int index = getDoubleIndex(num);
+ addIndexOp(Token.NUMBER, index);
+ }
+ stackChange(1);
+ }
+ break;
+
+ case Token.GETVAR:
+ {
+ if (itsData.itsNeedsActivation) Kit.codeBug();
+ int index = scriptOrFn.getIndexForNameNode(node);
+ addVarOp(Token.GETVAR, index);
+ stackChange(1);
+ }
+ break;
+
+ case Token.SETVAR:
+ {
+ if (itsData.itsNeedsActivation) Kit.codeBug();
+ int index = scriptOrFn.getIndexForNameNode(child);
+ child = child.getNext();
+ visitExpression(child, 0);
+ addVarOp(Token.SETVAR, index);
+ }
+ break;
+
+ case Token.SETCONSTVAR:
+ {
+ if (itsData.itsNeedsActivation) Kit.codeBug();
+ int index = scriptOrFn.getIndexForNameNode(child);
+ child = child.getNext();
+ visitExpression(child, 0);
+ addVarOp(Token.SETCONSTVAR, index);
+ }
+ break;
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.THISFN:
+ case Token.FALSE:
+ case Token.TRUE:
+ addToken(type);
+ stackChange(1);
+ break;
+
+ case Token.ENUM_NEXT:
+ case Token.ENUM_ID:
+ addIndexOp(type, getLocalBlockRef(node));
+ stackChange(1);
+ break;
+
+ case Token.REGEXP:
+ {
+ int index = node.getExistingIntProp(Node.REGEXP_PROP);
+ addIndexOp(Token.REGEXP, index);
+ stackChange(1);
+ }
+ break;
+
+ case Token.ARRAYLIT:
+ case Token.OBJECTLIT:
+ visitLiteral(node, child);
+ break;
+
+ case Token.ARRAYCOMP:
+ visitArrayComprehension(node, child, child.getNext());
+ break;
+
+ case Token.REF_SPECIAL:
+ visitExpression(child, 0);
+ addStringOp(type, (String)node.getProp(Node.NAME_PROP));
+ break;
+
+ case Token.REF_MEMBER:
+ case Token.REF_NS_MEMBER:
+ case Token.REF_NAME:
+ case Token.REF_NS_NAME:
+ {
+ int memberTypeFlags = node.getIntProp(Node.MEMBER_TYPE_PROP, 0);
+ // generate possible target, possible namespace and member
+ int childCount = 0;
+ do {
+ visitExpression(child, 0);
+ ++childCount;
+ child = child.getNext();
+ } while (child != null);
+ addIndexOp(type, memberTypeFlags);
+ stackChange(1 - childCount);
+ }
+ break;
+
+ case Token.DOTQUERY:
+ {
+ int queryPC;
+ updateLineNumber(node);
+ visitExpression(child, 0);
+ addIcode(Icode_ENTERDQ);
+ stackChange(-1);
+ queryPC = itsICodeTop;
+ visitExpression(child.getNext(), 0);
+ addBackwardGoto(Icode_LEAVEDQ, queryPC);
+ }
+ break;
+
+ case Token.DEFAULTNAMESPACE :
+ case Token.ESCXMLATTR :
+ case Token.ESCXMLTEXT :
+ visitExpression(child, 0);
+ addToken(type);
+ break;
+
+ case Token.YIELD:
+ if (child != null) {
+ visitExpression(child, 0);
+ } else {
+ addIcode(Icode_UNDEF);
+ stackChange(1);
+ }
+ addToken(Token.YIELD);
+ addUint16(node.getLineno() & 0xFFFF);
+ break;
+
+ case Token.WITHEXPR: {
+ Node enterWith = node.getFirstChild();
+ Node with = enterWith.getNext();
+ visitExpression(enterWith.getFirstChild(), 0);
+ addToken(Token.ENTERWITH);
+ stackChange(-1);
+ visitExpression(with.getFirstChild(), 0);
+ addToken(Token.LEAVEWITH);
+ break;
+ }
+
+ default:
+ throw badTree(node);
+ }
+ if (savedStackDepth + 1 != itsStackDepth) {
+ Kit.codeBug();
+ }
+ }
+
+ private void generateCallFunAndThis(Node left)
+ {
+ // Generate code to place on stack function and thisObj
+ int type = left.getType();
+ switch (type) {
+ case Token.NAME: {
+ String name = left.getString();
+ // stack: ... -> ... function thisObj
+ addStringOp(Icode_NAME_AND_THIS, name);
+ stackChange(2);
+ break;
+ }
+ case Token.GETPROP:
+ case Token.GETELEM: {
+ Node target = left.getFirstChild();
+ visitExpression(target, 0);
+ Node id = target.getNext();
+ if (type == Token.GETPROP) {
+ String property = id.getString();
+ // stack: ... target -> ... function thisObj
+ addStringOp(Icode_PROP_AND_THIS, property);
+ stackChange(1);
+ } else {
+ visitExpression(id, 0);
+ // stack: ... target id -> ... function thisObj
+ addIcode(Icode_ELEM_AND_THIS);
+ }
+ break;
+ }
+ default:
+ // Including Token.GETVAR
+ visitExpression(left, 0);
+ // stack: ... value -> ... function thisObj
+ addIcode(Icode_VALUE_AND_THIS);
+ stackChange(1);
+ break;
+ }
+ }
+
+ private void visitIncDec(Node node, Node child)
+ {
+ int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP);
+ int childType = child.getType();
+ switch (childType) {
+ case Token.GETVAR : {
+ if (itsData.itsNeedsActivation) Kit.codeBug();
+ int i = scriptOrFn.getIndexForNameNode(child);
+ addVarOp(Icode_VAR_INC_DEC, i);
+ addUint8(incrDecrMask);
+ stackChange(1);
+ break;
+ }
+ case Token.NAME : {
+ String name = child.getString();
+ addStringOp(Icode_NAME_INC_DEC, name);
+ addUint8(incrDecrMask);
+ stackChange(1);
+ break;
+ }
+ case Token.GETPROP : {
+ Node object = child.getFirstChild();
+ visitExpression(object, 0);
+ String property = object.getNext().getString();
+ addStringOp(Icode_PROP_INC_DEC, property);
+ addUint8(incrDecrMask);
+ break;
+ }
+ case Token.GETELEM : {
+ Node object = child.getFirstChild();
+ visitExpression(object, 0);
+ Node index = object.getNext();
+ visitExpression(index, 0);
+ addIcode(Icode_ELEM_INC_DEC);
+ addUint8(incrDecrMask);
+ stackChange(-1);
+ break;
+ }
+ case Token.GET_REF : {
+ Node ref = child.getFirstChild();
+ visitExpression(ref, 0);
+ addIcode(Icode_REF_INC_DEC);
+ addUint8(incrDecrMask);
+ break;
+ }
+ default : {
+ throw badTree(node);
+ }
+ }
+ }
+
+ private void visitLiteral(Node node, Node child)
+ {
+ int type = node.getType();
+ int count;
+ Object[] propertyIds = null;
+ if (type == Token.ARRAYLIT) {
+ count = 0;
+ for (Node n = child; n != null; n = n.getNext()) {
+ ++count;
+ }
+ } else if (type == Token.OBJECTLIT) {
+ propertyIds = (Object[])node.getProp(Node.OBJECT_IDS_PROP);
+ count = propertyIds.length;
+ } else {
+ throw badTree(node);
+ }
+ addIndexOp(Icode_LITERAL_NEW, count);
+ stackChange(2);
+ while (child != null) {
+ int childType = child.getType();
+ if (childType == Token.GET) {
+ visitExpression(child.getFirstChild(), 0);
+ addIcode(Icode_LITERAL_GETTER);
+ } else if (childType == Token.SET) {
+ visitExpression(child.getFirstChild(), 0);
+ addIcode(Icode_LITERAL_SETTER);
+ } else {
+ visitExpression(child, 0);
+ addIcode(Icode_LITERAL_SET);
+ }
+ stackChange(-1);
+ child = child.getNext();
+ }
+ if (type == Token.ARRAYLIT) {
+ int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP);
+ if (skipIndexes == null) {
+ addToken(Token.ARRAYLIT);
+ } else {
+ int index = itsLiteralIds.size();
+ itsLiteralIds.add(skipIndexes);
+ addIndexOp(Icode_SPARE_ARRAYLIT, index);
+ }
+ } else {
+ int index = itsLiteralIds.size();
+ itsLiteralIds.add(propertyIds);
+ addIndexOp(Token.OBJECTLIT, index);
+ }
+ stackChange(-1);
+ }
+
+ private void visitArrayComprehension(Node node, Node initStmt, Node expr)
+ {
+ // A bit of a hack: array comprehensions are implemented using
+ // statement nodes for the iteration, yet they appear in an
+ // expression context. So we pass the current stack depth to
+ // visitStatement so it can check that the depth is not altered
+ // by statements.
+ visitStatement(initStmt, itsStackDepth);
+ visitExpression(expr, 0);
+ }
+
+ private int getLocalBlockRef(Node node)
+ {
+ Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP);
+ return localBlock.getExistingIntProp(Node.LOCAL_PROP);
+ }
+
+ private int getTargetLabel(Node target)
+ {
+ int label = target.labelId();
+ if (label != -1) {
+ return label;
+ }
+ label = itsLabelTableTop;
+ if (itsLabelTable == null || label == itsLabelTable.length) {
+ if (itsLabelTable == null) {
+ itsLabelTable = new int[MIN_LABEL_TABLE_SIZE];
+ }else {
+ int[] tmp = new int[itsLabelTable.length * 2];
+ System.arraycopy(itsLabelTable, 0, tmp, 0, label);
+ itsLabelTable = tmp;
+ }
+ }
+ itsLabelTableTop = label + 1;
+ itsLabelTable[label] = -1;
+
+ target.labelId(label);
+ return label;
+ }
+
+ private void markTargetLabel(Node target)
+ {
+ int label = getTargetLabel(target);
+ if (itsLabelTable[label] != -1) {
+ // Can mark label only once
+ Kit.codeBug();
+ }
+ itsLabelTable[label] = itsICodeTop;
+ }
+
+ private void addGoto(Node target, int gotoOp)
+ {
+ int label = getTargetLabel(target);
+ if (!(label < itsLabelTableTop)) Kit.codeBug();
+ int targetPC = itsLabelTable[label];
+
+ if (targetPC != -1) {
+ addBackwardGoto(gotoOp, targetPC);
+ } else {
+ int gotoPC = itsICodeTop;
+ addGotoOp(gotoOp);
+ int top = itsFixupTableTop;
+ if (itsFixupTable == null || top == itsFixupTable.length) {
+ if (itsFixupTable == null) {
+ itsFixupTable = new long[MIN_FIXUP_TABLE_SIZE];
+ } else {
+ long[] tmp = new long[itsFixupTable.length * 2];
+ System.arraycopy(itsFixupTable, 0, tmp, 0, top);
+ itsFixupTable = tmp;
+ }
+ }
+ itsFixupTableTop = top + 1;
+ itsFixupTable[top] = ((long)label << 32) | gotoPC;
+ }
+ }
+
+ private void fixLabelGotos()
+ {
+ for (int i = 0; i < itsFixupTableTop; i++) {
+ long fixup = itsFixupTable[i];
+ int label = (int)(fixup >> 32);
+ int jumpSource = (int)fixup;
+ int pc = itsLabelTable[label];
+ if (pc == -1) {
+ // Unlocated label
+ throw Kit.codeBug();
+ }
+ resolveGoto(jumpSource, pc);
+ }
+ itsFixupTableTop = 0;
+ }
+
+ private void addBackwardGoto(int gotoOp, int jumpPC)
+ {
+ int fromPC = itsICodeTop;
+ // Ensure that this is a jump backward
+ if (fromPC <= jumpPC) throw Kit.codeBug();
+ addGotoOp(gotoOp);
+ resolveGoto(fromPC, jumpPC);
+ }
+
+ private void resolveForwardGoto(int fromPC)
+ {
+ // Ensure that forward jump skips at least self bytecode
+ if (itsICodeTop < fromPC + 3) throw Kit.codeBug();
+ resolveGoto(fromPC, itsICodeTop);
+ }
+
+ private void resolveGoto(int fromPC, int jumpPC)
+ {
+ int offset = jumpPC - fromPC;
+ // Ensure that jumps do not overlap
+ if (0 <= offset && offset <= 2) throw Kit.codeBug();
+ int offsetSite = fromPC + 1;
+ if (offset != (short)offset) {
+ if (itsData.longJumps == null) {
+ itsData.longJumps = new UintMap();
+ }
+ itsData.longJumps.put(offsetSite, jumpPC);
+ offset = 0;
+ }
+ byte[] array = itsData.itsICode;
+ array[offsetSite] = (byte)(offset >> 8);
+ array[offsetSite + 1] = (byte)offset;
+ }
+
+ private void addToken(int token)
+ {
+ if (!validTokenCode(token)) throw Kit.codeBug();
+ addUint8(token);
+ }
+
+ private void addIcode(int icode)
+ {
+ if (!validIcode(icode)) throw Kit.codeBug();
+ // Write negative icode as uint8 bits
+ addUint8(icode & 0xFF);
+ }
+
+ private void addUint8(int value)
+ {
+ if ((value & ~0xFF) != 0) throw Kit.codeBug();
+ byte[] array = itsData.itsICode;
+ int top = itsICodeTop;
+ if (top == array.length) {
+ array = increaseICodeCapacity(1);
+ }
+ array[top] = (byte)value;
+ itsICodeTop = top + 1;
+ }
+
+ private void addUint16(int value)
+ {
+ if ((value & ~0xFFFF) != 0) throw Kit.codeBug();
+ byte[] array = itsData.itsICode;
+ int top = itsICodeTop;
+ if (top + 2 > array.length) {
+ array = increaseICodeCapacity(2);
+ }
+ array[top] = (byte)(value >>> 8);
+ array[top + 1] = (byte)value;
+ itsICodeTop = top + 2;
+ }
+
+ private void addInt(int i)
+ {
+ byte[] array = itsData.itsICode;
+ int top = itsICodeTop;
+ if (top + 4 > array.length) {
+ array = increaseICodeCapacity(4);
+ }
+ array[top] = (byte)(i >>> 24);
+ array[top + 1] = (byte)(i >>> 16);
+ array[top + 2] = (byte)(i >>> 8);
+ array[top + 3] = (byte)i;
+ itsICodeTop = top + 4;
+ }
+
+ private int getDoubleIndex(double num)
+ {
+ int index = itsDoubleTableTop;
+ if (index == 0) {
+ itsData.itsDoubleTable = new double[64];
+ } else if (itsData.itsDoubleTable.length == index) {
+ double[] na = new double[index * 2];
+ System.arraycopy(itsData.itsDoubleTable, 0, na, 0, index);
+ itsData.itsDoubleTable = na;
+ }
+ itsData.itsDoubleTable[index] = num;
+ itsDoubleTableTop = index + 1;
+ return index;
+ }
+
+ private void addGotoOp(int gotoOp)
+ {
+ byte[] array = itsData.itsICode;
+ int top = itsICodeTop;
+ if (top + 3 > array.length) {
+ array = increaseICodeCapacity(3);
+ }
+ array[top] = (byte)gotoOp;
+ // Offset would written later
+ itsICodeTop = top + 1 + 2;
+ }
+
+ private void addVarOp(int op, int varIndex)
+ {
+ switch (op) {
+ case Token.SETCONSTVAR:
+ if (varIndex < 128) {
+ addIcode(Icode_SETCONSTVAR1);
+ addUint8(varIndex);
+ return;
+ }
+ addIndexOp(Icode_SETCONSTVAR, varIndex);
+ return;
+ case Token.GETVAR:
+ case Token.SETVAR:
+ if (varIndex < 128) {
+ addIcode(op == Token.GETVAR ? Icode_GETVAR1 : Icode_SETVAR1);
+ addUint8(varIndex);
+ return;
+ }
+ // fallthrough
+ case Icode_VAR_INC_DEC:
+ addIndexOp(op, varIndex);
+ return;
+ }
+ throw Kit.codeBug();
+ }
+
+ private void addStringOp(int op, String str)
+ {
+ addStringPrefix(str);
+ if (validIcode(op)) {
+ addIcode(op);
+ } else {
+ addToken(op);
+ }
+ }
+
+ private void addIndexOp(int op, int index)
+ {
+ addIndexPrefix(index);
+ if (validIcode(op)) {
+ addIcode(op);
+ } else {
+ addToken(op);
+ }
+ }
+
+ private void addStringPrefix(String str)
+ {
+ int index = itsStrings.get(str, -1);
+ if (index == -1) {
+ index = itsStrings.size();
+ itsStrings.put(str, index);
+ }
+ if (index < 4) {
+ addIcode(Icode_REG_STR_C0 - index);
+ } else if (index <= 0xFF) {
+ addIcode(Icode_REG_STR1);
+ addUint8(index);
+ } else if (index <= 0xFFFF) {
+ addIcode(Icode_REG_STR2);
+ addUint16(index);
+ } else {
+ addIcode(Icode_REG_STR4);
+ addInt(index);
+ }
+ }
+
+ private void addIndexPrefix(int index)
+ {
+ if (index < 0) Kit.codeBug();
+ if (index < 6) {
+ addIcode(Icode_REG_IND_C0 - index);
+ } else if (index <= 0xFF) {
+ addIcode(Icode_REG_IND1);
+ addUint8(index);
+ } else if (index <= 0xFFFF) {
+ addIcode(Icode_REG_IND2);
+ addUint16(index);
+ } else {
+ addIcode(Icode_REG_IND4);
+ addInt(index);
+ }
+ }
+
+ private void addExceptionHandler(int icodeStart, int icodeEnd,
+ int handlerStart, boolean isFinally,
+ int exceptionObjectLocal, int scopeLocal)
+ {
+ int top = itsExceptionTableTop;
+ int[] table = itsData.itsExceptionTable;
+ if (table == null) {
+ if (top != 0) Kit.codeBug();
+ table = new int[EXCEPTION_SLOT_SIZE * 2];
+ itsData.itsExceptionTable = table;
+ } else if (table.length == top) {
+ table = new int[table.length * 2];
+ System.arraycopy(itsData.itsExceptionTable, 0, table, 0, top);
+ itsData.itsExceptionTable = table;
+ }
+ table[top + EXCEPTION_TRY_START_SLOT] = icodeStart;
+ table[top + EXCEPTION_TRY_END_SLOT] = icodeEnd;
+ table[top + EXCEPTION_HANDLER_SLOT] = handlerStart;
+ table[top + EXCEPTION_TYPE_SLOT] = isFinally ? 1 : 0;
+ table[top + EXCEPTION_LOCAL_SLOT] = exceptionObjectLocal;
+ table[top + EXCEPTION_SCOPE_SLOT] = scopeLocal;
+
+ itsExceptionTableTop = top + EXCEPTION_SLOT_SIZE;
+ }
+
+ private byte[] increaseICodeCapacity(int extraSize)
+ {
+ int capacity = itsData.itsICode.length;
+ int top = itsICodeTop;
+ if (top + extraSize <= capacity) throw Kit.codeBug();
+ capacity *= 2;
+ if (top + extraSize > capacity) {
+ capacity = top + extraSize;
+ }
+ byte[] array = new byte[capacity];
+ System.arraycopy(itsData.itsICode, 0, array, 0, top);
+ itsData.itsICode = array;
+ return array;
+ }
+
+ private void stackChange(int change)
+ {
+ if (change <= 0) {
+ itsStackDepth += change;
+ } else {
+ int newDepth = itsStackDepth + change;
+ if (newDepth > itsData.itsMaxStack) {
+ itsData.itsMaxStack = newDepth;
+ }
+ itsStackDepth = newDepth;
+ }
+ }
+
+ private int allocLocal()
+ {
+ int localSlot = itsLocalTop;
+ ++itsLocalTop;
+ if (itsLocalTop > itsData.itsMaxLocals) {
+ itsData.itsMaxLocals = itsLocalTop;
+ }
+ return localSlot;
+ }
+
+ private void releaseLocal(int localSlot)
+ {
+ --itsLocalTop;
+ if (localSlot != itsLocalTop) Kit.codeBug();
+ }
+
+ private static int getShort(byte[] iCode, int pc) {
+ return (iCode[pc] << 8) | (iCode[pc + 1] & 0xFF);
+ }
+
+ private static int getIndex(byte[] iCode, int pc) {
+ return ((iCode[pc] & 0xFF) << 8) | (iCode[pc + 1] & 0xFF);
+ }
+
+ private static int getInt(byte[] iCode, int pc) {
+ return (iCode[pc] << 24) | ((iCode[pc + 1] & 0xFF) << 16)
+ | ((iCode[pc + 2] & 0xFF) << 8) | (iCode[pc + 3] & 0xFF);
+ }
+
+ private static int getExceptionHandler(CallFrame frame,
+ boolean onlyFinally)
+ {
+ int[] exceptionTable = frame.idata.itsExceptionTable;
+ if (exceptionTable == null) {
+ // No exception handlers
+ return -1;
+ }
+
+ // Icode switch in the interpreter increments PC immediately
+ // and it is necessary to subtract 1 from the saved PC
+ // to point it before the start of the next instruction.
+ int pc = frame.pc - 1;
+
+ // OPT: use binary search
+ int best = -1, bestStart = 0, bestEnd = 0;
+ for (int i = 0; i != exceptionTable.length; i += EXCEPTION_SLOT_SIZE) {
+ int start = exceptionTable[i + EXCEPTION_TRY_START_SLOT];
+ int end = exceptionTable[i + EXCEPTION_TRY_END_SLOT];
+ if (!(start <= pc && pc < end)) {
+ continue;
+ }
+ if (onlyFinally && exceptionTable[i + EXCEPTION_TYPE_SLOT] != 1) {
+ continue;
+ }
+ if (best >= 0) {
+ // Since handlers always nest and they never have shared end
+ // although they can share start it is sufficient to compare
+ // handlers ends
+ if (bestEnd < end) {
+ continue;
+ }
+ // Check the above assumption
+ if (bestStart > start) Kit.codeBug(); // should be nested
+ if (bestEnd == end) Kit.codeBug(); // no ens sharing
+ }
+ best = i;
+ bestStart = start;
+ bestEnd = end;
+ }
+ return best;
+ }
+
+ private static void dumpICode(InterpreterData idata)
+ {
+ if (!Token.printICode) {
+ return;
+ }
+
+ byte iCode[] = idata.itsICode;
+ int iCodeLength = iCode.length;
+ String[] strings = idata.itsStringTable;
+ PrintStream out = System.out;
+ out.println("ICode dump, for " + idata.itsName
+ + ", length = " + iCodeLength);
+ out.println("MaxStack = " + idata.itsMaxStack);
+
+ int indexReg = 0;
+ for (int pc = 0; pc < iCodeLength; ) {
+ out.flush();
+ out.print(" [" + pc + "] ");
+ int token = iCode[pc];
+ int icodeLength = bytecodeSpan(token);
+ String tname = bytecodeName(token);
+ int old_pc = pc;
+ ++pc;
+ switch (token) {
+ default:
+ if (icodeLength != 1) Kit.codeBug();
+ out.println(tname);
+ break;
+
+ case Icode_GOSUB :
+ case Token.GOTO :
+ case Token.IFEQ :
+ case Token.IFNE :
+ case Icode_IFEQ_POP :
+ case Icode_LEAVEDQ : {
+ int newPC = pc + getShort(iCode, pc) - 1;
+ out.println(tname + " " + newPC);
+ pc += 2;
+ break;
+ }
+ case Icode_VAR_INC_DEC :
+ case Icode_NAME_INC_DEC :
+ case Icode_PROP_INC_DEC :
+ case Icode_ELEM_INC_DEC :
+ case Icode_REF_INC_DEC: {
+ int incrDecrType = iCode[pc];
+ out.println(tname + " " + incrDecrType);
+ ++pc;
+ break;
+ }
+
+ case Icode_CALLSPECIAL : {
+ int callType = iCode[pc] & 0xFF;
+ boolean isNew = (iCode[pc + 1] != 0);
+ int line = getIndex(iCode, pc+2);
+ out.println(tname+" "+callType+" "+isNew+" "+indexReg+" "+line);
+ pc += 4;
+ break;
+ }
+
+ case Token.CATCH_SCOPE:
+ {
+ boolean afterFisrtFlag = (iCode[pc] != 0);
+ out.println(tname+" "+afterFisrtFlag);
+ ++pc;
+ }
+ break;
+ case Token.REGEXP :
+ out.println(tname+" "+idata.itsRegExpLiterals[indexReg]);
+ break;
+ case Token.OBJECTLIT :
+ case Icode_SPARE_ARRAYLIT :
+ out.println(tname+" "+idata.literalIds[indexReg]);
+ break;
+ case Icode_CLOSURE_EXPR :
+ case Icode_CLOSURE_STMT :
+ out.println(tname+" "+idata.itsNestedFunctions[indexReg]);
+ break;
+ case Token.CALL :
+ case Icode_TAIL_CALL :
+ case Token.REF_CALL :
+ case Token.NEW :
+ out.println(tname+' '+indexReg);
+ break;
+ case Token.THROW :
+ case Token.YIELD :
+ case Icode_GENERATOR :
+ case Icode_GENERATOR_END :
+ {
+ int line = getIndex(iCode, pc);
+ out.println(tname + " : " + line);
+ pc += 2;
+ break;
+ }
+ case Icode_SHORTNUMBER : {
+ int value = getShort(iCode, pc);
+ out.println(tname + " " + value);
+ pc += 2;
+ break;
+ }
+ case Icode_INTNUMBER : {
+ int value = getInt(iCode, pc);
+ out.println(tname + " " + value);
+ pc += 4;
+ break;
+ }
+ case Token.NUMBER : {
+ double value = idata.itsDoubleTable[indexReg];
+ out.println(tname + " " + value);
+ break;
+ }
+ case Icode_LINE : {
+ int line = getIndex(iCode, pc);
+ out.println(tname + " : " + line);
+ pc += 2;
+ break;
+ }
+ case Icode_REG_STR1: {
+ String str = strings[0xFF & iCode[pc]];
+ out.println(tname + " \"" + str + '"');
+ ++pc;
+ break;
+ }
+ case Icode_REG_STR2: {
+ String str = strings[getIndex(iCode, pc)];
+ out.println(tname + " \"" + str + '"');
+ pc += 2;
+ break;
+ }
+ case Icode_REG_STR4: {
+ String str = strings[getInt(iCode, pc)];
+ out.println(tname + " \"" + str + '"');
+ pc += 4;
+ break;
+ }
+ case Icode_REG_IND_C0:
+ indexReg = 0;
+ out.println(tname);
+ break;
+ case Icode_REG_IND_C1:
+ indexReg = 1;
+ out.println(tname);
+ break;
+ case Icode_REG_IND_C2:
+ indexReg = 2;
+ out.println(tname);
+ break;
+ case Icode_REG_IND_C3:
+ indexReg = 3;
+ out.println(tname);
+ break;
+ case Icode_REG_IND_C4:
+ indexReg = 4;
+ out.println(tname);
+ break;
+ case Icode_REG_IND_C5:
+ indexReg = 5;
+ out.println(tname);
+ break;
+ case Icode_REG_IND1: {
+ indexReg = 0xFF & iCode[pc];
+ out.println(tname+" "+indexReg);
+ ++pc;
+ break;
+ }
+ case Icode_REG_IND2: {
+ indexReg = getIndex(iCode, pc);
+ out.println(tname+" "+indexReg);
+ pc += 2;
+ break;
+ }
+ case Icode_REG_IND4: {
+ indexReg = getInt(iCode, pc);
+ out.println(tname+" "+indexReg);
+ pc += 4;
+ break;
+ }
+ case Icode_GETVAR1:
+ case Icode_SETVAR1:
+ case Icode_SETCONSTVAR1:
+ indexReg = iCode[pc];
+ out.println(tname+" "+indexReg);
+ ++pc;
+ break;
+ }
+ if (old_pc + icodeLength != pc) Kit.codeBug();
+ }
+
+ int[] table = idata.itsExceptionTable;
+ if (table != null) {
+ out.println("Exception handlers: "
+ +table.length / EXCEPTION_SLOT_SIZE);
+ for (int i = 0; i != table.length;
+ i += EXCEPTION_SLOT_SIZE)
+ {
+ int tryStart = table[i + EXCEPTION_TRY_START_SLOT];
+ int tryEnd = table[i + EXCEPTION_TRY_END_SLOT];
+ int handlerStart = table[i + EXCEPTION_HANDLER_SLOT];
+ int type = table[i + EXCEPTION_TYPE_SLOT];
+ int exceptionLocal = table[i + EXCEPTION_LOCAL_SLOT];
+ int scopeLocal = table[i + EXCEPTION_SCOPE_SLOT];
+
+ out.println(" tryStart="+tryStart+" tryEnd="+tryEnd
+ +" handlerStart="+handlerStart
+ +" type="+(type == 0 ? "catch" : "finally")
+ +" exceptionLocal="+exceptionLocal);
+ }
+ }
+ out.flush();
+ }
+
+ private static int bytecodeSpan(int bytecode)
+ {
+ switch (bytecode) {
+ case Token.THROW :
+ case Token.YIELD:
+ case Icode_GENERATOR:
+ case Icode_GENERATOR_END:
+ // source line
+ return 1 + 2;
+
+ case Icode_GOSUB :
+ case Token.GOTO :
+ case Token.IFEQ :
+ case Token.IFNE :
+ case Icode_IFEQ_POP :
+ case Icode_LEAVEDQ :
+ // target pc offset
+ return 1 + 2;
+
+ case Icode_CALLSPECIAL :
+ // call type
+ // is new
+ // line number
+ return 1 + 1 + 1 + 2;
+
+ case Token.CATCH_SCOPE:
+ // scope flag
+ return 1 + 1;
+
+ case Icode_VAR_INC_DEC:
+ case Icode_NAME_INC_DEC:
+ case Icode_PROP_INC_DEC:
+ case Icode_ELEM_INC_DEC:
+ case Icode_REF_INC_DEC:
+ // type of ++/--
+ return 1 + 1;
+
+ case Icode_SHORTNUMBER :
+ // short number
+ return 1 + 2;
+
+ case Icode_INTNUMBER :
+ // int number
+ return 1 + 4;
+
+ case Icode_REG_IND1:
+ // ubyte index
+ return 1 + 1;
+
+ case Icode_REG_IND2:
+ // ushort index
+ return 1 + 2;
+
+ case Icode_REG_IND4:
+ // int index
+ return 1 + 4;
+
+ case Icode_REG_STR1:
+ // ubyte string index
+ return 1 + 1;
+
+ case Icode_REG_STR2:
+ // ushort string index
+ return 1 + 2;
+
+ case Icode_REG_STR4:
+ // int string index
+ return 1 + 4;
+
+ case Icode_GETVAR1:
+ case Icode_SETVAR1:
+ case Icode_SETCONSTVAR1:
+ // byte var index
+ return 1 + 1;
+
+ case Icode_LINE :
+ // line number
+ return 1 + 2;
+ }
+ if (!validBytecode(bytecode)) throw Kit.codeBug();
+ return 1;
+ }
+
+ static int[] getLineNumbers(InterpreterData data)
+ {
+ UintMap presentLines = new UintMap();
+
+ byte[] iCode = data.itsICode;
+ int iCodeLength = iCode.length;
+ for (int pc = 0; pc != iCodeLength;) {
+ int bytecode = iCode[pc];
+ int span = bytecodeSpan(bytecode);
+ if (bytecode == Icode_LINE) {
+ if (span != 3) Kit.codeBug();
+ int line = getIndex(iCode, pc + 1);
+ presentLines.put(line, 0);
+ }
+ pc += span;
+ }
+
+ return presentLines.getKeys();
+ }
+
+ public void captureStackInfo(RhinoException ex)
+ {
+ Context cx = Context.getCurrentContext();
+ if (cx == null || cx.lastInterpreterFrame == null) {
+ // No interpreter invocations
+ ex.interpreterStackInfo = null;
+ ex.interpreterLineData = null;
+ return;
+ }
+ // has interpreter frame on the stack
+ CallFrame[] array;
+ if (cx.previousInterpreterInvocations == null
+ || cx.previousInterpreterInvocations.size() == 0)
+ {
+ array = new CallFrame[1];
+ } else {
+ int previousCount = cx.previousInterpreterInvocations.size();
+ if (cx.previousInterpreterInvocations.peek()
+ == cx.lastInterpreterFrame)
+ {
+ // It can happen if exception was generated after
+ // frame was pushed to cx.previousInterpreterInvocations
+ // but before assignment to cx.lastInterpreterFrame.
+ // In this case frames has to be ignored.
+ --previousCount;
+ }
+ array = new CallFrame[previousCount + 1];
+ cx.previousInterpreterInvocations.toArray(array);
+ }
+ array[array.length - 1] = (CallFrame)cx.lastInterpreterFrame;
+
+ int interpreterFrameCount = 0;
+ for (int i = 0; i != array.length; ++i) {
+ interpreterFrameCount += 1 + array[i].frameIndex;
+ }
+
+ int[] linePC = new int[interpreterFrameCount];
+ // Fill linePC with pc positions from all interpreter frames.
+ // Start from the most nested frame
+ int linePCIndex = interpreterFrameCount;
+ for (int i = array.length; i != 0;) {
+ --i;
+ CallFrame frame = array[i];
+ while (frame != null) {
+ --linePCIndex;
+ linePC[linePCIndex] = frame.pcSourceLineStart;
+ frame = frame.parentFrame;
+ }
+ }
+ if (linePCIndex != 0) Kit.codeBug();
+
+ ex.interpreterStackInfo = array;
+ ex.interpreterLineData = linePC;
+ }
+
+ public String getSourcePositionFromStack(Context cx, int[] linep)
+ {
+ CallFrame frame = (CallFrame)cx.lastInterpreterFrame;
+ InterpreterData idata = frame.idata;
+ if (frame.pcSourceLineStart >= 0) {
+ linep[0] = getIndex(idata.itsICode, frame.pcSourceLineStart);
+ } else {
+ linep[0] = 0;
+ }
+ return idata.itsSourceFile;
+ }
+
+ public String getPatchedStack(RhinoException ex,
+ String nativeStackTrace)
+ {
+ String tag = "org.mozilla.javascript.Interpreter.interpretLoop";
+ StringBuffer sb = new StringBuffer(nativeStackTrace.length() + 1000);
+ String lineSeparator = SecurityUtilities.getSystemProperty("line.separator");
+
+ CallFrame[] array = (CallFrame[])ex.interpreterStackInfo;
+ int[] linePC = ex.interpreterLineData;
+ int arrayIndex = array.length;
+ int linePCIndex = linePC.length;
+ int offset = 0;
+ while (arrayIndex != 0) {
+ --arrayIndex;
+ int pos = nativeStackTrace.indexOf(tag, offset);
+ if (pos < 0) {
+ break;
+ }
+
+ // Skip tag length
+ pos += tag.length();
+ // Skip until the end of line
+ for (; pos != nativeStackTrace.length(); ++pos) {
+ char c = nativeStackTrace.charAt(pos);
+ if (c == '\n' || c == '\r') {
+ break;
+ }
+ }
+ sb.append(nativeStackTrace.substring(offset, pos));
+ offset = pos;
+
+ CallFrame frame = array[arrayIndex];
+ while (frame != null) {
+ if (linePCIndex == 0) Kit.codeBug();
+ --linePCIndex;
+ InterpreterData idata = frame.idata;
+ sb.append(lineSeparator);
+ sb.append("\tat script");
+ if (idata.itsName != null && idata.itsName.length() != 0) {
+ sb.append('.');
+ sb.append(idata.itsName);
+ }
+ sb.append('(');
+ sb.append(idata.itsSourceFile);
+ int pc = linePC[linePCIndex];
+ if (pc >= 0) {
+ // Include line info only if available
+ sb.append(':');
+ sb.append(getIndex(idata.itsICode, pc));
+ }
+ sb.append(')');
+ frame = frame.parentFrame;
+ }
+ }
+ sb.append(nativeStackTrace.substring(offset));
+
+ return sb.toString();
+ }
+
+ public List getScriptStack(RhinoException ex)
+ {
+ if (ex.interpreterStackInfo == null) {
+ return null;
+ }
+
+ List list = new ArrayList();
+ String lineSeparator =
+ SecurityUtilities.getSystemProperty("line.separator");
+
+ CallFrame[] array = (CallFrame[])ex.interpreterStackInfo;
+ int[] linePC = ex.interpreterLineData;
+ int arrayIndex = array.length;
+ int linePCIndex = linePC.length;
+ while (arrayIndex != 0) {
+ --arrayIndex;
+ StringBuffer sb = new StringBuffer();
+ CallFrame frame = array[arrayIndex];
+ while (frame != null) {
+ if (linePCIndex == 0) Kit.codeBug();
+ --linePCIndex;
+ InterpreterData idata = frame.idata;
+ sb.append("\tat ");
+ sb.append(idata.itsSourceFile);
+ int pc = linePC[linePCIndex];
+ if (pc >= 0) {
+ // Include line info only if available
+ sb.append(':');
+ sb.append(getIndex(idata.itsICode, pc));
+ }
+ if (idata.itsName != null && idata.itsName.length() != 0) {
+ sb.append(" (");
+ sb.append(idata.itsName);
+ sb.append(')');
+ }
+ sb.append(lineSeparator);
+ frame = frame.parentFrame;
+ }
+ list.add(sb.toString());
+ }
+ return list;
+ }
+
+ static String getEncodedSource(InterpreterData idata)
+ {
+ if (idata.encodedSource == null) {
+ return null;
+ }
+ return idata.encodedSource.substring(idata.encodedSourceStart,
+ idata.encodedSourceEnd);
+ }
+
+ private static void initFunction(Context cx, Scriptable scope,
+ InterpretedFunction parent, int index)
+ {
+ InterpretedFunction fn;
+ fn = InterpretedFunction.createFunction(cx, scope, parent, index);
+ ScriptRuntime.initFunction(cx, scope, fn, fn.idata.itsFunctionType,
+ parent.idata.evalScriptFlag);
+ }
+
+ static Object interpret(InterpretedFunction ifun,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!ScriptRuntime.hasTopCall(cx)) Kit.codeBug();
+
+ if (cx.interpreterSecurityDomain != ifun.securityDomain) {
+ Object savedDomain = cx.interpreterSecurityDomain;
+ cx.interpreterSecurityDomain = ifun.securityDomain;
+ try {
+ return ifun.securityController.callWithDomain(
+ ifun.securityDomain, cx, ifun, scope, thisObj, args);
+ } finally {
+ cx.interpreterSecurityDomain = savedDomain;
+ }
+ }
+
+ CallFrame frame = new CallFrame();
+ initFrame(cx, scope, thisObj, args, null, 0, args.length,
+ ifun, null, frame);
+
+ return interpretLoop(cx, frame, null);
+ }
+
+ static class GeneratorState {
+ GeneratorState(int operation, Object value) {
+ this.operation = operation;
+ this.value = value;
+ }
+ int operation;
+ Object value;
+ RuntimeException returnedException;
+ }
+
+ public static Object resumeGenerator(Context cx,
+ Scriptable scope,
+ int operation,
+ Object savedState,
+ Object value)
+ {
+ CallFrame frame = (CallFrame) savedState;
+ GeneratorState generatorState = new GeneratorState(operation, value);
+ if (operation == NativeGenerator.GENERATOR_CLOSE) {
+ try {
+ return interpretLoop(cx, frame, generatorState);
+ } catch (RuntimeException e) {
+ // Only propagate exceptions other than closingException
+ if (e != value)
+ throw e;
+ }
+ return Undefined.instance;
+ }
+ Object result = interpretLoop(cx, frame, generatorState);
+ if (generatorState.returnedException != null)
+ throw generatorState.returnedException;
+ return result;
+ }
+
+ public static Object restartContinuation(Continuation c, Context cx,
+ Scriptable scope, Object[] args)
+ {
+ if (!ScriptRuntime.hasTopCall(cx)) {
+ return ScriptRuntime.doTopCall(c, cx, scope, null, args);
+ }
+
+ Object arg;
+ if (args.length == 0) {
+ arg = Undefined.instance;
+ } else {
+ arg = args[0];
+ }
+
+ CallFrame capturedFrame = (CallFrame)c.getImplementation();
+ if (capturedFrame == null) {
+ // No frames to restart
+ return arg;
+ }
+
+ ContinuationJump cjump = new ContinuationJump(c, null);
+
+ cjump.result = arg;
+ return interpretLoop(cx, null, cjump);
+ }
+
+ private static Object interpretLoop(Context cx, CallFrame frame,
+ Object throwable)
+ {
+ // throwable holds exception object to rethrow or catch
+ // It is also used for continuation restart in which case
+ // it holds ContinuationJump
+
+ final Object DBL_MRK = UniqueTag.DOUBLE_MARK;
+ final Object undefined = Undefined.instance;
+
+ final boolean instructionCounting = (cx.instructionThreshold != 0);
+ // arbitrary number to add to instructionCount when calling
+ // other functions
+ final int INVOCATION_COST = 100;
+ // arbitrary exception cost for instruction counting
+ final int EXCEPTION_COST = 100;
+
+ String stringReg = null;
+ int indexReg = -1;
+
+ if (cx.lastInterpreterFrame != null) {
+ // save the top frame from the previous interpretLoop
+ // invocation on the stack
+ if (cx.previousInterpreterInvocations == null) {
+ cx.previousInterpreterInvocations = new ObjArray();
+ }
+ cx.previousInterpreterInvocations.push(cx.lastInterpreterFrame);
+ }
+
+ // When restarting continuation throwable is not null and to jump
+ // to the code that rewind continuation state indexReg should be set
+ // to -1.
+ // With the normal call throable == null and indexReg == -1 allows to
+ // catch bugs with using indeReg to access array eleemnts before
+ // initializing indexReg.
+
+ GeneratorState generatorState = null;
+ if (throwable != null) {
+ if (throwable instanceof GeneratorState) {
+ generatorState = (GeneratorState) throwable;
+
+ // reestablish this call frame
+ enterFrame(cx, frame, ScriptRuntime.emptyArgs, true);
+ throwable = null;
+ } else if (!(throwable instanceof ContinuationJump)) {
+ // It should be continuation
+ Kit.codeBug();
+ }
+ }
+
+ Object interpreterResult = null;
+ double interpreterResultDbl = 0.0;
+
+ StateLoop: for (;;) {
+ withoutExceptions: try {
+
+ if (throwable != null) {
+ // Need to return both 'frame' and 'throwable' from
+ // 'processThrowable', so just added a 'throwable'
+ // member in 'frame'.
+ frame = processThrowable(cx, throwable, frame, indexReg,
+ instructionCounting);
+ throwable = frame.throwable;
+ frame.throwable = null;
+ } else {
+ if (generatorState == null && frame.frozen) Kit.codeBug();
+ }
+
+ // Use local variables for constant values in frame
+ // for faster access
+ Object[] stack = frame.stack;
+ double[] sDbl = frame.sDbl;
+ Object[] vars = frame.varSource.stack;
+ double[] varDbls = frame.varSource.sDbl;
+ int[] varAttributes = frame.varSource.stackAttributes;
+ byte[] iCode = frame.idata.itsICode;
+ String[] strings = frame.idata.itsStringTable;
+
+ // Use local for stackTop as well. Since execption handlers
+ // can only exist at statement level where stack is empty,
+ // it is necessary to save/restore stackTop only across
+ // function calls and normal returns.
+ int stackTop = frame.savedStackTop;
+
+ // Store new frame in cx which is used for error reporting etc.
+ cx.lastInterpreterFrame = frame;
+
+ Loop: for (;;) {
+
+ // Exception handler assumes that PC is already incremented
+ // pass the instruction start when it searches the
+ // exception handler
+ int op = iCode[frame.pc++];
+ jumplessRun: {
+
+ // Back indent to ease implementation reading
+switch (op) {
+ case Icode_GENERATOR: {
+ if (!frame.frozen) {
+ // First time encountering this opcode: create new generator
+ // object and return
+ frame.pc--; // we want to come back here when we resume
+ CallFrame generatorFrame = captureFrameForGenerator(frame);
+ generatorFrame.frozen = true;
+ NativeGenerator generator = new NativeGenerator(frame.scope,
+ generatorFrame.fnOrScript, generatorFrame);
+ frame.result = generator;
+ break Loop;
+ } else {
+ // We are now resuming execution. Fall through to YIELD case.
+ }
+ }
+ // fall through...
+ case Token.YIELD: {
+ if (!frame.frozen) {
+ return freezeGenerator(cx, frame, stackTop, generatorState);
+ } else {
+ Object obj = thawGenerator(frame, stackTop, generatorState, op);
+ if (obj != Scriptable.NOT_FOUND) {
+ throwable = obj;
+ break withoutExceptions;
+ }
+ continue Loop;
+ }
+ }
+ case Icode_GENERATOR_END: {
+ // throw StopIteration
+ frame.frozen = true;
+ int sourceLine = getIndex(iCode, frame.pc);
+ generatorState.returnedException = new JavaScriptException(
+ NativeIterator.getStopIterationObject(frame.scope),
+ frame.idata.itsSourceFile, sourceLine);
+ break Loop;
+ }
+ case Token.THROW: {
+ Object value = stack[stackTop];
+ if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+
+ int sourceLine = getIndex(iCode, frame.pc);
+ throwable = new JavaScriptException(value,
+ frame.idata.itsSourceFile,
+ sourceLine);
+ break withoutExceptions;
+ }
+ case Token.RETHROW: {
+ indexReg += frame.localShift;
+ throwable = stack[indexReg];
+ break withoutExceptions;
+ }
+ case Token.GE :
+ case Token.LE :
+ case Token.GT :
+ case Token.LT : {
+ --stackTop;
+ Object rhs = stack[stackTop + 1];
+ Object lhs = stack[stackTop];
+ boolean valBln;
+ object_compare:
+ {
+ number_compare:
+ {
+ double rDbl, lDbl;
+ if (rhs == DBL_MRK) {
+ rDbl = sDbl[stackTop + 1];
+ lDbl = stack_double(frame, stackTop);
+ } else if (lhs == DBL_MRK) {
+ rDbl = ScriptRuntime.toNumber(rhs);
+ lDbl = sDbl[stackTop];
+ } else {
+ break number_compare;
+ }
+ switch (op) {
+ case Token.GE:
+ valBln = (lDbl >= rDbl);
+ break object_compare;
+ case Token.LE:
+ valBln = (lDbl <= rDbl);
+ break object_compare;
+ case Token.GT:
+ valBln = (lDbl > rDbl);
+ break object_compare;
+ case Token.LT:
+ valBln = (lDbl < rDbl);
+ break object_compare;
+ default:
+ throw Kit.codeBug();
+ }
+ }
+ switch (op) {
+ case Token.GE:
+ valBln = ScriptRuntime.cmp_LE(rhs, lhs);
+ break;
+ case Token.LE:
+ valBln = ScriptRuntime.cmp_LE(lhs, rhs);
+ break;
+ case Token.GT:
+ valBln = ScriptRuntime.cmp_LT(rhs, lhs);
+ break;
+ case Token.LT:
+ valBln = ScriptRuntime.cmp_LT(lhs, rhs);
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ }
+ stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
+ continue Loop;
+ }
+ case Token.IN :
+ case Token.INSTANCEOF : {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ boolean valBln;
+ if (op == Token.IN) {
+ valBln = ScriptRuntime.in(lhs, rhs, cx);
+ } else {
+ valBln = ScriptRuntime.instanceOf(lhs, rhs, cx);
+ }
+ stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
+ continue Loop;
+ }
+ case Token.EQ :
+ case Token.NE : {
+ --stackTop;
+ boolean valBln;
+ Object rhs = stack[stackTop + 1];
+ Object lhs = stack[stackTop];
+ if (rhs == DBL_MRK) {
+ if (lhs == DBL_MRK) {
+ valBln = (sDbl[stackTop] == sDbl[stackTop + 1]);
+ } else {
+ valBln = ScriptRuntime.eqNumber(sDbl[stackTop + 1], lhs);
+ }
+ } else {
+ if (lhs == DBL_MRK) {
+ valBln = ScriptRuntime.eqNumber(sDbl[stackTop], rhs);
+ } else {
+ valBln = ScriptRuntime.eq(lhs, rhs);
+ }
+ }
+ valBln ^= (op == Token.NE);
+ stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
+ continue Loop;
+ }
+ case Token.SHEQ :
+ case Token.SHNE : {
+ --stackTop;
+ Object rhs = stack[stackTop + 1];
+ Object lhs = stack[stackTop];
+ boolean valBln;
+ shallow_compare: {
+ double rdbl, ldbl;
+ if (rhs == DBL_MRK) {
+ rdbl = sDbl[stackTop + 1];
+ if (lhs == DBL_MRK) {
+ ldbl = sDbl[stackTop];
+ } else if (lhs instanceof Number) {
+ ldbl = ((Number)lhs).doubleValue();
+ } else {
+ valBln = false;
+ break shallow_compare;
+ }
+ } else if (lhs == DBL_MRK) {
+ ldbl = sDbl[stackTop];
+ if (rhs == DBL_MRK) {
+ rdbl = sDbl[stackTop + 1];
+ } else if (rhs instanceof Number) {
+ rdbl = ((Number)rhs).doubleValue();
+ } else {
+ valBln = false;
+ break shallow_compare;
+ }
+ } else {
+ valBln = ScriptRuntime.shallowEq(lhs, rhs);
+ break shallow_compare;
+ }
+ valBln = (ldbl == rdbl);
+ }
+ valBln ^= (op == Token.SHNE);
+ stack[stackTop] = ScriptRuntime.wrapBoolean(valBln);
+ continue Loop;
+ }
+ case Token.IFNE :
+ if (stack_boolean(frame, stackTop--)) {
+ frame.pc += 2;
+ continue Loop;
+ }
+ break jumplessRun;
+ case Token.IFEQ :
+ if (!stack_boolean(frame, stackTop--)) {
+ frame.pc += 2;
+ continue Loop;
+ }
+ break jumplessRun;
+ case Icode_IFEQ_POP :
+ if (!stack_boolean(frame, stackTop--)) {
+ frame.pc += 2;
+ continue Loop;
+ }
+ stack[stackTop--] = null;
+ break jumplessRun;
+ case Token.GOTO :
+ break jumplessRun;
+ case Icode_GOSUB :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = frame.pc + 2;
+ break jumplessRun;
+ case Icode_STARTSUB :
+ if (stackTop == frame.emptyStackTop + 1) {
+ // Call from Icode_GOSUB: store return PC address in the local
+ indexReg += frame.localShift;
+ stack[indexReg] = stack[stackTop];
+ sDbl[indexReg] = sDbl[stackTop];
+ --stackTop;
+ } else {
+ // Call from exception handler: exception object is already stored
+ // in the local
+ if (stackTop != frame.emptyStackTop) Kit.codeBug();
+ }
+ continue Loop;
+ case Icode_RETSUB : {
+ // indexReg: local to store return address
+ if (instructionCounting) {
+ addInstructionCount(cx, frame, 0);
+ }
+ indexReg += frame.localShift;
+ Object value = stack[indexReg];
+ if (value != DBL_MRK) {
+ // Invocation from exception handler, restore object to rethrow
+ throwable = value;
+ break withoutExceptions;
+ }
+ // Normal return from GOSUB
+ frame.pc = (int)sDbl[indexReg];
+ if (instructionCounting) {
+ frame.pcPrevBranch = frame.pc;
+ }
+ continue Loop;
+ }
+ case Icode_POP :
+ stack[stackTop] = null;
+ stackTop--;
+ continue Loop;
+ case Icode_POP_RESULT :
+ frame.result = stack[stackTop];
+ frame.resultDbl = sDbl[stackTop];
+ stack[stackTop] = null;
+ --stackTop;
+ continue Loop;
+ case Icode_DUP :
+ stack[stackTop + 1] = stack[stackTop];
+ sDbl[stackTop + 1] = sDbl[stackTop];
+ stackTop++;
+ continue Loop;
+ case Icode_DUP2 :
+ stack[stackTop + 1] = stack[stackTop - 1];
+ sDbl[stackTop + 1] = sDbl[stackTop - 1];
+ stack[stackTop + 2] = stack[stackTop];
+ sDbl[stackTop + 2] = sDbl[stackTop];
+ stackTop += 2;
+ continue Loop;
+ case Icode_SWAP : {
+ Object o = stack[stackTop];
+ stack[stackTop] = stack[stackTop - 1];
+ stack[stackTop - 1] = o;
+ double d = sDbl[stackTop];
+ sDbl[stackTop] = sDbl[stackTop - 1];
+ sDbl[stackTop - 1] = d;
+ continue Loop;
+ }
+ case Token.RETURN :
+ frame.result = stack[stackTop];
+ frame.resultDbl = sDbl[stackTop];
+ --stackTop;
+ break Loop;
+ case Token.RETURN_RESULT :
+ break Loop;
+ case Icode_RETUNDEF :
+ frame.result = undefined;
+ break Loop;
+ case Token.BITNOT : {
+ int rIntValue = stack_int32(frame, stackTop);
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = ~rIntValue;
+ continue Loop;
+ }
+ case Token.BITAND :
+ case Token.BITOR :
+ case Token.BITXOR :
+ case Token.LSH :
+ case Token.RSH : {
+ int lIntValue = stack_int32(frame, stackTop-1);
+ int rIntValue = stack_int32(frame, stackTop);
+ stack[--stackTop] = DBL_MRK;
+ switch (op) {
+ case Token.BITAND:
+ lIntValue &= rIntValue;
+ break;
+ case Token.BITOR:
+ lIntValue |= rIntValue;
+ break;
+ case Token.BITXOR:
+ lIntValue ^= rIntValue;
+ break;
+ case Token.LSH:
+ lIntValue <<= rIntValue;
+ break;
+ case Token.RSH:
+ lIntValue >>= rIntValue;
+ break;
+ }
+ sDbl[stackTop] = lIntValue;
+ continue Loop;
+ }
+ case Token.URSH : {
+ double lDbl = stack_double(frame, stackTop-1);
+ int rIntValue = stack_int32(frame, stackTop) & 0x1F;
+ stack[--stackTop] = DBL_MRK;
+ sDbl[stackTop] = ScriptRuntime.toUint32(lDbl) >>> rIntValue;
+ continue Loop;
+ }
+ case Token.NEG :
+ case Token.POS : {
+ double rDbl = stack_double(frame, stackTop);
+ stack[stackTop] = DBL_MRK;
+ if (op == Token.NEG) {
+ rDbl = -rDbl;
+ }
+ sDbl[stackTop] = rDbl;
+ continue Loop;
+ }
+ case Token.ADD :
+ --stackTop;
+ do_add(stack, sDbl, stackTop, cx);
+ continue Loop;
+ case Token.SUB :
+ case Token.MUL :
+ case Token.DIV :
+ case Token.MOD : {
+ double rDbl = stack_double(frame, stackTop);
+ --stackTop;
+ double lDbl = stack_double(frame, stackTop);
+ stack[stackTop] = DBL_MRK;
+ switch (op) {
+ case Token.SUB:
+ lDbl -= rDbl;
+ break;
+ case Token.MUL:
+ lDbl *= rDbl;
+ break;
+ case Token.DIV:
+ lDbl /= rDbl;
+ break;
+ case Token.MOD:
+ lDbl %= rDbl;
+ break;
+ }
+ sDbl[stackTop] = lDbl;
+ continue Loop;
+ }
+ case Token.NOT :
+ stack[stackTop] = ScriptRuntime.wrapBoolean(
+ !stack_boolean(frame, stackTop));
+ continue Loop;
+ case Token.BINDNAME :
+ stack[++stackTop] = ScriptRuntime.bind(cx, frame.scope, stringReg);
+ continue Loop;
+ case Token.SETNAME : {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Scriptable lhs = (Scriptable)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx,
+ frame.scope, stringReg);
+ continue Loop;
+ }
+ case Icode_SETCONST: {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Scriptable lhs = (Scriptable)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.setConst(lhs, rhs, cx, stringReg);
+ continue Loop;
+ }
+ case Token.DELPROP : {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.delete(lhs, rhs, cx);
+ continue Loop;
+ }
+ case Token.GETPROPNOWARN : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.getObjectPropNoWarn(lhs, stringReg, cx);
+ continue Loop;
+ }
+ case Token.GETPROP : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.getObjectProp(lhs, stringReg, cx);
+ continue Loop;
+ }
+ case Token.SETPROP : {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.setObjectProp(lhs, stringReg, rhs,
+ cx);
+ continue Loop;
+ }
+ case Icode_PROP_INC_DEC : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.propIncrDecr(lhs, stringReg,
+ cx, iCode[frame.pc]);
+ ++frame.pc;
+ continue Loop;
+ }
+ case Token.GETELEM : {
+ --stackTop;
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) {
+ lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ }
+ Object value;
+ Object id = stack[stackTop + 1];
+ if (id != DBL_MRK) {
+ value = ScriptRuntime.getObjectElem(lhs, id, cx);
+ } else {
+ double d = sDbl[stackTop + 1];
+ value = ScriptRuntime.getObjectIndex(lhs, d, cx);
+ }
+ stack[stackTop] = value;
+ continue Loop;
+ }
+ case Token.SETELEM : {
+ stackTop -= 2;
+ Object rhs = stack[stackTop + 2];
+ if (rhs == DBL_MRK) {
+ rhs = ScriptRuntime.wrapNumber(sDbl[stackTop + 2]);
+ }
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) {
+ lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ }
+ Object value;
+ Object id = stack[stackTop + 1];
+ if (id != DBL_MRK) {
+ value = ScriptRuntime.setObjectElem(lhs, id, rhs, cx);
+ } else {
+ double d = sDbl[stackTop + 1];
+ value = ScriptRuntime.setObjectIndex(lhs, d, rhs, cx);
+ }
+ stack[stackTop] = value;
+ continue Loop;
+ }
+ case Icode_ELEM_INC_DEC: {
+ Object rhs = stack[stackTop];
+ if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.elemIncrDecr(lhs, rhs, cx,
+ iCode[frame.pc]);
+ ++frame.pc;
+ continue Loop;
+ }
+ case Token.GET_REF : {
+ Ref ref = (Ref)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.refGet(ref, cx);
+ continue Loop;
+ }
+ case Token.SET_REF : {
+ Object value = stack[stackTop];
+ if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Ref ref = (Ref)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.refSet(ref, value, cx);
+ continue Loop;
+ }
+ case Token.DEL_REF : {
+ Ref ref = (Ref)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.refDel(ref, cx);
+ continue Loop;
+ }
+ case Icode_REF_INC_DEC : {
+ Ref ref = (Ref)stack[stackTop];
+ stack[stackTop] = ScriptRuntime.refIncrDecr(ref, cx, iCode[frame.pc]);
+ ++frame.pc;
+ continue Loop;
+ }
+ case Token.LOCAL_LOAD :
+ ++stackTop;
+ indexReg += frame.localShift;
+ stack[stackTop] = stack[indexReg];
+ sDbl[stackTop] = sDbl[indexReg];
+ continue Loop;
+ case Icode_LOCAL_CLEAR :
+ indexReg += frame.localShift;
+ stack[indexReg] = null;
+ continue Loop;
+ case Icode_NAME_AND_THIS :
+ // stringReg: name
+ ++stackTop;
+ stack[stackTop] = ScriptRuntime.getNameFunctionAndThis(stringReg,
+ cx, frame.scope);
+ ++stackTop;
+ stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
+ continue Loop;
+ case Icode_PROP_AND_THIS: {
+ Object obj = stack[stackTop];
+ if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ // stringReg: property
+ stack[stackTop] = ScriptRuntime.getPropFunctionAndThis(obj, stringReg,
+ cx);
+ ++stackTop;
+ stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
+ continue Loop;
+ }
+ case Icode_ELEM_AND_THIS: {
+ Object obj = stack[stackTop - 1];
+ if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop - 1]);
+ Object id = stack[stackTop];
+ if (id == DBL_MRK) id = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop - 1] = ScriptRuntime.getElemFunctionAndThis(obj, id, cx);
+ stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
+ continue Loop;
+ }
+ case Icode_VALUE_AND_THIS : {
+ Object value = stack[stackTop];
+ if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.getValueFunctionAndThis(value, cx);
+ ++stackTop;
+ stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
+ continue Loop;
+ }
+ case Icode_CALLSPECIAL : {
+ if (instructionCounting) {
+ cx.instructionCount += INVOCATION_COST;
+ }
+ int callType = iCode[frame.pc] & 0xFF;
+ boolean isNew = (iCode[frame.pc + 1] != 0);
+ int sourceLine = getIndex(iCode, frame.pc + 2);
+
+ // indexReg: number of arguments
+ if (isNew) {
+ // stack change: function arg0 .. argN -> newResult
+ stackTop -= indexReg;
+
+ Object function = stack[stackTop];
+ if (function == DBL_MRK)
+ function = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ Object[] outArgs = getArgsArray(
+ stack, sDbl, stackTop + 1, indexReg);
+ stack[stackTop] = ScriptRuntime.newSpecial(
+ cx, function, outArgs, frame.scope, callType);
+ } else {
+ // stack change: function thisObj arg0 .. argN -> result
+ stackTop -= 1 + indexReg;
+
+ // Call code generation ensure that stack here
+ // is ... Callable Scriptable
+ Scriptable functionThis = (Scriptable)stack[stackTop + 1];
+ Callable function = (Callable)stack[stackTop];
+ Object[] outArgs = getArgsArray(
+ stack, sDbl, stackTop + 2, indexReg);
+ stack[stackTop] = ScriptRuntime.callSpecial(
+ cx, function, functionThis, outArgs,
+ frame.scope, frame.thisObj, callType,
+ frame.idata.itsSourceFile, sourceLine);
+ }
+ frame.pc += 4;
+ continue Loop;
+ }
+ case Token.CALL :
+ case Icode_TAIL_CALL :
+ case Token.REF_CALL : {
+ if (instructionCounting) {
+ cx.instructionCount += INVOCATION_COST;
+ }
+ // stack change: function thisObj arg0 .. argN -> result
+ // indexReg: number of arguments
+ stackTop -= 1 + indexReg;
+
+ // CALL generation ensures that fun and funThisObj
+ // are already Scriptable and Callable objects respectively
+ Callable fun = (Callable)stack[stackTop];
+ Scriptable funThisObj = (Scriptable)stack[stackTop + 1];
+ if (op == Token.REF_CALL) {
+ Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 2,
+ indexReg);
+ stack[stackTop] = ScriptRuntime.callRef(fun, funThisObj,
+ outArgs, cx);
+ continue Loop;
+ }
+ Scriptable calleeScope = frame.scope;
+ if (frame.useActivation) {
+ calleeScope = ScriptableObject.getTopLevelScope(frame.scope);
+ }
+ if (fun instanceof InterpretedFunction) {
+ InterpretedFunction ifun = (InterpretedFunction)fun;
+ if (frame.fnOrScript.securityDomain == ifun.securityDomain) {
+ CallFrame callParentFrame = frame;
+ CallFrame calleeFrame = new CallFrame();
+ if (op == Icode_TAIL_CALL) {
+ // In principle tail call can re-use the current
+ // frame and its stack arrays but it is hard to
+ // do properly. Any exceptions that can legally
+ // happen during frame re-initialization including
+ // StackOverflowException during innocent looking
+ // System.arraycopy may leave the current frame
+ // data corrupted leading to undefined behaviour
+ // in the catch code bellow that unwinds JS stack
+ // on exceptions. Then there is issue about frame release
+ // end exceptions there.
+ // To avoid frame allocation a released frame
+ // can be cached for re-use which would also benefit
+ // non-tail calls but it is not clear that this caching
+ // would gain in performance due to potentially
+ // bad interaction with GC.
+ callParentFrame = frame.parentFrame;
+ // Release the current frame. See Bug #344501 to see why
+ // it is being done here.
+ exitFrame(cx, frame, null);
+ }
+ initFrame(cx, calleeScope, funThisObj, stack, sDbl,
+ stackTop + 2, indexReg, ifun, callParentFrame,
+ calleeFrame);
+ if (op != Icode_TAIL_CALL) {
+ frame.savedStackTop = stackTop;
+ frame.savedCallOp = op;
+ }
+ frame = calleeFrame;
+ continue StateLoop;
+ }
+ }
+
+ if (fun instanceof Continuation) {
+ // Jump to the captured continuation
+ ContinuationJump cjump;
+ cjump = new ContinuationJump((Continuation)fun, frame);
+
+ // continuation result is the first argument if any
+ // of contination call
+ if (indexReg == 0) {
+ cjump.result = undefined;
+ } else {
+ cjump.result = stack[stackTop + 2];
+ cjump.resultDbl = sDbl[stackTop + 2];
+ }
+
+ // Start the real unwind job
+ throwable = cjump;
+ break withoutExceptions;
+ }
+
+ if (fun instanceof IdFunctionObject) {
+ IdFunctionObject ifun = (IdFunctionObject)fun;
+ if (Continuation.isContinuationConstructor(ifun)) {
+ captureContinuation(cx, frame, stackTop);
+ continue Loop;
+ }
+ // Bug 405654 -- make best effort to keep Function.apply and
+ // Function.call within this interpreter loop invocation
+ if(BaseFunction.isApplyOrCall(ifun)) {
+ Callable applyCallable = ScriptRuntime.getCallable(funThisObj);
+ if(applyCallable instanceof InterpretedFunction) {
+ InterpretedFunction iApplyCallable = (InterpretedFunction)applyCallable;
+ if(frame.fnOrScript.securityDomain == iApplyCallable.securityDomain) {
+ frame = initFrameForApplyOrCall(cx, frame, indexReg,
+ stack, sDbl, stackTop, op, calleeScope, ifun,
+ iApplyCallable);
+ continue StateLoop;
+ }
+ }
+ }
+ }
+
+ stack[stackTop] = fun.call(cx, calleeScope, funThisObj,
+ getArgsArray(stack, sDbl, stackTop + 2, indexReg));
+
+ continue Loop;
+ }
+ case Token.NEW : {
+ if (instructionCounting) {
+ cx.instructionCount += INVOCATION_COST;
+ }
+ // stack change: function arg0 .. argN -> newResult
+ // indexReg: number of arguments
+ stackTop -= indexReg;
+
+ Object lhs = stack[stackTop];
+ if (lhs instanceof InterpretedFunction) {
+ InterpretedFunction f = (InterpretedFunction)lhs;
+ if (frame.fnOrScript.securityDomain == f.securityDomain) {
+ Scriptable newInstance = f.createObject(cx, frame.scope);
+ CallFrame calleeFrame = new CallFrame();
+ initFrame(cx, frame.scope, newInstance, stack, sDbl,
+ stackTop + 1, indexReg, f, frame,
+ calleeFrame);
+
+ stack[stackTop] = newInstance;
+ frame.savedStackTop = stackTop;
+ frame.savedCallOp = op;
+ frame = calleeFrame;
+ continue StateLoop;
+ }
+ }
+ if (!(lhs instanceof Function)) {
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ throw ScriptRuntime.notFunctionError(lhs);
+ }
+ Function fun = (Function)lhs;
+
+ if (fun instanceof IdFunctionObject) {
+ IdFunctionObject ifun = (IdFunctionObject)fun;
+ if (Continuation.isContinuationConstructor(ifun)) {
+ captureContinuation(cx, frame, stackTop);
+ continue Loop;
+ }
+ }
+
+ Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 1, indexReg);
+ stack[stackTop] = fun.construct(cx, frame.scope, outArgs);
+ continue Loop;
+ }
+ case Token.TYPEOF : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.typeof(lhs);
+ continue Loop;
+ }
+ case Icode_TYPEOFNAME :
+ stack[++stackTop] = ScriptRuntime.typeofName(frame.scope, stringReg);
+ continue Loop;
+ case Token.STRING :
+ stack[++stackTop] = stringReg;
+ continue Loop;
+ case Icode_SHORTNUMBER :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = getShort(iCode, frame.pc);
+ frame.pc += 2;
+ continue Loop;
+ case Icode_INTNUMBER :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = getInt(iCode, frame.pc);
+ frame.pc += 4;
+ continue Loop;
+ case Token.NUMBER :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = frame.idata.itsDoubleTable[indexReg];
+ continue Loop;
+ case Token.NAME :
+ stack[++stackTop] = ScriptRuntime.name(cx, frame.scope, stringReg);
+ continue Loop;
+ case Icode_NAME_INC_DEC :
+ stack[++stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, stringReg,
+ cx, iCode[frame.pc]);
+ ++frame.pc;
+ continue Loop;
+ case Icode_SETCONSTVAR1:
+ indexReg = iCode[frame.pc++];
+ // fallthrough
+ case Token.SETCONSTVAR :
+ if (!frame.useActivation) {
+ if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) {
+ throw Context.reportRuntimeError1("msg.var.redecl",
+ frame.idata.argNames[indexReg]);
+ }
+ if ((varAttributes[indexReg] & ScriptableObject.UNINITIALIZED_CONST)
+ != 0)
+ {
+ vars[indexReg] = stack[stackTop];
+ varAttributes[indexReg] &= ~ScriptableObject.UNINITIALIZED_CONST;
+ varDbls[indexReg] = sDbl[stackTop];
+ }
+ } else {
+ Object val = stack[stackTop];
+ if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stringReg = frame.idata.argNames[indexReg];
+ if (frame.scope instanceof ConstProperties) {
+ ConstProperties cp = (ConstProperties)frame.scope;
+ cp.putConst(stringReg, frame.scope, val);
+ } else
+ throw Kit.codeBug();
+ }
+ continue Loop;
+ case Icode_SETVAR1:
+ indexReg = iCode[frame.pc++];
+ // fallthrough
+ case Token.SETVAR :
+ if (!frame.useActivation) {
+ if ((varAttributes[indexReg] & ScriptableObject.READONLY) == 0) {
+ vars[indexReg] = stack[stackTop];
+ varDbls[indexReg] = sDbl[stackTop];
+ }
+ } else {
+ Object val = stack[stackTop];
+ if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stringReg = frame.idata.argNames[indexReg];
+ frame.scope.put(stringReg, frame.scope, val);
+ }
+ continue Loop;
+ case Icode_GETVAR1:
+ indexReg = iCode[frame.pc++];
+ // fallthrough
+ case Token.GETVAR :
+ ++stackTop;
+ if (!frame.useActivation) {
+ stack[stackTop] = vars[indexReg];
+ sDbl[stackTop] = varDbls[indexReg];
+ } else {
+ stringReg = frame.idata.argNames[indexReg];
+ stack[stackTop] = frame.scope.get(stringReg, frame.scope);
+ }
+ continue Loop;
+ case Icode_VAR_INC_DEC : {
+ // indexReg : varindex
+ ++stackTop;
+ int incrDecrMask = iCode[frame.pc];
+ if (!frame.useActivation) {
+ stack[stackTop] = DBL_MRK;
+ Object varValue = vars[indexReg];
+ double d;
+ if (varValue == DBL_MRK) {
+ d = varDbls[indexReg];
+ } else {
+ d = ScriptRuntime.toNumber(varValue);
+ vars[indexReg] = DBL_MRK;
+ }
+ double d2 = ((incrDecrMask & Node.DECR_FLAG) == 0)
+ ? d + 1.0 : d - 1.0;
+ varDbls[indexReg] = d2;
+ sDbl[stackTop] = ((incrDecrMask & Node.POST_FLAG) == 0) ? d2 : d;
+ } else {
+ String varName = frame.idata.argNames[indexReg];
+ stack[stackTop] = ScriptRuntime.nameIncrDecr(frame.scope, varName,
+ cx, incrDecrMask);
+ }
+ ++frame.pc;
+ continue Loop;
+ }
+ case Icode_ZERO :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = 0;
+ continue Loop;
+ case Icode_ONE :
+ ++stackTop;
+ stack[stackTop] = DBL_MRK;
+ sDbl[stackTop] = 1;
+ continue Loop;
+ case Token.NULL :
+ stack[++stackTop] = null;
+ continue Loop;
+ case Token.THIS :
+ stack[++stackTop] = frame.thisObj;
+ continue Loop;
+ case Token.THISFN :
+ stack[++stackTop] = frame.fnOrScript;
+ continue Loop;
+ case Token.FALSE :
+ stack[++stackTop] = Boolean.FALSE;
+ continue Loop;
+ case Token.TRUE :
+ stack[++stackTop] = Boolean.TRUE;
+ continue Loop;
+ case Icode_UNDEF :
+ stack[++stackTop] = undefined;
+ continue Loop;
+ case Token.ENTERWITH : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ frame.scope = ScriptRuntime.enterWith(lhs, cx, frame.scope);
+ continue Loop;
+ }
+ case Token.LEAVEWITH :
+ frame.scope = ScriptRuntime.leaveWith(frame.scope);
+ continue Loop;
+ case Token.CATCH_SCOPE : {
+ // stack top: exception object
+ // stringReg: name of exception variable
+ // indexReg: local for exception scope
+ --stackTop;
+ indexReg += frame.localShift;
+
+ boolean afterFirstScope = (frame.idata.itsICode[frame.pc] != 0);
+ Throwable caughtException = (Throwable)stack[stackTop + 1];
+ Scriptable lastCatchScope;
+ if (!afterFirstScope) {
+ lastCatchScope = null;
+ } else {
+ lastCatchScope = (Scriptable)stack[indexReg];
+ }
+ stack[indexReg] = ScriptRuntime.newCatchScope(caughtException,
+ lastCatchScope, stringReg,
+ cx, frame.scope);
+ ++frame.pc;
+ continue Loop;
+ }
+ case Token.ENUM_INIT_KEYS :
+ case Token.ENUM_INIT_VALUES :
+ case Token.ENUM_INIT_ARRAY : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ indexReg += frame.localShift;
+ int enumType = op == Token.ENUM_INIT_KEYS
+ ? ScriptRuntime.ENUMERATE_KEYS :
+ op == Token.ENUM_INIT_VALUES
+ ? ScriptRuntime.ENUMERATE_VALUES :
+ ScriptRuntime.ENUMERATE_ARRAY;
+ stack[indexReg] = ScriptRuntime.enumInit(lhs, cx, enumType);
+ continue Loop;
+ }
+ case Token.ENUM_NEXT :
+ case Token.ENUM_ID : {
+ indexReg += frame.localShift;
+ Object val = stack[indexReg];
+ ++stackTop;
+ stack[stackTop] = (op == Token.ENUM_NEXT)
+ ? (Object)ScriptRuntime.enumNext(val)
+ : (Object)ScriptRuntime.enumId(val, cx);
+ continue Loop;
+ }
+ case Token.REF_SPECIAL : {
+ //stringReg: name of special property
+ Object obj = stack[stackTop];
+ if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.specialRef(obj, stringReg, cx);
+ continue Loop;
+ }
+ case Token.REF_MEMBER: {
+ //indexReg: flags
+ Object elem = stack[stackTop];
+ if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object obj = stack[stackTop];
+ if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.memberRef(obj, elem, cx, indexReg);
+ continue Loop;
+ }
+ case Token.REF_NS_MEMBER: {
+ //indexReg: flags
+ Object elem = stack[stackTop];
+ if (elem == DBL_MRK) elem = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object ns = stack[stackTop];
+ if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object obj = stack[stackTop];
+ if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.memberRef(obj, ns, elem, cx, indexReg);
+ continue Loop;
+ }
+ case Token.REF_NAME: {
+ //indexReg: flags
+ Object name = stack[stackTop];
+ if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.nameRef(name, cx, frame.scope,
+ indexReg);
+ continue Loop;
+ }
+ case Token.REF_NS_NAME: {
+ //indexReg: flags
+ Object name = stack[stackTop];
+ if (name == DBL_MRK) name = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ Object ns = stack[stackTop];
+ if (ns == DBL_MRK) ns = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.nameRef(ns, name, cx, frame.scope,
+ indexReg);
+ continue Loop;
+ }
+ case Icode_SCOPE_LOAD :
+ indexReg += frame.localShift;
+ frame.scope = (Scriptable)stack[indexReg];
+ continue Loop;
+ case Icode_SCOPE_SAVE :
+ indexReg += frame.localShift;
+ stack[indexReg] = frame.scope;
+ continue Loop;
+ case Icode_CLOSURE_EXPR :
+ stack[++stackTop] = InterpretedFunction.createFunction(cx, frame.scope,
+ frame.fnOrScript,
+ indexReg);
+ continue Loop;
+ case Icode_CLOSURE_STMT :
+ initFunction(cx, frame.scope, frame.fnOrScript, indexReg);
+ continue Loop;
+ case Token.REGEXP :
+ stack[++stackTop] = frame.scriptRegExps[indexReg];
+ continue Loop;
+ case Icode_LITERAL_NEW :
+ // indexReg: number of values in the literal
+ ++stackTop;
+ stack[stackTop] = new int[indexReg];
+ ++stackTop;
+ stack[stackTop] = new Object[indexReg];
+ sDbl[stackTop] = 0;
+ continue Loop;
+ case Icode_LITERAL_SET : {
+ Object value = stack[stackTop];
+ if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ int i = (int)sDbl[stackTop];
+ ((Object[])stack[stackTop])[i] = value;
+ sDbl[stackTop] = i + 1;
+ continue Loop;
+ }
+ case Icode_LITERAL_GETTER : {
+ Object value = stack[stackTop];
+ --stackTop;
+ int i = (int)sDbl[stackTop];
+ ((Object[])stack[stackTop])[i] = value;
+ ((int[])stack[stackTop - 1])[i] = -1;
+ sDbl[stackTop] = i + 1;
+ continue Loop;
+ }
+ case Icode_LITERAL_SETTER : {
+ Object value = stack[stackTop];
+ --stackTop;
+ int i = (int)sDbl[stackTop];
+ ((Object[])stack[stackTop])[i] = value;
+ ((int[])stack[stackTop - 1])[i] = +1;
+ sDbl[stackTop] = i + 1;
+ continue Loop;
+ }
+ case Token.ARRAYLIT :
+ case Icode_SPARE_ARRAYLIT :
+ case Token.OBJECTLIT : {
+ Object[] data = (Object[])stack[stackTop];
+ --stackTop;
+ int[] getterSetters = (int[])stack[stackTop];
+ Object val;
+ if (op == Token.OBJECTLIT) {
+ Object[] ids = (Object[])frame.idata.literalIds[indexReg];
+ val = ScriptRuntime.newObjectLiteral(ids, data, getterSetters, cx,
+ frame.scope);
+ } else {
+ int[] skipIndexces = null;
+ if (op == Icode_SPARE_ARRAYLIT) {
+ skipIndexces = (int[])frame.idata.literalIds[indexReg];
+ }
+ val = ScriptRuntime.newArrayLiteral(data, skipIndexces, cx,
+ frame.scope);
+ }
+ stack[stackTop] = val;
+ continue Loop;
+ }
+ case Icode_ENTERDQ : {
+ Object lhs = stack[stackTop];
+ if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ --stackTop;
+ frame.scope = ScriptRuntime.enterDotQuery(lhs, frame.scope);
+ continue Loop;
+ }
+ case Icode_LEAVEDQ : {
+ boolean valBln = stack_boolean(frame, stackTop);
+ Object x = ScriptRuntime.updateDotQuery(valBln, frame.scope);
+ if (x != null) {
+ stack[stackTop] = x;
+ frame.scope = ScriptRuntime.leaveDotQuery(frame.scope);
+ frame.pc += 2;
+ continue Loop;
+ }
+ // reset stack and PC to code after ENTERDQ
+ --stackTop;
+ break jumplessRun;
+ }
+ case Token.DEFAULTNAMESPACE : {
+ Object value = stack[stackTop];
+ if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
+ stack[stackTop] = ScriptRuntime.setDefaultNamespace(value, cx);
+ continue Loop;
+ }
+ case Token.ESCXMLATTR : {
+ Object value = stack[stackTop];
+ if (value != DBL_MRK) {
+ stack[stackTop] = ScriptRuntime.escapeAttributeValue(value, cx);
+ }
+ continue Loop;
+ }
+ case Token.ESCXMLTEXT : {
+ Object value = stack[stackTop];
+ if (value != DBL_MRK) {
+ stack[stackTop] = ScriptRuntime.escapeTextValue(value, cx);
+ }
+ continue Loop;
+ }
+ case Icode_DEBUGGER:
+ if (frame.debuggerFrame != null) {
+ frame.debuggerFrame.onDebuggerStatement(cx);
+ }
+ break Loop;
+ case Icode_LINE :
+ frame.pcSourceLineStart = frame.pc;
+ if (frame.debuggerFrame != null) {
+ int line = getIndex(iCode, frame.pc);
+ frame.debuggerFrame.onLineChange(cx, line);
+ }
+ frame.pc += 2;
+ continue Loop;
+ case Icode_REG_IND_C0:
+ indexReg = 0;
+ continue Loop;
+ case Icode_REG_IND_C1:
+ indexReg = 1;
+ continue Loop;
+ case Icode_REG_IND_C2:
+ indexReg = 2;
+ continue Loop;
+ case Icode_REG_IND_C3:
+ indexReg = 3;
+ continue Loop;
+ case Icode_REG_IND_C4:
+ indexReg = 4;
+ continue Loop;
+ case Icode_REG_IND_C5:
+ indexReg = 5;
+ continue Loop;
+ case Icode_REG_IND1:
+ indexReg = 0xFF & iCode[frame.pc];
+ ++frame.pc;
+ continue Loop;
+ case Icode_REG_IND2:
+ indexReg = getIndex(iCode, frame.pc);
+ frame.pc += 2;
+ continue Loop;
+ case Icode_REG_IND4:
+ indexReg = getInt(iCode, frame.pc);
+ frame.pc += 4;
+ continue Loop;
+ case Icode_REG_STR_C0:
+ stringReg = strings[0];
+ continue Loop;
+ case Icode_REG_STR_C1:
+ stringReg = strings[1];
+ continue Loop;
+ case Icode_REG_STR_C2:
+ stringReg = strings[2];
+ continue Loop;
+ case Icode_REG_STR_C3:
+ stringReg = strings[3];
+ continue Loop;
+ case Icode_REG_STR1:
+ stringReg = strings[0xFF & iCode[frame.pc]];
+ ++frame.pc;
+ continue Loop;
+ case Icode_REG_STR2:
+ stringReg = strings[getIndex(iCode, frame.pc)];
+ frame.pc += 2;
+ continue Loop;
+ case Icode_REG_STR4:
+ stringReg = strings[getInt(iCode, frame.pc)];
+ frame.pc += 4;
+ continue Loop;
+ default :
+ dumpICode(frame.idata);
+ throw new RuntimeException(
+ "Unknown icode : "+op+" @ pc : "+(frame.pc-1));
+} // end of interpreter switch
+
+ } // end of jumplessRun label block
+
+ // This should be reachable only for jump implementation
+ // when pc points to encoded target offset
+ if (instructionCounting) {
+ addInstructionCount(cx, frame, 2);
+ }
+ int offset = getShort(iCode, frame.pc);
+ if (offset != 0) {
+ // -1 accounts for pc pointing to jump opcode + 1
+ frame.pc += offset - 1;
+ } else {
+ frame.pc = frame.idata.longJumps.
+ getExistingInt(frame.pc);
+ }
+ if (instructionCounting) {
+ frame.pcPrevBranch = frame.pc;
+ }
+ continue Loop;
+
+ } // end of Loop: for
+
+ exitFrame(cx, frame, null);
+ interpreterResult = frame.result;
+ interpreterResultDbl = frame.resultDbl;
+ if (frame.parentFrame != null) {
+ frame = frame.parentFrame;
+ if (frame.frozen) {
+ frame = frame.cloneFrozen();
+ }
+ setCallResult(
+ frame, interpreterResult, interpreterResultDbl);
+ interpreterResult = null; // Help GC
+ continue StateLoop;
+ }
+ break StateLoop;
+
+ } // end of interpreter withoutExceptions: try
+ catch (Throwable ex) {
+ if (throwable != null) {
+ // This is serious bug and it is better to track it ASAP
+ ex.printStackTrace(System.err);
+ throw new IllegalStateException();
+ }
+ throwable = ex;
+ }
+
+ // This should be reachable only after above catch or from
+ // finally when it needs to propagate exception or from
+ // explicit throw
+ if (throwable == null) Kit.codeBug();
+
+ // Exception type
+ final int EX_CATCH_STATE = 2; // Can execute JS catch
+ final int EX_FINALLY_STATE = 1; // Can execute JS finally
+ final int EX_NO_JS_STATE = 0; // Terminate JS execution
+
+ int exState;
+ ContinuationJump cjump = null;
+
+ if (generatorState != null &&
+ generatorState.operation == NativeGenerator.GENERATOR_CLOSE &&
+ throwable == generatorState.value)
+ {
+ exState = EX_FINALLY_STATE;
+ } else if (throwable instanceof JavaScriptException) {
+ exState = EX_CATCH_STATE;
+ } else if (throwable instanceof EcmaError) {
+ // an offical ECMA error object,
+ exState = EX_CATCH_STATE;
+ } else if (throwable instanceof EvaluatorException) {
+ exState = EX_CATCH_STATE;
+ } else if (throwable instanceof RuntimeException) {
+ exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
+ ? EX_CATCH_STATE
+ : EX_FINALLY_STATE;
+ } else if (throwable instanceof Error) {
+ exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
+ ? EX_CATCH_STATE
+ : EX_NO_JS_STATE;
+ } else if (throwable instanceof ContinuationJump) {
+ // It must be ContinuationJump
+ exState = EX_FINALLY_STATE;
+ cjump = (ContinuationJump)throwable;
+ } else {
+ exState = cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)
+ ? EX_CATCH_STATE
+ : EX_FINALLY_STATE;
+ }
+
+ if (instructionCounting) {
+ try {
+ addInstructionCount(cx, frame, EXCEPTION_COST);
+ } catch (RuntimeException ex) {
+ throwable = ex;
+ exState = EX_FINALLY_STATE;
+ } catch (Error ex) {
+ // Error from instruction counting
+ // => unconditionally terminate JS
+ throwable = ex;
+ cjump = null;
+ exState = EX_NO_JS_STATE;
+ }
+ }
+ if (frame.debuggerFrame != null
+ && throwable instanceof RuntimeException)
+ {
+ // Call debugger only for RuntimeException
+ RuntimeException rex = (RuntimeException)throwable;
+ try {
+ frame.debuggerFrame.onExceptionThrown(cx, rex);
+ } catch (Throwable ex) {
+ // Any exception from debugger
+ // => unconditionally terminate JS
+ throwable = ex;
+ cjump = null;
+ exState = EX_NO_JS_STATE;
+ }
+ }
+
+ for (;;) {
+ if (exState != EX_NO_JS_STATE) {
+ boolean onlyFinally = (exState != EX_CATCH_STATE);
+ indexReg = getExceptionHandler(frame, onlyFinally);
+ if (indexReg >= 0) {
+ // We caught an exception, restart the loop
+ // with exception pending the processing at the loop
+ // start
+ continue StateLoop;
+ }
+ }
+ // No allowed exception handlers in this frame, unwind
+ // to parent and try to look there
+
+ exitFrame(cx, frame, throwable);
+
+ frame = frame.parentFrame;
+ if (frame == null) { break; }
+ if (cjump != null && cjump.branchFrame == frame) {
+ // Continuation branch point was hit,
+ // restart the state loop to reenter continuation
+ indexReg = -1;
+ continue StateLoop;
+ }
+ }
+
+ // No more frames, rethrow the exception or deal with continuation
+ if (cjump != null) {
+ if (cjump.branchFrame != null) {
+ // The above loop should locate the top frame
+ Kit.codeBug();
+ }
+ if (cjump.capturedFrame != null) {
+ // Restarting detached continuation
+ indexReg = -1;
+ continue StateLoop;
+ }
+ // Return continuation result to the caller
+ interpreterResult = cjump.result;
+ interpreterResultDbl = cjump.resultDbl;
+ throwable = null;
+ }
+ break StateLoop;
+
+ } // end of StateLoop: for(;;)
+
+ // Do cleanups/restorations before the final return or throw
+
+ if (cx.previousInterpreterInvocations != null
+ && cx.previousInterpreterInvocations.size() != 0)
+ {
+ cx.lastInterpreterFrame
+ = cx.previousInterpreterInvocations.pop();
+ } else {
+ // It was the last interpreter frame on the stack
+ cx.lastInterpreterFrame = null;
+ // Force GC of the value cx.previousInterpreterInvocations
+ cx.previousInterpreterInvocations = null;
+ }
+
+ if (throwable != null) {
+ if (throwable instanceof RuntimeException) {
+ throw (RuntimeException)throwable;
+ } else {
+ // Must be instance of Error or code bug
+ throw (Error)throwable;
+ }
+ }
+
+ return (interpreterResult != DBL_MRK)
+ ? interpreterResult
+ : ScriptRuntime.wrapNumber(interpreterResultDbl);
+ }
+
+ private static CallFrame processThrowable(Context cx, Object throwable,
+ CallFrame frame, int indexReg,
+ boolean instructionCounting)
+ {
+ // Recovering from exception, indexReg contains
+ // the index of handler
+
+ if (indexReg >= 0) {
+ // Normal exception handler, transfer
+ // control appropriately
+
+ if (frame.frozen) {
+ // XXX Deal with exceptios!!!
+ frame = frame.cloneFrozen();
+ }
+
+ int[] table = frame.idata.itsExceptionTable;
+
+ frame.pc = table[indexReg + EXCEPTION_HANDLER_SLOT];
+ if (instructionCounting) {
+ frame.pcPrevBranch = frame.pc;
+ }
+
+ frame.savedStackTop = frame.emptyStackTop;
+ int scopeLocal = frame.localShift
+ + table[indexReg
+ + EXCEPTION_SCOPE_SLOT];
+ int exLocal = frame.localShift
+ + table[indexReg
+ + EXCEPTION_LOCAL_SLOT];
+ frame.scope = (Scriptable)frame.stack[scopeLocal];
+ frame.stack[exLocal] = throwable;
+
+ throwable = null;
+ } else {
+ // Continuation restoration
+ ContinuationJump cjump = (ContinuationJump)throwable;
+
+ // Clear throwable to indicate that exceptions are OK
+ throwable = null;
+
+ if (cjump.branchFrame != frame) Kit.codeBug();
+
+ // Check that we have at least one frozen frame
+ // in the case of detached continuation restoration:
+ // unwind code ensure that
+ if (cjump.capturedFrame == null) Kit.codeBug();
+
+ // Need to rewind branchFrame, capturedFrame
+ // and all frames in between
+ int rewindCount = cjump.capturedFrame.frameIndex + 1;
+ if (cjump.branchFrame != null) {
+ rewindCount -= cjump.branchFrame.frameIndex;
+ }
+
+ int enterCount = 0;
+ CallFrame[] enterFrames = null;
+
+ CallFrame x = cjump.capturedFrame;
+ for (int i = 0; i != rewindCount; ++i) {
+ if (!x.frozen) Kit.codeBug();
+ if (isFrameEnterExitRequired(x)) {
+ if (enterFrames == null) {
+ // Allocate enough space to store the rest
+ // of rewind frames in case all of them
+ // would require to enter
+ enterFrames = new CallFrame[rewindCount
+ - i];
+ }
+ enterFrames[enterCount] = x;
+ ++enterCount;
+ }
+ x = x.parentFrame;
+ }
+
+ while (enterCount != 0) {
+ // execute enter: walk enterFrames in the reverse
+ // order since they were stored starting from
+ // the capturedFrame, not branchFrame
+ --enterCount;
+ x = enterFrames[enterCount];
+ enterFrame(cx, x, ScriptRuntime.emptyArgs, true);
+ }
+
+ // Continuation jump is almost done: capturedFrame
+ // points to the call to the function that captured
+ // continuation, so clone capturedFrame and
+ // emulate return that function with the suplied result
+ frame = cjump.capturedFrame.cloneFrozen();
+ setCallResult(frame, cjump.result, cjump.resultDbl);
+ // restart the execution
+ }
+ frame.throwable = throwable;
+ return frame;
+ }
+
+ private static Object freezeGenerator(Context cx, CallFrame frame,
+ int stackTop,
+ GeneratorState generatorState)
+ {
+ if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) {
+ // Error: no yields when generator is closing
+ throw ScriptRuntime.typeError0("msg.yield.closing");
+ }
+ // return to our caller (which should be a method of NativeGenerator)
+ frame.frozen = true;
+ frame.result = frame.stack[stackTop];
+ frame.resultDbl = frame.sDbl[stackTop];
+ frame.savedStackTop = stackTop;
+ frame.pc--; // we want to come back here when we resume
+ ScriptRuntime.exitActivationFunction(cx);
+ return (frame.result != UniqueTag.DOUBLE_MARK)
+ ? frame.result
+ : ScriptRuntime.wrapNumber(frame.resultDbl);
+ }
+
+ private static Object thawGenerator(CallFrame frame, int stackTop,
+ GeneratorState generatorState, int op)
+ {
+ // we are resuming execution
+ frame.frozen = false;
+ int sourceLine = getIndex(frame.idata.itsICode, frame.pc);
+ frame.pc += 2; // skip line number data
+ if (generatorState.operation == NativeGenerator.GENERATOR_THROW) {
+ // processing a call to <generator>.throw(exception): must
+ // act as if exception was thrown from resumption point
+ return new JavaScriptException(generatorState.value,
+ frame.idata.itsSourceFile,
+ sourceLine);
+ }
+ if (generatorState.operation == NativeGenerator.GENERATOR_CLOSE) {
+ return generatorState.value;
+ }
+ if (generatorState.operation != NativeGenerator.GENERATOR_SEND)
+ throw Kit.codeBug();
+ if (op == Token.YIELD)
+ frame.stack[stackTop] = generatorState.value;
+ return Scriptable.NOT_FOUND;
+ }
+
+ private static CallFrame initFrameForApplyOrCall(Context cx, CallFrame frame,
+ int indexReg, Object[] stack, double[] sDbl, int stackTop, int op,
+ Scriptable calleeScope, IdFunctionObject ifun,
+ InterpretedFunction iApplyCallable)
+ {
+ Scriptable applyThis;
+ if (indexReg != 0) {
+ applyThis = ScriptRuntime.toObjectOrNull(cx, stack[stackTop + 2]);
+ }
+ else {
+ applyThis = null;
+ }
+ if (applyThis == null) {
+ // This covers the case of args[0] == (null|undefined) as well.
+ applyThis = ScriptRuntime.getTopCallScope(cx);
+ }
+ if(op == Icode_TAIL_CALL) {
+ exitFrame(cx, frame, null);
+ frame = frame.parentFrame;
+ }
+ else {
+ frame.savedStackTop = stackTop;
+ frame.savedCallOp = op;
+ }
+ CallFrame calleeFrame = new CallFrame();
+ if(BaseFunction.isApply(ifun)) {
+ Object[] callArgs = indexReg < 2 ? ScriptRuntime.emptyArgs :
+ ScriptRuntime.getApplyArguments(cx, stack[stackTop + 3]);
+ initFrame(cx, calleeScope, applyThis, callArgs, null, 0,
+ callArgs.length, iApplyCallable, frame, calleeFrame);
+ }
+ else {
+ // Shift args left
+ for(int i = 1; i < indexReg; ++i) {
+ stack[stackTop + 1 + i] = stack[stackTop + 2 + i];
+ sDbl[stackTop + 1 + i] = sDbl[stackTop + 2 + i];
+ }
+ int argCount = indexReg < 2 ? 0 : indexReg - 1;
+ initFrame(cx, calleeScope, applyThis, stack, sDbl, stackTop + 2,
+ argCount, iApplyCallable, frame, calleeFrame);
+ }
+
+ frame = calleeFrame;
+ return frame;
+ }
+
+ private static void initFrame(Context cx, Scriptable callerScope,
+ Scriptable thisObj,
+ Object[] args, double[] argsDbl,
+ int argShift, int argCount,
+ InterpretedFunction fnOrScript,
+ CallFrame parentFrame, CallFrame frame)
+ {
+ InterpreterData idata = fnOrScript.idata;
+
+ boolean useActivation = idata.itsNeedsActivation;
+ DebugFrame debuggerFrame = null;
+ if (cx.debugger != null) {
+ debuggerFrame = cx.debugger.getFrame(cx, idata);
+ if (debuggerFrame != null) {
+ useActivation = true;
+ }
+ }
+
+ if (useActivation) {
+ // Copy args to new array to pass to enterActivationFunction
+ // or debuggerFrame.onEnter
+ if (argsDbl != null) {
+ args = getArgsArray(args, argsDbl, argShift, argCount);
+ }
+ argShift = 0;
+ argsDbl = null;
+ }
+
+ Scriptable scope;
+ if (idata.itsFunctionType != 0) {
+ if (!idata.useDynamicScope) {
+ scope = fnOrScript.getParentScope();
+ } else {
+ scope = callerScope;
+ }
+
+ if (useActivation) {
+ scope = ScriptRuntime.createFunctionActivation(
+ fnOrScript, scope, args);
+ }
+ } else {
+ scope = callerScope;
+ ScriptRuntime.initScript(fnOrScript, thisObj, cx, scope,
+ fnOrScript.idata.evalScriptFlag);
+ }
+
+ if (idata.itsNestedFunctions != null) {
+ if (idata.itsFunctionType != 0 && !idata.itsNeedsActivation)
+ Kit.codeBug();
+ for (int i = 0; i < idata.itsNestedFunctions.length; i++) {
+ InterpreterData fdata = idata.itsNestedFunctions[i];
+ if (fdata.itsFunctionType == FunctionNode.FUNCTION_STATEMENT) {
+ initFunction(cx, scope, fnOrScript, i);
+ }
+ }
+ }
+
+ Scriptable[] scriptRegExps = null;
+ if (idata.itsRegExpLiterals != null) {
+ // Wrapped regexps for functions are stored in
+ // InterpretedFunction
+ // but for script which should not contain references to scope
+ // the regexps re-wrapped during each script execution
+ if (idata.itsFunctionType != 0) {
+ scriptRegExps = fnOrScript.functionRegExps;
+ } else {
+ scriptRegExps = fnOrScript.createRegExpWraps(cx, scope);
+ }
+ }
+
+ // Initialize args, vars, locals and stack
+
+ int emptyStackTop = idata.itsMaxVars + idata.itsMaxLocals - 1;
+ int maxFrameArray = idata.itsMaxFrameArray;
+ if (maxFrameArray != emptyStackTop + idata.itsMaxStack + 1)
+ Kit.codeBug();
+
+ Object[] stack;
+ int[] stackAttributes;
+ double[] sDbl;
+ boolean stackReuse;
+ if (frame.stack != null && maxFrameArray <= frame.stack.length) {
+ // Reuse stacks from old frame
+ stackReuse = true;
+ stack = frame.stack;
+ stackAttributes = frame.stackAttributes;
+ sDbl = frame.sDbl;
+ } else {
+ stackReuse = false;
+ stack = new Object[maxFrameArray];
+ stackAttributes = new int[maxFrameArray];
+ sDbl = new double[maxFrameArray];
+ }
+
+ int varCount = idata.getParamAndVarCount();
+ for (int i = 0; i < varCount; i++) {
+ if (idata.getParamOrVarConst(i))
+ stackAttributes[i] = ScriptableObject.CONST;
+ }
+ int definedArgs = idata.argCount;
+ if (definedArgs > argCount) { definedArgs = argCount; }
+
+ // Fill the frame structure
+
+ frame.parentFrame = parentFrame;
+ frame.frameIndex = (parentFrame == null)
+ ? 0 : parentFrame.frameIndex + 1;
+ if(frame.frameIndex > cx.getMaximumInterpreterStackDepth())
+ {
+ throw Context.reportRuntimeError("Exceeded maximum stack depth");
+ }
+ frame.frozen = false;
+
+ frame.fnOrScript = fnOrScript;
+ frame.idata = idata;
+
+ frame.stack = stack;
+ frame.stackAttributes = stackAttributes;
+ frame.sDbl = sDbl;
+ frame.varSource = frame;
+ frame.localShift = idata.itsMaxVars;
+ frame.emptyStackTop = emptyStackTop;
+
+ frame.debuggerFrame = debuggerFrame;
+ frame.useActivation = useActivation;
+
+ frame.thisObj = thisObj;
+ frame.scriptRegExps = scriptRegExps;
+
+ // Initialize initial values of variables that change during
+ // interpretation.
+ frame.result = Undefined.instance;
+ frame.pc = 0;
+ frame.pcPrevBranch = 0;
+ frame.pcSourceLineStart = idata.firstLinePC;
+ frame.scope = scope;
+
+ frame.savedStackTop = emptyStackTop;
+ frame.savedCallOp = 0;
+
+ System.arraycopy(args, argShift, stack, 0, definedArgs);
+ if (argsDbl != null) {
+ System.arraycopy(argsDbl, argShift, sDbl, 0, definedArgs);
+ }
+ for (int i = definedArgs; i != idata.itsMaxVars; ++i) {
+ stack[i] = Undefined.instance;
+ }
+ if (stackReuse) {
+ // Clean the stack part and space beyond stack if any
+ // of the old array to allow to GC objects there
+ for (int i = emptyStackTop + 1; i != stack.length; ++i) {
+ stack[i] = null;
+ }
+ }
+
+ enterFrame(cx, frame, args, false);
+ }
+
+ private static boolean isFrameEnterExitRequired(CallFrame frame)
+ {
+ return frame.debuggerFrame != null || frame.idata.itsNeedsActivation;
+ }
+
+ private static void enterFrame(Context cx, CallFrame frame, Object[] args,
+ boolean continuationRestart)
+ {
+ boolean usesActivation = frame.idata.itsNeedsActivation;
+ boolean isDebugged = frame.debuggerFrame != null;
+ if(usesActivation || isDebugged) {
+ Scriptable scope = frame.scope;
+ if(scope == null) {
+ Kit.codeBug();
+ } else if (continuationRestart) {
+ // Walk the parent chain of frame.scope until a NativeCall is
+ // found. Normally, frame.scope is a NativeCall when called
+ // from initFrame() for a debugged or activatable function.
+ // However, when called from interpretLoop() as part of
+ // restarting a continuation, it can also be a NativeWith if
+ // the continuation was captured within a "with" or "catch"
+ // block ("catch" implicitly uses NativeWith to create a scope
+ // to expose the exception variable).
+ for(;;) {
+ if(scope instanceof NativeWith) {
+ scope = scope.getParentScope();
+ if (scope == null || (frame.parentFrame != null &&
+ frame.parentFrame.scope == scope))
+ {
+ // If we get here, we didn't find a NativeCall in
+ // the call chain before reaching parent frame's
+ // scope. This should not be possible.
+ Kit.codeBug();
+ break; // Never reached, but keeps the static analyzer happy about "scope" not being null 5 lines above.
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ if (isDebugged) {
+ frame.debuggerFrame.onEnter(cx, scope, frame.thisObj, args);
+ }
+ // Enter activation only when itsNeedsActivation true,
+ // since debugger should not interfere with activation
+ // chaining
+ if (usesActivation) {
+ ScriptRuntime.enterActivationFunction(cx, scope);
+ }
+ }
+ }
+
+ private static void exitFrame(Context cx, CallFrame frame,
+ Object throwable)
+ {
+ if (frame.idata.itsNeedsActivation) {
+ ScriptRuntime.exitActivationFunction(cx);
+ }
+
+ if (frame.debuggerFrame != null) {
+ try {
+ if (throwable instanceof Throwable) {
+ frame.debuggerFrame.onExit(cx, true, throwable);
+ } else {
+ Object result;
+ ContinuationJump cjump = (ContinuationJump)throwable;
+ if (cjump == null) {
+ result = frame.result;
+ } else {
+ result = cjump.result;
+ }
+ if (result == UniqueTag.DOUBLE_MARK) {
+ double resultDbl;
+ if (cjump == null) {
+ resultDbl = frame.resultDbl;
+ } else {
+ resultDbl = cjump.resultDbl;
+ }
+ result = ScriptRuntime.wrapNumber(resultDbl);
+ }
+ frame.debuggerFrame.onExit(cx, false, result);
+ }
+ } catch (Throwable ex) {
+ System.err.println(
+"RHINO USAGE WARNING: onExit terminated with exception");
+ ex.printStackTrace(System.err);
+ }
+ }
+ }
+
+ private static void setCallResult(CallFrame frame,
+ Object callResult,
+ double callResultDbl)
+ {
+ if (frame.savedCallOp == Token.CALL) {
+ frame.stack[frame.savedStackTop] = callResult;
+ frame.sDbl[frame.savedStackTop] = callResultDbl;
+ } else if (frame.savedCallOp == Token.NEW) {
+ // If construct returns scriptable,
+ // then it replaces on stack top saved original instance
+ // of the object.
+ if (callResult instanceof Scriptable) {
+ frame.stack[frame.savedStackTop] = callResult;
+ }
+ } else {
+ Kit.codeBug();
+ }
+ frame.savedCallOp = 0;
+ }
+
+ private static void captureContinuation(Context cx, CallFrame frame,
+ int stackTop)
+ {
+ Continuation c = new Continuation();
+ ScriptRuntime.setObjectProtoAndParent(
+ c, ScriptRuntime.getTopCallScope(cx));
+
+ // Make sure that all frames upstack frames are frozen
+ CallFrame x = frame.parentFrame;
+ while (x != null && !x.frozen) {
+ x.frozen = true;
+ // Allow to GC unused stack space
+ for (int i = x.savedStackTop + 1; i != x.stack.length; ++i) {
+ // Allow to GC unused stack space
+ x.stack[i] = null;
+ x.stackAttributes[i] = ScriptableObject.EMPTY;
+ }
+ if (x.savedCallOp == Token.CALL) {
+ // the call will always overwrite the stack top with the result
+ x.stack[x.savedStackTop] = null;
+ } else {
+ if (x.savedCallOp != Token.NEW) Kit.codeBug();
+ // the new operator uses stack top to store the constructed
+ // object so it shall not be cleared: see comments in
+ // setCallResult
+ }
+ x = x.parentFrame;
+ }
+
+ c.initImplementation(frame.parentFrame);
+ frame.stack[stackTop] = c;
+ }
+
+ private static int stack_int32(CallFrame frame, int i)
+ {
+ Object x = frame.stack[i];
+ double value;
+ if (x == UniqueTag.DOUBLE_MARK) {
+ value = frame.sDbl[i];
+ } else {
+ value = ScriptRuntime.toNumber(x);
+ }
+ return ScriptRuntime.toInt32(value);
+ }
+
+ private static double stack_double(CallFrame frame, int i)
+ {
+ Object x = frame.stack[i];
+ if (x != UniqueTag.DOUBLE_MARK) {
+ return ScriptRuntime.toNumber(x);
+ } else {
+ return frame.sDbl[i];
+ }
+ }
+
+ private static boolean stack_boolean(CallFrame frame, int i)
+ {
+ Object x = frame.stack[i];
+ if (x == Boolean.TRUE) {
+ return true;
+ } else if (x == Boolean.FALSE) {
+ return false;
+ } else if (x == UniqueTag.DOUBLE_MARK) {
+ double d = frame.sDbl[i];
+ return d == d && d != 0.0;
+ } else if (x == null || x == Undefined.instance) {
+ return false;
+ } else if (x instanceof Number) {
+ double d = ((Number)x).doubleValue();
+ return (d == d && d != 0.0);
+ } else if (x instanceof Boolean) {
+ return ((Boolean)x).booleanValue();
+ } else {
+ return ScriptRuntime.toBoolean(x);
+ }
+ }
+
+ private static void do_add(Object[] stack, double[] sDbl, int stackTop,
+ Context cx)
+ {
+ Object rhs = stack[stackTop + 1];
+ Object lhs = stack[stackTop];
+ double d;
+ boolean leftRightOrder;
+ if (rhs == UniqueTag.DOUBLE_MARK) {
+ d = sDbl[stackTop + 1];
+ if (lhs == UniqueTag.DOUBLE_MARK) {
+ sDbl[stackTop] += d;
+ return;
+ }
+ leftRightOrder = true;
+ // fallthrough to object + number code
+ } else if (lhs == UniqueTag.DOUBLE_MARK) {
+ d = sDbl[stackTop];
+ lhs = rhs;
+ leftRightOrder = false;
+ // fallthrough to object + number code
+ } else {
+ if (lhs instanceof Scriptable || rhs instanceof Scriptable) {
+ stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
+ } else if (lhs instanceof String) {
+ String lstr = (String)lhs;
+ String rstr = ScriptRuntime.toString(rhs);
+ stack[stackTop] = lstr.concat(rstr);
+ } else if (rhs instanceof String) {
+ String lstr = ScriptRuntime.toString(lhs);
+ String rstr = (String)rhs;
+ stack[stackTop] = lstr.concat(rstr);
+ } else {
+ double lDbl = (lhs instanceof Number)
+ ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
+ double rDbl = (rhs instanceof Number)
+ ? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs);
+ stack[stackTop] = UniqueTag.DOUBLE_MARK;
+ sDbl[stackTop] = lDbl + rDbl;
+ }
+ return;
+ }
+
+ // handle object(lhs) + number(d) code
+ if (lhs instanceof Scriptable) {
+ rhs = ScriptRuntime.wrapNumber(d);
+ if (!leftRightOrder) {
+ Object tmp = lhs;
+ lhs = rhs;
+ rhs = tmp;
+ }
+ stack[stackTop] = ScriptRuntime.add(lhs, rhs, cx);
+ } else if (lhs instanceof String) {
+ String lstr = (String)lhs;
+ String rstr = ScriptRuntime.toString(d);
+ if (leftRightOrder) {
+ stack[stackTop] = lstr.concat(rstr);
+ } else {
+ stack[stackTop] = rstr.concat(lstr);
+ }
+ } else {
+ double lDbl = (lhs instanceof Number)
+ ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
+ stack[stackTop] = UniqueTag.DOUBLE_MARK;
+ sDbl[stackTop] = lDbl + d;
+ }
+ }
+
+ private static Object[] getArgsArray(Object[] stack, double[] sDbl,
+ int shift, int count)
+ {
+ if (count == 0) {
+ return ScriptRuntime.emptyArgs;
+ }
+ Object[] args = new Object[count];
+ for (int i = 0; i != count; ++i, ++shift) {
+ Object val = stack[shift];
+ if (val == UniqueTag.DOUBLE_MARK) {
+ val = ScriptRuntime.wrapNumber(sDbl[shift]);
+ }
+ args[i] = val;
+ }
+ return args;
+ }
+
+ private static void addInstructionCount(Context cx, CallFrame frame,
+ int extra)
+ {
+ cx.instructionCount += frame.pc - frame.pcPrevBranch + extra;
+ if (cx.instructionCount > cx.instructionThreshold) {
+ cx.observeInstructionCount(cx.instructionCount);
+ cx.instructionCount = 0;
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java
new file mode 100644
index 0000000..7435b10
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/InterpreterData.java
@@ -0,0 +1,192 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Bob Jervis
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+import org.mozilla.javascript.debug.DebuggableScript;
+
+final class InterpreterData implements Serializable, DebuggableScript
+{
+ static final long serialVersionUID = 5067677351589230234L;
+
+ static final int INITIAL_MAX_ICODE_LENGTH = 1024;
+ static final int INITIAL_STRINGTABLE_SIZE = 64;
+ static final int INITIAL_NUMBERTABLE_SIZE = 64;
+
+ InterpreterData(int languageVersion,
+ String sourceFile, String encodedSource)
+ {
+ this.languageVersion = languageVersion;
+ this.itsSourceFile = sourceFile;
+ this.encodedSource = encodedSource;
+
+ init();
+ }
+
+ InterpreterData(InterpreterData parent)
+ {
+ this.parentData = parent;
+ this.languageVersion = parent.languageVersion;
+ this.itsSourceFile = parent.itsSourceFile;
+ this.encodedSource = parent.encodedSource;
+
+ init();
+ }
+
+ private void init()
+ {
+ itsICode = new byte[INITIAL_MAX_ICODE_LENGTH];
+ itsStringTable = new String[INITIAL_STRINGTABLE_SIZE];
+ }
+
+ String itsName;
+ String itsSourceFile;
+ boolean itsNeedsActivation;
+ int itsFunctionType;
+
+ String[] itsStringTable;
+ double[] itsDoubleTable;
+ InterpreterData[] itsNestedFunctions;
+ Object[] itsRegExpLiterals;
+
+ byte[] itsICode;
+
+ int[] itsExceptionTable;
+
+ int itsMaxVars;
+ int itsMaxLocals;
+ int itsMaxStack;
+ int itsMaxFrameArray;
+
+ // see comments in NativeFuncion for definition of argNames and argCount
+ String[] argNames;
+ boolean[] argIsConst;
+ int argCount;
+
+ int itsMaxCalleeArgs;
+
+ String encodedSource;
+ int encodedSourceStart;
+ int encodedSourceEnd;
+
+ int languageVersion;
+
+ boolean useDynamicScope;
+
+ boolean topLevel;
+
+ Object[] literalIds;
+
+ UintMap longJumps;
+
+ int firstLinePC = -1; // PC for the first LINE icode
+
+ InterpreterData parentData;
+
+ boolean evalScriptFlag; // true if script corresponds to eval() code
+
+ public boolean isTopLevel()
+ {
+ return topLevel;
+ }
+
+ public boolean isFunction()
+ {
+ return itsFunctionType != 0;
+ }
+
+ public String getFunctionName()
+ {
+ return itsName;
+ }
+
+ public int getParamCount()
+ {
+ return argCount;
+ }
+
+ public int getParamAndVarCount()
+ {
+ return argNames.length;
+ }
+
+ public String getParamOrVarName(int index)
+ {
+ return argNames[index];
+ }
+
+ public boolean getParamOrVarConst(int index)
+ {
+ return argIsConst[index];
+ }
+
+ public String getSourceName()
+ {
+ return itsSourceFile;
+ }
+
+ public boolean isGeneratedScript()
+ {
+ return ScriptRuntime.isGeneratedScript(itsSourceFile);
+ }
+
+ public int[] getLineNumbers()
+ {
+ return Interpreter.getLineNumbers(this);
+ }
+
+ public int getFunctionCount()
+ {
+ return (itsNestedFunctions == null) ? 0 : itsNestedFunctions.length;
+ }
+
+ public DebuggableScript getFunction(int index)
+ {
+ return itsNestedFunctions[index];
+ }
+
+ public DebuggableScript getParent()
+ {
+ return parentData;
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java
new file mode 100644
index 0000000..6e0a827
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaAdapter.java
@@ -0,0 +1,1129 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ * Norris Boyd
+ * Igor Bukanov
+ * Mike McCabe
+ * Matthias Radestock
+ * Andi Vajda
+ * Andrew Wason
+ * Kemal Bayram
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import org.mozilla.classfile.*;
+import java.lang.reflect.*;
+import java.io.*;
+import java.security.*;
+import java.util.*;
+
+public final class JavaAdapter implements IdFunctionCall
+{
+ /**
+ * Provides a key with which to distinguish previously generated
+ * adapter classes stored in a hash table.
+ */
+ static class JavaAdapterSignature
+ {
+ Class superClass;
+ Class[] interfaces;
+ ObjToIntMap names;
+
+ JavaAdapterSignature(Class superClass, Class[] interfaces,
+ ObjToIntMap names)
+ {
+ this.superClass = superClass;
+ this.interfaces = interfaces;
+ this.names = names;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof JavaAdapterSignature))
+ return false;
+ JavaAdapterSignature sig = (JavaAdapterSignature) obj;
+ if (superClass != sig.superClass)
+ return false;
+ if (interfaces != sig.interfaces) {
+ if (interfaces.length != sig.interfaces.length)
+ return false;
+ for (int i=0; i < interfaces.length; i++)
+ if (interfaces[i] != sig.interfaces[i])
+ return false;
+ }
+ if (names.size() != sig.names.size())
+ return false;
+ ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(names);
+ for (iter.start(); !iter.done(); iter.next()) {
+ String name = (String)iter.getKey();
+ int arity = iter.getValue();
+ if (arity != names.get(name, arity + 1))
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return superClass.hashCode()
+ | (0x9e3779b9 * (names.size() | (interfaces.length << 16)));
+ }
+ }
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+ JavaAdapter obj = new JavaAdapter();
+ IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_JavaAdapter,
+ "JavaAdapter", 1, scope);
+ ctor.markAsConstructor(null);
+ if (sealed) {
+ ctor.sealObject();
+ }
+ ctor.exportAsScopeProperty();
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (f.hasTag(FTAG)) {
+ if (f.methodId() == Id_JavaAdapter) {
+ return js_createAdapter(cx, scope, args);
+ }
+ }
+ throw f.unknown();
+ }
+
+ public static Object convertResult(Object result, Class c)
+ {
+ if (result == Undefined.instance &&
+ (c != ScriptRuntime.ObjectClass &&
+ c != ScriptRuntime.StringClass))
+ {
+ // Avoid an error for an undefined value; return null instead.
+ return null;
+ }
+ return Context.jsToJava(result, c);
+ }
+
+ public static Scriptable createAdapterWrapper(Scriptable obj,
+ Object adapter)
+ {
+ Scriptable scope = ScriptableObject.getTopLevelScope(obj);
+ NativeJavaObject res = new NativeJavaObject(scope, adapter, null, true);
+ res.setPrototype(obj);
+ return res;
+ }
+
+ public static Object getAdapterSelf(Class adapterClass, Object adapter)
+ throws NoSuchFieldException, IllegalAccessException
+ {
+ Field self = adapterClass.getDeclaredField("self");
+ return self.get(adapter);
+ }
+
+ static Object js_createAdapter(Context cx, Scriptable scope, Object[] args)
+ {
+ int N = args.length;
+ if (N == 0) {
+ throw ScriptRuntime.typeError0("msg.adapter.zero.args");
+ }
+
+ Class superClass = null;
+ Class[] intfs = new Class[N - 1];
+ int interfaceCount = 0;
+ for (int i = 0; i != N - 1; ++i) {
+ Object arg = args[i];
+ if (!(arg instanceof NativeJavaClass)) {
+ throw ScriptRuntime.typeError2("msg.not.java.class.arg",
+ String.valueOf(i),
+ ScriptRuntime.toString(arg));
+ }
+ Class c = ((NativeJavaClass) arg).getClassObject();
+ if (!c.isInterface()) {
+ if (superClass != null) {
+ throw ScriptRuntime.typeError2("msg.only.one.super",
+ superClass.getName(), c.getName());
+ }
+ superClass = c;
+ } else {
+ intfs[interfaceCount++] = c;
+ }
+ }
+
+ if (superClass == null)
+ superClass = ScriptRuntime.ObjectClass;
+
+ Class[] interfaces = new Class[interfaceCount];
+ System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);
+ Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]);
+
+ Class adapterClass = getAdapterClass(scope, superClass, interfaces,
+ obj);
+
+ Class[] ctorParms = {
+ ScriptRuntime.ContextFactoryClass,
+ ScriptRuntime.ScriptableClass
+ };
+ Object[] ctorArgs = { cx.getFactory(), obj };
+ try {
+ Object adapter = adapterClass.getConstructor(ctorParms).
+ newInstance(ctorArgs);
+ return getAdapterSelf(adapterClass, adapter);
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+
+ // Needed by NativeJavaObject serializer
+ public static void writeAdapterObject(Object javaObject,
+ ObjectOutputStream out)
+ throws IOException
+ {
+ Class cl = javaObject.getClass();
+ out.writeObject(cl.getSuperclass().getName());
+
+ Class[] interfaces = cl.getInterfaces();
+ String[] interfaceNames = new String[interfaces.length];
+
+ for (int i=0; i < interfaces.length; i++)
+ interfaceNames[i] = interfaces[i].getName();
+
+ out.writeObject(interfaceNames);
+
+ try {
+ Object delegee = cl.getField("delegee").get(javaObject);
+ out.writeObject(delegee);
+ return;
+ } catch (IllegalAccessException e) {
+ } catch (NoSuchFieldException e) {
+ }
+ throw new IOException();
+ }
+
+ // Needed by NativeJavaObject de-serializer
+ public static Object readAdapterObject(Scriptable self,
+ ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ ContextFactory factory;
+ Context cx = Context.getCurrentContext();
+ if (cx != null) {
+ factory = cx.getFactory();
+ } else {
+ factory = null;
+ }
+
+ Class superClass = Class.forName((String)in.readObject());
+
+ String[] interfaceNames = (String[])in.readObject();
+ Class[] interfaces = new Class[interfaceNames.length];
+
+ for (int i=0; i < interfaceNames.length; i++)
+ interfaces[i] = Class.forName(interfaceNames[i]);
+
+ Scriptable delegee = (Scriptable)in.readObject();
+
+ Class adapterClass = getAdapterClass(self, superClass, interfaces,
+ delegee);
+
+ Class[] ctorParms = {
+ ScriptRuntime.ContextFactoryClass,
+ ScriptRuntime.ScriptableClass,
+ ScriptRuntime.ScriptableClass
+ };
+ Object[] ctorArgs = { factory, delegee, self };
+ try {
+ return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
+ } catch(InstantiationException e) {
+ } catch(IllegalAccessException e) {
+ } catch(InvocationTargetException e) {
+ } catch(NoSuchMethodException e) {
+ }
+
+ throw new ClassNotFoundException("adapter");
+ }
+
+ private static ObjToIntMap getObjectFunctionNames(Scriptable obj)
+ {
+ Object[] ids = ScriptableObject.getPropertyIds(obj);
+ ObjToIntMap map = new ObjToIntMap(ids.length);
+ for (int i = 0; i != ids.length; ++i) {
+ if (!(ids[i] instanceof String))
+ continue;
+ String id = (String) ids[i];
+ Object value = ScriptableObject.getProperty(obj, id);
+ if (value instanceof Function) {
+ Function f = (Function)value;
+ int length = ScriptRuntime.toInt32(
+ ScriptableObject.getProperty(f, "length"));
+ if (length < 0) {
+ length = 0;
+ }
+ map.put(id, length);
+ }
+ }
+ return map;
+ }
+
+ private static Class getAdapterClass(Scriptable scope, Class superClass,
+ Class[] interfaces, Scriptable obj)
+ {
+ ClassCache cache = ClassCache.get(scope);
+ Map<JavaAdapterSignature,Class<?>> generated
+ = cache.getInterfaceAdapterCacheMap();
+
+ ObjToIntMap names = getObjectFunctionNames(obj);
+ JavaAdapterSignature sig;
+ sig = new JavaAdapterSignature(superClass, interfaces, names);
+ Class<?> adapterClass = generated.get(sig);
+ if (adapterClass == null) {
+ String adapterName = "adapter"
+ + cache.newClassSerialNumber();
+ byte[] code = createAdapterCode(names, adapterName,
+ superClass, interfaces, null);
+
+ adapterClass = loadAdapterClass(adapterName, code);
+ if (cache.isCachingEnabled()) {
+ generated.put(sig, adapterClass);
+ }
+ }
+ return adapterClass;
+ }
+
+ public static byte[] createAdapterCode(ObjToIntMap functionNames,
+ String adapterName,
+ Class superClass,
+ Class[] interfaces,
+ String scriptClassName)
+ {
+ ClassFileWriter cfw = new ClassFileWriter(adapterName,
+ superClass.getName(),
+ "<adapter>");
+ cfw.addField("factory", "Lorg/mozilla/javascript/ContextFactory;",
+ (short) (ClassFileWriter.ACC_PUBLIC |
+ ClassFileWriter.ACC_FINAL));
+ cfw.addField("delegee", "Lorg/mozilla/javascript/Scriptable;",
+ (short) (ClassFileWriter.ACC_PUBLIC |
+ ClassFileWriter.ACC_FINAL));
+ cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;",
+ (short) (ClassFileWriter.ACC_PUBLIC |
+ ClassFileWriter.ACC_FINAL));
+ int interfacesCount = interfaces == null ? 0 : interfaces.length;
+ for (int i=0; i < interfacesCount; i++) {
+ if (interfaces[i] != null)
+ cfw.addInterface(interfaces[i].getName());
+ }
+
+ String superName = superClass.getName().replace('.', '/');
+ generateCtor(cfw, adapterName, superName);
+ generateSerialCtor(cfw, adapterName, superName);
+ if (scriptClassName != null)
+ generateEmptyCtor(cfw, adapterName, superName, scriptClassName);
+
+ ObjToIntMap generatedOverrides = new ObjToIntMap();
+ ObjToIntMap generatedMethods = new ObjToIntMap();
+
+ // generate methods to satisfy all specified interfaces.
+ for (int i = 0; i < interfacesCount; i++) {
+ Method[] methods = interfaces[i].getMethods();
+ for (int j = 0; j < methods.length; j++) {
+ Method method = methods[j];
+ int mods = method.getModifiers();
+ if (Modifier.isStatic(mods) || Modifier.isFinal(mods)) {
+ continue;
+ }
+ String methodName = method.getName();
+ Class[] argTypes = method.getParameterTypes();
+ if (!functionNames.has(methodName)) {
+ try {
+ superClass.getMethod(methodName, argTypes);
+ // The class we're extending implements this method and
+ // the JavaScript object doesn't have an override. See
+ // bug 61226.
+ continue;
+ } catch (NoSuchMethodException e) {
+ // Not implemented by superclass; fall through
+ }
+ }
+ // make sure to generate only one instance of a particular
+ // method/signature.
+ String methodSignature = getMethodSignature(method, argTypes);
+ String methodKey = methodName + methodSignature;
+ if (! generatedOverrides.has(methodKey)) {
+ generateMethod(cfw, adapterName, methodName,
+ argTypes, method.getReturnType());
+ generatedOverrides.put(methodKey, 0);
+ generatedMethods.put(methodName, 0);
+ }
+ }
+ }
+
+ // Now, go through the superclass's methods, checking for abstract
+ // methods or additional methods to override.
+
+ // generate any additional overrides that the object might contain.
+ Method[] methods = getOverridableMethods(superClass);
+ for (int j = 0; j < methods.length; j++) {
+ Method method = methods[j];
+ int mods = method.getModifiers();
+ // if a method is marked abstract, must implement it or the
+ // resulting class won't be instantiable. otherwise, if the object
+ // has a property of the same name, then an override is intended.
+ boolean isAbstractMethod = Modifier.isAbstract(mods);
+ String methodName = method.getName();
+ if (isAbstractMethod || functionNames.has(methodName)) {
+ // make sure to generate only one instance of a particular
+ // method/signature.
+ Class[] argTypes = method.getParameterTypes();
+ String methodSignature = getMethodSignature(method, argTypes);
+ String methodKey = methodName + methodSignature;
+ if (! generatedOverrides.has(methodKey)) {
+ generateMethod(cfw, adapterName, methodName,
+ argTypes, method.getReturnType());
+ generatedOverrides.put(methodKey, 0);
+ generatedMethods.put(methodName, 0);
+
+ // if a method was overridden, generate a "super$method"
+ // which lets the delegate call the superclass' version.
+ if (!isAbstractMethod) {
+ generateSuper(cfw, adapterName, superName,
+ methodName, methodSignature,
+ argTypes, method.getReturnType());
+ }
+ }
+ }
+ }
+
+ // Generate Java methods for remaining properties that are not
+ // overrides.
+ ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(functionNames);
+ for (iter.start(); !iter.done(); iter.next()) {
+ String functionName = (String)iter.getKey();
+ if (generatedMethods.has(functionName))
+ continue;
+ int length = iter.getValue();
+ Class[] parms = new Class[length];
+ for (int k=0; k < length; k++)
+ parms[k] = ScriptRuntime.ObjectClass;
+ generateMethod(cfw, adapterName, functionName, parms,
+ ScriptRuntime.ObjectClass);
+ }
+ return cfw.toByteArray();
+ }
+
+ static Method[] getOverridableMethods(Class c)
+ {
+ ArrayList<Method> list = new ArrayList<Method>();
+ HashSet<String> skip = new HashSet<String>();
+ while (c != null) {
+ Method[] methods = c.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ String methodKey = methods[i].getName() +
+ getMethodSignature(methods[i],
+ methods[i].getParameterTypes());
+ if (skip.contains(methodKey))
+ continue; // skip this method
+ int mods = methods[i].getModifiers();
+ if (Modifier.isStatic(mods))
+ continue;
+ if (Modifier.isFinal(mods)) {
+ // Make sure we don't add a final method to the list
+ // of overridable methods.
+ skip.add(methodKey);
+ continue;
+ }
+ if (Modifier.isPublic(mods) || Modifier.isProtected(mods)) {
+ list.add(methods[i]);
+ skip.add(methodKey);
+ }
+ }
+ c = c.getSuperclass();
+ }
+ return list.toArray(new Method[list.size()]);
+ }
+
+ static Class loadAdapterClass(String className, byte[] classBytes)
+ {
+ Object staticDomain;
+ Class domainClass = SecurityController.getStaticSecurityDomainClass();
+ if(domainClass == CodeSource.class || domainClass == ProtectionDomain.class) {
+ ProtectionDomain protectionDomain = JavaAdapter.class.getProtectionDomain();
+ if(domainClass == CodeSource.class) {
+ staticDomain = protectionDomain == null ? null : protectionDomain.getCodeSource();
+ }
+ else {
+ staticDomain = protectionDomain;
+ }
+ }
+ else {
+ staticDomain = null;
+ }
+ GeneratedClassLoader loader = SecurityController.createLoader(null,
+ staticDomain);
+ Class result = loader.defineClass(className, classBytes);
+ loader.linkClass(result);
+ return result;
+ }
+
+ public static Function getFunction(Scriptable obj, String functionName)
+ {
+ Object x = ScriptableObject.getProperty(obj, functionName);
+ if (x == Scriptable.NOT_FOUND) {
+ // This method used to swallow the exception from calling
+ // an undefined method. People have come to depend on this
+ // somewhat dubious behavior. It allows people to avoid
+ // implementing listener methods that they don't care about,
+ // for instance.
+ return null;
+ }
+ if (!(x instanceof Function))
+ throw ScriptRuntime.notFunctionError(x, functionName);
+
+ return (Function)x;
+ }
+
+ /**
+ * Utility method which dynamically binds a Context to the current thread,
+ * if none already exists.
+ */
+ public static Object callMethod(ContextFactory factory,
+ final Scriptable thisObj,
+ final Function f, final Object[] args,
+ final long argsToWrap)
+ {
+ if (f == null) {
+ // See comments in getFunction
+ return Undefined.instance;
+ }
+ if (factory == null) {
+ factory = ContextFactory.getGlobal();
+ }
+
+ final Scriptable scope = f.getParentScope();
+ if (argsToWrap == 0) {
+ return Context.call(factory, f, scope, thisObj, args);
+ }
+
+ Context cx = Context.getCurrentContext();
+ if (cx != null) {
+ return doCall(cx, scope, thisObj, f, args, argsToWrap);
+ } else {
+ return factory.call(new ContextAction() {
+ public Object run(Context cx)
+ {
+ return doCall(cx, scope, thisObj, f, args, argsToWrap);
+ }
+ });
+ }
+ }
+
+ private static Object doCall(Context cx, Scriptable scope,
+ Scriptable thisObj, Function f,
+ Object[] args, long argsToWrap)
+ {
+ // Wrap the rest of objects
+ for (int i = 0; i != args.length; ++i) {
+ if (0 != (argsToWrap & (1 << i))) {
+ Object arg = args[i];
+ if (!(arg instanceof Scriptable)) {
+ args[i] = cx.getWrapFactory().wrap(cx, scope, arg,
+ null);
+ }
+ }
+ }
+ return f.call(cx, scope, thisObj, args);
+ }
+
+ public static Scriptable runScript(final Script script)
+ {
+ return (Scriptable)Context.call(new ContextAction() {
+ public Object run(Context cx)
+ {
+ ScriptableObject global = ScriptRuntime.getGlobal(cx);
+ script.exec(cx, global);
+ return global;
+ }
+ });
+ }
+
+ private static void generateCtor(ClassFileWriter cfw, String adapterName,
+ String superName)
+ {
+ cfw.startMethod("<init>",
+ "(Lorg/mozilla/javascript/ContextFactory;"
+ +"Lorg/mozilla/javascript/Scriptable;)V",
+ ClassFileWriter.ACC_PUBLIC);
+
+ // Invoke base class constructor
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
+
+ // Save parameter in instance variable "factory"
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance
+ cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
+ "Lorg/mozilla/javascript/ContextFactory;");
+
+ // Save parameter in instance variable "delegee"
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee
+ cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self
+ // create a wrapper object to be used as "this" in method calls
+ cfw.add(ByteCode.ALOAD_2); // the Scriptable delegee
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "createAdapterWrapper",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.add(ByteCode.PUTFIELD, adapterName, "self",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)3); // 3: this + factory + delegee
+ }
+
+ private static void generateSerialCtor(ClassFileWriter cfw,
+ String adapterName,
+ String superName)
+ {
+ cfw.startMethod("<init>",
+ "(Lorg/mozilla/javascript/ContextFactory;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")V",
+ ClassFileWriter.ACC_PUBLIC);
+
+ // Invoke base class constructor
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
+
+ // Save parameter in instance variable "factory"
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_1); // first arg: ContextFactory instance
+ cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
+ "Lorg/mozilla/javascript/ContextFactory;");
+
+ // Save parameter in instance variable "delegee"
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_2); // second arg: Scriptable delegee
+ cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
+ "Lorg/mozilla/javascript/Scriptable;");
+ // save self
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_3); // second arg: Scriptable self
+ cfw.add(ByteCode.PUTFIELD, adapterName, "self",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)4); // 4: this + factory + delegee + self
+ }
+
+ private static void generateEmptyCtor(ClassFileWriter cfw,
+ String adapterName,
+ String superName,
+ String scriptClassName)
+ {
+ cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
+
+ // Invoke base class constructor
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, superName, "<init>", "()V");
+
+ // Set factory to null to use current global when necessary
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.ACONST_NULL);
+ cfw.add(ByteCode.PUTFIELD, adapterName, "factory",
+ "Lorg/mozilla/javascript/ContextFactory;");
+
+ // Load script class
+ cfw.add(ByteCode.NEW, scriptClassName);
+ cfw.add(ByteCode.DUP);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, scriptClassName, "<init>", "()V");
+
+ // Run script and save resulting scope
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "runScript",
+ "(Lorg/mozilla/javascript/Script;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.add(ByteCode.ASTORE_1);
+
+ // Save the Scriptable in instance variable "delegee"
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.add(ByteCode.ALOAD_1); // the Scriptable
+ cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.ALOAD_0); // this for the following PUTFIELD for self
+ // create a wrapper object to be used as "this" in method calls
+ cfw.add(ByteCode.ALOAD_1); // the Scriptable
+ cfw.add(ByteCode.ALOAD_0); // this
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "createAdapterWrapper",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.add(ByteCode.PUTFIELD, adapterName, "self",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)2); // this + delegee
+ }
+
+ /**
+ * Generates code to wrap Java arguments into Object[].
+ * Non-primitive Java types are left as-is pending conversion
+ * in the helper method. Leaves the array object on the top of the stack.
+ */
+ static void generatePushWrappedArgs(ClassFileWriter cfw,
+ Class[] argTypes,
+ int arrayLength)
+ {
+ // push arguments
+ cfw.addPush(arrayLength);
+ cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
+ int paramOffset = 1;
+ for (int i = 0; i != argTypes.length; ++i) {
+ cfw.add(ByteCode.DUP); // duplicate array reference
+ cfw.addPush(i);
+ paramOffset += generateWrapArg(cfw, paramOffset, argTypes[i]);
+ cfw.add(ByteCode.AASTORE);
+ }
+ }
+
+ /**
+ * Generates code to wrap Java argument into Object.
+ * Non-primitive Java types are left unconverted pending conversion
+ * in the helper method. Leaves the wrapper object on the top of the stack.
+ */
+ private static int generateWrapArg(ClassFileWriter cfw, int paramOffset,
+ Class argType)
+ {
+ int size = 1;
+ if (!argType.isPrimitive()) {
+ cfw.add(ByteCode.ALOAD, paramOffset);
+
+ } else if (argType == Boolean.TYPE) {
+ // wrap boolean values with java.lang.Boolean.
+ cfw.add(ByteCode.NEW, "java/lang/Boolean");
+ cfw.add(ByteCode.DUP);
+ cfw.add(ByteCode.ILOAD, paramOffset);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Boolean",
+ "<init>", "(Z)V");
+
+ } else if (argType == Character.TYPE) {
+ // Create a string of length 1 using the character parameter.
+ cfw.add(ByteCode.ILOAD, paramOffset);
+ cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/String",
+ "valueOf", "(C)Ljava/lang/String;");
+
+ } else {
+ // convert all numeric values to java.lang.Double.
+ cfw.add(ByteCode.NEW, "java/lang/Double");
+ cfw.add(ByteCode.DUP);
+ String typeName = argType.getName();
+ switch (typeName.charAt(0)) {
+ case 'b':
+ case 's':
+ case 'i':
+ // load an int value, convert to double.
+ cfw.add(ByteCode.ILOAD, paramOffset);
+ cfw.add(ByteCode.I2D);
+ break;
+ case 'l':
+ // load a long, convert to double.
+ cfw.add(ByteCode.LLOAD, paramOffset);
+ cfw.add(ByteCode.L2D);
+ size = 2;
+ break;
+ case 'f':
+ // load a float, convert to double.
+ cfw.add(ByteCode.FLOAD, paramOffset);
+ cfw.add(ByteCode.F2D);
+ break;
+ case 'd':
+ cfw.add(ByteCode.DLOAD, paramOffset);
+ size = 2;
+ break;
+ }
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Double",
+ "<init>", "(D)V");
+ }
+ return size;
+ }
+
+ /**
+ * Generates code to convert a wrapped value type to a primitive type.
+ * Handles unwrapping java.lang.Boolean, and java.lang.Number types.
+ * Generates the appropriate RETURN bytecode.
+ */
+ static void generateReturnResult(ClassFileWriter cfw, Class retType,
+ boolean callConvertResult)
+ {
+ // wrap boolean values with java.lang.Boolean, convert all other
+ // primitive values to java.lang.Double.
+ if (retType == Void.TYPE) {
+ cfw.add(ByteCode.POP);
+ cfw.add(ByteCode.RETURN);
+
+ } else if (retType == Boolean.TYPE) {
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/Context",
+ "toBoolean", "(Ljava/lang/Object;)Z");
+ cfw.add(ByteCode.IRETURN);
+
+ } else if (retType == Character.TYPE) {
+ // characters are represented as strings in JavaScript.
+ // return the first character.
+ // first convert the value to a string if possible.
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/Context",
+ "toString",
+ "(Ljava/lang/Object;)Ljava/lang/String;");
+ cfw.add(ByteCode.ICONST_0);
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "java/lang/String",
+ "charAt", "(I)C");
+ cfw.add(ByteCode.IRETURN);
+
+ } else if (retType.isPrimitive()) {
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/Context",
+ "toNumber", "(Ljava/lang/Object;)D");
+ String typeName = retType.getName();
+ switch (typeName.charAt(0)) {
+ case 'b':
+ case 's':
+ case 'i':
+ cfw.add(ByteCode.D2I);
+ cfw.add(ByteCode.IRETURN);
+ break;
+ case 'l':
+ cfw.add(ByteCode.D2L);
+ cfw.add(ByteCode.LRETURN);
+ break;
+ case 'f':
+ cfw.add(ByteCode.D2F);
+ cfw.add(ByteCode.FRETURN);
+ break;
+ case 'd':
+ cfw.add(ByteCode.DRETURN);
+ break;
+ default:
+ throw new RuntimeException("Unexpected return type " +
+ retType.toString());
+ }
+
+ } else {
+ String retTypeStr = retType.getName();
+ if (callConvertResult) {
+ cfw.addLoadConstant(retTypeStr);
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "java/lang/Class",
+ "forName",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "convertResult",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Class;"
+ +")Ljava/lang/Object;");
+ }
+ // Now cast to return type
+ cfw.add(ByteCode.CHECKCAST, retTypeStr);
+ cfw.add(ByteCode.ARETURN);
+ }
+ }
+
+ private static void generateMethod(ClassFileWriter cfw, String genName,
+ String methodName, Class[] parms,
+ Class returnType)
+ {
+ StringBuffer sb = new StringBuffer();
+ int paramsEnd = appendMethodSignature(parms, returnType, sb);
+ String methodSignature = sb.toString();
+ cfw.startMethod(methodName, methodSignature,
+ ClassFileWriter.ACC_PUBLIC);
+
+ // Prepare stack to call method
+
+ // push factory
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD, genName, "factory",
+ "Lorg/mozilla/javascript/ContextFactory;");
+
+ // push self
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD, genName, "self",
+ "Lorg/mozilla/javascript/Scriptable;");
+
+ // push function
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD, genName, "delegee",
+ "Lorg/mozilla/javascript/Scriptable;");
+ cfw.addPush(methodName);
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "getFunction",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +")Lorg/mozilla/javascript/Function;");
+
+ // push arguments
+ generatePushWrappedArgs(cfw, parms, parms.length);
+
+ // push bits to indicate which parameters should be wrapped
+ if (parms.length > 64) {
+ // If it will be an issue, then passing a static boolean array
+ // can be an option, but for now using simple bitmask
+ throw Context.reportRuntimeError0(
+ "JavaAdapter can not subclass methods with more then"
+ +" 64 arguments.");
+ }
+ long convertionMask = 0;
+ for (int i = 0; i != parms.length; ++i) {
+ if (!parms[i].isPrimitive()) {
+ convertionMask |= (1 << i);
+ }
+ }
+ cfw.addPush(convertionMask);
+
+ // go through utility method, which creates a Context to run the
+ // method in.
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/JavaAdapter",
+ "callMethod",
+ "(Lorg/mozilla/javascript/ContextFactory;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Function;"
+ +"[Ljava/lang/Object;"
+ +"J"
+ +")Ljava/lang/Object;");
+
+ generateReturnResult(cfw, returnType, true);
+
+ cfw.stopMethod((short)paramsEnd);
+ }
+
+ /**
+ * Generates code to push typed parameters onto the operand stack
+ * prior to a direct Java method call.
+ */
+ private static int generatePushParam(ClassFileWriter cfw, int paramOffset,
+ Class paramType)
+ {
+ if (!paramType.isPrimitive()) {
+ cfw.addALoad(paramOffset);
+ return 1;
+ }
+ String typeName = paramType.getName();
+ switch (typeName.charAt(0)) {
+ case 'z':
+ case 'b':
+ case 'c':
+ case 's':
+ case 'i':
+ // load an int value, convert to double.
+ cfw.addILoad(paramOffset);
+ return 1;
+ case 'l':
+ // load a long, convert to double.
+ cfw.addLLoad(paramOffset);
+ return 2;
+ case 'f':
+ // load a float, convert to double.
+ cfw.addFLoad(paramOffset);
+ return 1;
+ case 'd':
+ cfw.addDLoad(paramOffset);
+ return 2;
+ }
+ throw Kit.codeBug();
+ }
+
+ /**
+ * Generates code to return a Java type, after calling a Java method
+ * that returns the same type.
+ * Generates the appropriate RETURN bytecode.
+ */
+ private static void generatePopResult(ClassFileWriter cfw,
+ Class retType)
+ {
+ if (retType.isPrimitive()) {
+ String typeName = retType.getName();
+ switch (typeName.charAt(0)) {
+ case 'b':
+ case 'c':
+ case 's':
+ case 'i':
+ case 'z':
+ cfw.add(ByteCode.IRETURN);
+ break;
+ case 'l':
+ cfw.add(ByteCode.LRETURN);
+ break;
+ case 'f':
+ cfw.add(ByteCode.FRETURN);
+ break;
+ case 'd':
+ cfw.add(ByteCode.DRETURN);
+ break;
+ }
+ } else {
+ cfw.add(ByteCode.ARETURN);
+ }
+ }
+
+ /**
+ * Generates a method called "super$methodName()" which can be called
+ * from JavaScript that is equivalent to calling "super.methodName()"
+ * from Java. Eventually, this may be supported directly in JavaScript.
+ */
+ private static void generateSuper(ClassFileWriter cfw,
+ String genName, String superName,
+ String methodName, String methodSignature,
+ Class[] parms, Class returnType)
+ {
+ cfw.startMethod("super$" + methodName, methodSignature,
+ ClassFileWriter.ACC_PUBLIC);
+
+ // push "this"
+ cfw.add(ByteCode.ALOAD, 0);
+
+ // push the rest of the parameters.
+ int paramOffset = 1;
+ for (int i = 0; i < parms.length; i++) {
+ paramOffset += generatePushParam(cfw, paramOffset, parms[i]);
+ }
+
+ // call the superclass implementation of the method.
+ cfw.addInvoke(ByteCode.INVOKESPECIAL,
+ superName,
+ methodName,
+ methodSignature);
+
+ // now, handle the return type appropriately.
+ Class retType = returnType;
+ if (!retType.equals(Void.TYPE)) {
+ generatePopResult(cfw, retType);
+ } else {
+ cfw.add(ByteCode.RETURN);
+ }
+ cfw.stopMethod((short)(paramOffset + 1));
+ }
+
+ /**
+ * Returns a fully qualified method name concatenated with its signature.
+ */
+ private static String getMethodSignature(Method method, Class[] argTypes)
+ {
+ StringBuffer sb = new StringBuffer();
+ appendMethodSignature(argTypes, method.getReturnType(), sb);
+ return sb.toString();
+ }
+
+ static int appendMethodSignature(Class[] argTypes,
+ Class returnType,
+ StringBuffer sb)
+ {
+ sb.append('(');
+ int firstLocal = 1 + argTypes.length; // includes this.
+ for (int i = 0; i < argTypes.length; i++) {
+ Class type = argTypes[i];
+ appendTypeString(sb, type);
+ if (type == Long.TYPE || type == Double.TYPE) {
+ // adjust for duble slot
+ ++firstLocal;
+ }
+ }
+ sb.append(')');
+ appendTypeString(sb, returnType);
+ return firstLocal;
+ }
+
+ private static StringBuffer appendTypeString(StringBuffer sb, Class type)
+ {
+ while (type.isArray()) {
+ sb.append('[');
+ type = type.getComponentType();
+ }
+ if (type.isPrimitive()) {
+ char typeLetter;
+ if (type == Boolean.TYPE) {
+ typeLetter = 'Z';
+ } else if (type == Long.TYPE) {
+ typeLetter = 'J';
+ } else {
+ String typeName = type.getName();
+ typeLetter = Character.toUpperCase(typeName.charAt(0));
+ }
+ sb.append(typeLetter);
+ } else {
+ sb.append('L');
+ sb.append(type.getName().replace('.', '/'));
+ sb.append(';');
+ }
+ return sb;
+ }
+
+ static int[] getArgsToConvert(Class[] argTypes)
+ {
+ int count = 0;
+ for (int i = 0; i != argTypes.length; ++i) {
+ if (!argTypes[i].isPrimitive())
+ ++count;
+ }
+ if (count == 0)
+ return null;
+ int[] array = new int[count];
+ count = 0;
+ for (int i = 0; i != argTypes.length; ++i) {
+ if (!argTypes[i].isPrimitive())
+ array[count++] = i;
+ }
+ return array;
+ }
+
+ private static final Object FTAG = new Object();
+ private static final int Id_JavaAdapter = 1;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java
new file mode 100644
index 0000000..84ef2d4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaMembers.java
@@ -0,0 +1,935 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Cameron McCormack
+ * Frank Mitchell
+ * Mike Shaver
+ * Kurt Westerfeld
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ *
+ * @author Mike Shaver
+ * @author Norris Boyd
+ * @see NativeJavaObject
+ * @see NativeJavaClass
+ */
+class JavaMembers
+{
+ JavaMembers(Scriptable scope, Class cl)
+ {
+ this(scope, cl, false);
+ }
+
+ JavaMembers(Scriptable scope, Class cl, boolean includeProtected)
+ {
+ try {
+ Context cx = ContextFactory.getGlobal().enterContext();
+ ClassShutter shutter = cx.getClassShutter();
+ if (shutter != null && !shutter.visibleToScripts(cl.getName())) {
+ throw Context.reportRuntimeError1("msg.access.prohibited",
+ cl.getName());
+ }
+ this.includePrivate = cx.hasFeature(
+ Context.FEATURE_ENHANCED_JAVA_ACCESS);
+ this.members = new Hashtable(23);
+ this.staticMembers = new Hashtable(7);
+ this.cl = cl;
+ reflect(scope, includeProtected);
+ } finally {
+ Context.exit();
+ }
+ }
+
+ boolean has(String name, boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticMembers : members;
+ Object obj = ht.get(name);
+ if (obj != null) {
+ return true;
+ }
+ return findExplicitFunction(name, isStatic) != null;
+ }
+
+ Object get(Scriptable scope, String name, Object javaObject,
+ boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticMembers : members;
+ Object member = ht.get(name);
+ if (!isStatic && member == null) {
+ // Try to get static member from instance (LC3)
+ member = staticMembers.get(name);
+ }
+ if (member == null) {
+ member = this.getExplicitFunction(scope, name,
+ javaObject, isStatic);
+ if (member == null)
+ return Scriptable.NOT_FOUND;
+ }
+ if (member instanceof Scriptable) {
+ return member;
+ }
+ Context cx = Context.getContext();
+ Object rval;
+ Class type;
+ try {
+ if (member instanceof BeanProperty) {
+ BeanProperty bp = (BeanProperty) member;
+ if (bp.getter == null)
+ return Scriptable.NOT_FOUND;
+ rval = bp.getter.invoke(javaObject, Context.emptyArgs);
+ type = bp.getter.method().getReturnType();
+ } else {
+ Field field = (Field) member;
+ rval = field.get(isStatic ? null : javaObject);
+ type = field.getType();
+ }
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ // Need to wrap the object before we return it.
+ scope = ScriptableObject.getTopLevelScope(scope);
+ return cx.getWrapFactory().wrap(cx, scope, rval, type);
+ }
+
+ void put(Scriptable scope, String name, Object javaObject,
+ Object value, boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticMembers : members;
+ Object member = ht.get(name);
+ if (!isStatic && member == null) {
+ // Try to get static member from instance (LC3)
+ member = staticMembers.get(name);
+ }
+ if (member == null)
+ throw reportMemberNotFound(name);
+ if (member instanceof FieldAndMethods) {
+ FieldAndMethods fam = (FieldAndMethods) ht.get(name);
+ member = fam.field;
+ }
+
+ // Is this a bean property "set"?
+ if (member instanceof BeanProperty) {
+ BeanProperty bp = (BeanProperty)member;
+ if (bp.setter == null) {
+ throw reportMemberNotFound(name);
+ }
+ // If there's only one setter or if the value is null, use the
+ // main setter. Otherwise, let the NativeJavaMethod decide which
+ // setter to use:
+ if (bp.setters == null || value == null) {
+ Class setType = bp.setter.argTypes[0];
+ Object[] args = { Context.jsToJava(value, setType) };
+ try {
+ bp.setter.invoke(javaObject, args);
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ } else {
+ Object[] args = { value };
+ bp.setters.call(Context.getContext(),
+ ScriptableObject.getTopLevelScope(scope),
+ scope, args);
+ }
+ }
+ else {
+ if (!(member instanceof Field)) {
+ String str = (member == null) ? "msg.java.internal.private"
+ : "msg.java.method.assign";
+ throw Context.reportRuntimeError1(str, name);
+ }
+ Field field = (Field)member;
+ Object javaValue = Context.jsToJava(value, field.getType());
+ try {
+ field.set(javaObject, javaValue);
+ } catch (IllegalAccessException accessEx) {
+ if ((field.getModifiers() & Modifier.FINAL) != 0) {
+ // treat Java final the same as JavaScript [[READONLY]]
+ return;
+ }
+ throw Context.throwAsScriptRuntimeEx(accessEx);
+ } catch (IllegalArgumentException argEx) {
+ throw Context.reportRuntimeError3(
+ "msg.java.internal.field.type",
+ value.getClass().getName(), field,
+ javaObject.getClass().getName());
+ }
+ }
+ }
+
+ Object[] getIds(boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticMembers : members;
+ int len = ht.size();
+ Object[] result = new Object[len];
+ Enumeration keys = ht.keys();
+ for (int i=0; i < len; i++)
+ result[i] = keys.nextElement();
+ return result;
+ }
+
+ static String javaSignature(Class type)
+ {
+ if (!type.isArray()) {
+ return type.getName();
+ } else {
+ int arrayDimension = 0;
+ do {
+ ++arrayDimension;
+ type = type.getComponentType();
+ } while (type.isArray());
+ String name = type.getName();
+ String suffix = "[]";
+ if (arrayDimension == 1) {
+ return name.concat(suffix);
+ } else {
+ int length = name.length() + arrayDimension * suffix.length();
+ StringBuffer sb = new StringBuffer(length);
+ sb.append(name);
+ while (arrayDimension != 0) {
+ --arrayDimension;
+ sb.append(suffix);
+ }
+ return sb.toString();
+ }
+ }
+ }
+
+ static String liveConnectSignature(Class[] argTypes)
+ {
+ int N = argTypes.length;
+ if (N == 0) { return "()"; }
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ for (int i = 0; i != N; ++i) {
+ if (i != 0) {
+ sb.append(',');
+ }
+ sb.append(javaSignature(argTypes[i]));
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ private MemberBox findExplicitFunction(String name, boolean isStatic)
+ {
+ int sigStart = name.indexOf('(');
+ if (sigStart < 0) { return null; }
+
+ Hashtable ht = isStatic ? staticMembers : members;
+ MemberBox[] methodsOrCtors = null;
+ boolean isCtor = (isStatic && sigStart == 0);
+
+ if (isCtor) {
+ // Explicit request for an overloaded constructor
+ methodsOrCtors = ctors;
+ } else {
+ // Explicit request for an overloaded method
+ String trueName = name.substring(0,sigStart);
+ Object obj = ht.get(trueName);
+ if (!isStatic && obj == null) {
+ // Try to get static member from instance (LC3)
+ obj = staticMembers.get(trueName);
+ }
+ if (obj instanceof NativeJavaMethod) {
+ NativeJavaMethod njm = (NativeJavaMethod)obj;
+ methodsOrCtors = njm.methods;
+ }
+ }
+
+ if (methodsOrCtors != null) {
+ for (int i = 0; i < methodsOrCtors.length; i++) {
+ Class[] type = methodsOrCtors[i].argTypes;
+ String sig = liveConnectSignature(type);
+ if (sigStart + sig.length() == name.length()
+ && name.regionMatches(sigStart, sig, 0, sig.length()))
+ {
+ return methodsOrCtors[i];
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private Object getExplicitFunction(Scriptable scope, String name,
+ Object javaObject, boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticMembers : members;
+ Object member = null;
+ MemberBox methodOrCtor = findExplicitFunction(name, isStatic);
+
+ if (methodOrCtor != null) {
+ Scriptable prototype =
+ ScriptableObject.getFunctionPrototype(scope);
+
+ if (methodOrCtor.isCtor()) {
+ NativeJavaConstructor fun =
+ new NativeJavaConstructor(methodOrCtor);
+ fun.setPrototype(prototype);
+ member = fun;
+ ht.put(name, fun);
+ } else {
+ String trueName = methodOrCtor.getName();
+ member = ht.get(trueName);
+
+ if (member instanceof NativeJavaMethod &&
+ ((NativeJavaMethod)member).methods.length > 1 ) {
+ NativeJavaMethod fun =
+ new NativeJavaMethod(methodOrCtor, name);
+ fun.setPrototype(prototype);
+ ht.put(name, fun);
+ member = fun;
+ }
+ }
+ }
+
+ return member;
+ }
+
+ /**
+ * Retrieves mapping of methods to accessible methods for a class.
+ * In case the class is not public, retrieves methods with same
+ * signature as its public methods from public superclasses and
+ * interfaces (if they exist). Basically upcasts every method to the
+ * nearest accessible method.
+ */
+ private static Method[] discoverAccessibleMethods(Class clazz,
+ boolean includeProtected,
+ boolean includePrivate)
+ {
+ Map map = new HashMap();
+ discoverAccessibleMethods(clazz, map, includeProtected, includePrivate);
+ return (Method[])map.values().toArray(new Method[map.size()]);
+ }
+
+ private static void discoverAccessibleMethods(Class clazz, Map map,
+ boolean includeProtected,
+ boolean includePrivate)
+ {
+ if (Modifier.isPublic(clazz.getModifiers()) || includePrivate) {
+ try {
+ if (includeProtected || includePrivate) {
+ while (clazz != null) {
+ try {
+ Method[] methods = clazz.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ int mods = method.getModifiers();
+
+ if (Modifier.isPublic(mods) ||
+ Modifier.isProtected(mods) ||
+ includePrivate)
+ {
+ if (includePrivate)
+ method.setAccessible(true);
+ map.put(new MethodSignature(method), method);
+ }
+ }
+ clazz = clazz.getSuperclass();
+ } catch (SecurityException e) {
+ // Some security settings (i.e., applets) disallow
+ // access to Class.getDeclaredMethods. Fall back to
+ // Class.getMethods.
+ Method[] methods = clazz.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ MethodSignature sig
+ = new MethodSignature(method);
+ if (map.get(sig) == null)
+ map.put(sig, method);
+ }
+ break; // getMethods gets superclass methods, no
+ // need to loop any more
+ }
+ }
+ } else {
+ Method[] methods = clazz.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ MethodSignature sig = new MethodSignature(method);
+ map.put(sig, method);
+ }
+ }
+ return;
+ } catch (SecurityException e) {
+ Context.reportWarning(
+ "Could not discover accessible methods of class " +
+ clazz.getName() + " due to lack of privileges, " +
+ "attemping superclasses/interfaces.");
+ // Fall through and attempt to discover superclass/interface
+ // methods
+ }
+ }
+
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+ discoverAccessibleMethods(interfaces[i], map, includeProtected,
+ includePrivate);
+ }
+ Class superclass = clazz.getSuperclass();
+ if (superclass != null) {
+ discoverAccessibleMethods(superclass, map, includeProtected,
+ includePrivate);
+ }
+ }
+
+ private static final class MethodSignature
+ {
+ private final String name;
+ private final Class[] args;
+
+ private MethodSignature(String name, Class[] args)
+ {
+ this.name = name;
+ this.args = args;
+ }
+
+ MethodSignature(Method method)
+ {
+ this(method.getName(), method.getParameterTypes());
+ }
+
+ public boolean equals(Object o)
+ {
+ if(o instanceof MethodSignature)
+ {
+ MethodSignature ms = (MethodSignature)o;
+ return ms.name.equals(name) && Arrays.equals(args, ms.args);
+ }
+ return false;
+ }
+
+ public int hashCode()
+ {
+ return name.hashCode() ^ args.length;
+ }
+ }
+
+ private void reflect(Scriptable scope, boolean includeProtected)
+ {
+ // We reflect methods first, because we want overloaded field/method
+ // names to be allocated to the NativeJavaMethod before the field
+ // gets in the way.
+
+ Method[] methods = discoverAccessibleMethods(cl, includeProtected,
+ includePrivate);
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ int mods = method.getModifiers();
+ boolean isStatic = Modifier.isStatic(mods);
+ Hashtable ht = isStatic ? staticMembers : members;
+ String name = method.getName();
+ Object value = ht.get(name);
+ if (value == null) {
+ ht.put(name, method);
+ } else {
+ ObjArray overloadedMethods;
+ if (value instanceof ObjArray) {
+ overloadedMethods = (ObjArray)value;
+ } else {
+ if (!(value instanceof Method)) Kit.codeBug();
+ // value should be instance of Method as at this stage
+ // staticMembers and members can only contain methods
+ overloadedMethods = new ObjArray();
+ overloadedMethods.add(value);
+ ht.put(name, overloadedMethods);
+ }
+ overloadedMethods.add(method);
+ }
+ }
+
+ // replace Method instances by wrapped NativeJavaMethod objects
+ // first in staticMembers and then in members
+ for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
+ boolean isStatic = (tableCursor == 0);
+ Hashtable ht = (isStatic) ? staticMembers : members;
+ Enumeration e = ht.keys();
+ while (e.hasMoreElements()) {
+ String name = (String)e.nextElement();
+ MemberBox[] methodBoxes;
+ Object value = ht.get(name);
+ if (value instanceof Method) {
+ methodBoxes = new MemberBox[1];
+ methodBoxes[0] = new MemberBox((Method)value);
+ } else {
+ ObjArray overloadedMethods = (ObjArray)value;
+ int N = overloadedMethods.size();
+ if (N < 2) Kit.codeBug();
+ methodBoxes = new MemberBox[N];
+ for (int i = 0; i != N; ++i) {
+ Method method = (Method)overloadedMethods.get(i);
+ methodBoxes[i] = new MemberBox(method);
+ }
+ }
+ NativeJavaMethod fun = new NativeJavaMethod(methodBoxes);
+ if (scope != null) {
+ ScriptRuntime.setFunctionProtoAndParent(fun, scope);
+ }
+ ht.put(name, fun);
+ }
+ }
+
+ // Reflect fields.
+ Field[] fields = getAccessibleFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ String name = field.getName();
+ int mods = field.getModifiers();
+ if (!includePrivate && !Modifier.isPublic(mods)) {
+ continue;
+ }
+ try {
+ boolean isStatic = Modifier.isStatic(mods);
+ Hashtable ht = isStatic ? staticMembers : members;
+ Object member = ht.get(name);
+ if (member == null) {
+ ht.put(name, field);
+ } else if (member instanceof NativeJavaMethod) {
+ NativeJavaMethod method = (NativeJavaMethod) member;
+ FieldAndMethods fam
+ = new FieldAndMethods(scope, method.methods, field);
+ Hashtable fmht = isStatic ? staticFieldAndMethods
+ : fieldAndMethods;
+ if (fmht == null) {
+ fmht = new Hashtable(4);
+ if (isStatic) {
+ staticFieldAndMethods = fmht;
+ } else {
+ fieldAndMethods = fmht;
+ }
+ }
+ fmht.put(name, fam);
+ ht.put(name, fam);
+ } else if (member instanceof Field) {
+ Field oldField = (Field) member;
+ // If this newly reflected field shadows an inherited field,
+ // then replace it. Otherwise, since access to the field
+ // would be ambiguous from Java, no field should be
+ // reflected.
+ // For now, the first field found wins, unless another field
+ // explicitly shadows it.
+ if (oldField.getDeclaringClass().
+ isAssignableFrom(field.getDeclaringClass()))
+ {
+ ht.put(name, field);
+ }
+ } else {
+ // "unknown member type"
+ Kit.codeBug();
+ }
+ } catch (SecurityException e) {
+ // skip this field
+ Context.reportWarning("Could not access field "
+ + name + " of class " + cl.getName() +
+ " due to lack of privileges.");
+ }
+ }
+
+ // Create bean propeties from corresponding get/set methods first for
+ // static members and then for instance members
+ for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
+ boolean isStatic = (tableCursor == 0);
+ Hashtable ht = (isStatic) ? staticMembers : members;
+
+ Hashtable toAdd = new Hashtable();
+
+ // Now, For each member, make "bean" properties.
+ for (Enumeration e = ht.keys(); e.hasMoreElements(); ) {
+
+ // Is this a getter?
+ String name = (String) e.nextElement();
+ boolean memberIsGetMethod = name.startsWith("get");
+ boolean memberIsSetMethod = name.startsWith("set");
+ boolean memberIsIsMethod = name.startsWith("is");
+ if (memberIsGetMethod || memberIsIsMethod
+ || memberIsSetMethod) {
+ // Double check name component.
+ String nameComponent
+ = name.substring(memberIsIsMethod ? 2 : 3);
+ if (nameComponent.length() == 0)
+ continue;
+
+ // Make the bean property name.
+ String beanPropertyName = nameComponent;
+ char ch0 = nameComponent.charAt(0);
+ if (Character.isUpperCase(ch0)) {
+ if (nameComponent.length() == 1) {
+ beanPropertyName = nameComponent.toLowerCase();
+ } else {
+ char ch1 = nameComponent.charAt(1);
+ if (!Character.isUpperCase(ch1)) {
+ beanPropertyName = Character.toLowerCase(ch0)
+ +nameComponent.substring(1);
+ }
+ }
+ }
+
+ // If we already have a member by this name, don't do this
+ // property.
+ if (ht.containsKey(beanPropertyName)
+ || toAdd.containsKey(beanPropertyName)) {
+ continue;
+ }
+
+ // Find the getter method, or if there is none, the is-
+ // method.
+ MemberBox getter = null;
+ getter = findGetter(isStatic, ht, "get", nameComponent);
+ // If there was no valid getter, check for an is- method.
+ if (getter == null) {
+ getter = findGetter(isStatic, ht, "is", nameComponent);
+ }
+
+ // setter
+ MemberBox setter = null;
+ NativeJavaMethod setters = null;
+ String setterName = "set".concat(nameComponent);
+
+ if (ht.containsKey(setterName)) {
+ // Is this value a method?
+ Object member = ht.get(setterName);
+ if (member instanceof NativeJavaMethod) {
+ NativeJavaMethod njmSet = (NativeJavaMethod)member;
+ if (getter != null) {
+ // We have a getter. Now, do we have a matching
+ // setter?
+ Class type = getter.method().getReturnType();
+ setter = extractSetMethod(type, njmSet.methods,
+ isStatic);
+ } else {
+ // No getter, find any set method
+ setter = extractSetMethod(njmSet.methods,
+ isStatic);
+ }
+ if (njmSet.methods.length > 1) {
+ setters = njmSet;
+ }
+ }
+ }
+ // Make the property.
+ BeanProperty bp = new BeanProperty(getter, setter,
+ setters);
+ toAdd.put(beanPropertyName, bp);
+ }
+ }
+
+ // Add the new bean properties.
+ for (Enumeration e = toAdd.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ Object value = toAdd.get(key);
+ ht.put(key, value);
+ }
+ }
+
+ // Reflect constructors
+ Constructor[] constructors = getAccessibleConstructors();
+ ctors = new MemberBox[constructors.length];
+ for (int i = 0; i != constructors.length; ++i) {
+ ctors[i] = new MemberBox(constructors[i]);
+ }
+ }
+
+ private Constructor[] getAccessibleConstructors()
+ {
+ // The JVM currently doesn't allow changing access on java.lang.Class
+ // constructors, so don't try
+ if (includePrivate && cl != ScriptRuntime.ClassClass) {
+ try {
+ Constructor[] cons = cl.getDeclaredConstructors();
+ Constructor.setAccessible(cons, true);
+
+ return cons;
+ } catch (SecurityException e) {
+ // Fall through to !includePrivate case
+ Context.reportWarning("Could not access constructor " +
+ " of class " + cl.getName() +
+ " due to lack of privileges.");
+ }
+ }
+ return cl.getConstructors();
+ }
+
+ private Field[] getAccessibleFields() {
+ if (includePrivate) {
+ try {
+ ArrayList fieldsList = new ArrayList();
+ Class currentClass = cl;
+
+ while (currentClass != null) {
+ // get all declared fields in this class, make them
+ // accessible, and save
+ Field[] declared = currentClass.getDeclaredFields();
+ for (int i = 0; i < declared.length; i++) {
+ declared[i].setAccessible(true);
+ fieldsList.add(declared[i]);
+ }
+ // walk up superclass chain. no need to deal specially with
+ // interfaces, since they can't have fields
+ currentClass = currentClass.getSuperclass();
+ }
+
+ return (Field[]) fieldsList.toArray(
+ new Field[fieldsList.size()]);
+ } catch (SecurityException e) {
+ // fall through to !includePrivate case
+ }
+ }
+ return cl.getFields();
+ }
+
+ private MemberBox findGetter(boolean isStatic, Hashtable ht, String prefix,
+ String propertyName)
+ {
+ String getterName = prefix.concat(propertyName);
+ if (ht.containsKey(getterName)) {
+ // Check that the getter is a method.
+ Object member = ht.get(getterName);
+ if (member instanceof NativeJavaMethod) {
+ NativeJavaMethod njmGet = (NativeJavaMethod) member;
+ return extractGetMethod(njmGet.methods, isStatic);
+ }
+ }
+ return null;
+ }
+
+ private static MemberBox extractGetMethod(MemberBox[] methods,
+ boolean isStatic)
+ {
+ // Inspect the list of all MemberBox for the only one having no
+ // parameters
+ for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
+ MemberBox method = methods[methodIdx];
+ // Does getter method have an empty parameter list with a return
+ // value (eg. a getSomething() or isSomething())?
+ if (method.argTypes.length == 0
+ && (!isStatic || method.isStatic()))
+ {
+ Class type = method.method().getReturnType();
+ if (type != Void.TYPE) {
+ return method;
+ }
+ break;
+ }
+ }
+ return null;
+ }
+
+ private static MemberBox extractSetMethod(Class type, MemberBox[] methods,
+ boolean isStatic)
+ {
+ //
+ // Note: it may be preferable to allow NativeJavaMethod.findFunction()
+ // to find the appropriate setter; unfortunately, it requires an
+ // instance of the target arg to determine that.
+ //
+
+ // Make two passes: one to find a method with direct type assignment,
+ // and one to find a widening conversion.
+ for (int pass = 1; pass <= 2; ++pass) {
+ for (int i = 0; i < methods.length; ++i) {
+ MemberBox method = methods[i];
+ if (!isStatic || method.isStatic()) {
+ Class[] params = method.argTypes;
+ if (params.length == 1) {
+ if (pass == 1) {
+ if (params[0] == type) {
+ return method;
+ }
+ } else {
+ if (pass != 2) Kit.codeBug();
+ if (params[0].isAssignableFrom(type)) {
+ return method;
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static MemberBox extractSetMethod(MemberBox[] methods,
+ boolean isStatic)
+ {
+
+ for (int i = 0; i < methods.length; ++i) {
+ MemberBox method = methods[i];
+ if (!isStatic || method.isStatic()) {
+ if (method.method().getReturnType() == Void.TYPE) {
+ if (method.argTypes.length == 1) {
+ return method;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ Hashtable getFieldAndMethodsObjects(Scriptable scope, Object javaObject,
+ boolean isStatic)
+ {
+ Hashtable ht = isStatic ? staticFieldAndMethods : fieldAndMethods;
+ if (ht == null)
+ return null;
+ int len = ht.size();
+ Hashtable result = new Hashtable(len);
+ Enumeration e = ht.elements();
+ while (len-- > 0) {
+ FieldAndMethods fam = (FieldAndMethods) e.nextElement();
+ FieldAndMethods famNew = new FieldAndMethods(scope, fam.methods,
+ fam.field);
+ famNew.javaObject = javaObject;
+ result.put(fam.field.getName(), famNew);
+ }
+ return result;
+ }
+
+ static JavaMembers lookupClass(Scriptable scope, Class dynamicType,
+ Class staticType, boolean includeProtected)
+ {
+ JavaMembers members;
+ scope = ScriptableObject.getTopLevelScope(scope);
+ ClassCache cache = ClassCache.get(scope);
+ Map<Class<?>,JavaMembers> ct = cache.getClassCacheMap();
+
+ Class cl = dynamicType;
+ for (;;) {
+ members = ct.get(cl);
+ if (members != null) {
+ return members;
+ }
+ try {
+ members = new JavaMembers(scope, cl, includeProtected);
+ break;
+ } catch (SecurityException e) {
+ // Reflection may fail for objects that are in a restricted
+ // access package (e.g. sun.*). If we get a security
+ // exception, try again with the static type if it is interface.
+ // Otherwise, try superclass
+ if (staticType != null && staticType.isInterface()) {
+ cl = staticType;
+ staticType = null; // try staticType only once
+ } else {
+ Class parent = cl.getSuperclass();
+ if (parent == null) {
+ if (cl.isInterface()) {
+ // last resort after failed staticType interface
+ parent = ScriptRuntime.ObjectClass;
+ } else {
+ throw e;
+ }
+ }
+ cl = parent;
+ }
+ }
+ }
+
+ if (cache.isCachingEnabled())
+ ct.put(cl, members);
+ return members;
+ }
+
+ RuntimeException reportMemberNotFound(String memberName)
+ {
+ return Context.reportRuntimeError2(
+ "msg.java.member.not.found", cl.getName(), memberName);
+ }
+
+ private Class cl;
+ private Hashtable members;
+ private Hashtable fieldAndMethods;
+ private Hashtable staticMembers;
+ private Hashtable staticFieldAndMethods;
+ MemberBox[] ctors;
+ private boolean includePrivate;
+}
+
+class BeanProperty
+{
+ BeanProperty(MemberBox getter, MemberBox setter, NativeJavaMethod setters)
+ {
+ this.getter = getter;
+ this.setter = setter;
+ this.setters = setters;
+ }
+
+ MemberBox getter;
+ MemberBox setter;
+ NativeJavaMethod setters;
+}
+
+class FieldAndMethods extends NativeJavaMethod
+{
+ static final long serialVersionUID = -9222428244284796755L;
+
+ FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field)
+ {
+ super(methods);
+ this.field = field;
+ setParentScope(scope);
+ setPrototype(ScriptableObject.getFunctionPrototype(scope));
+ }
+
+ public Object getDefaultValue(Class hint)
+ {
+ if (hint == ScriptRuntime.FunctionClass)
+ return this;
+ Object rval;
+ Class type;
+ try {
+ rval = field.get(javaObject);
+ type = field.getType();
+ } catch (IllegalAccessException accEx) {
+ throw Context.reportRuntimeError1(
+ "msg.java.internal.private", field.getName());
+ }
+ Context cx = Context.getContext();
+ rval = cx.getWrapFactory().wrap(cx, this, rval, type);
+ if (rval instanceof Scriptable) {
+ rval = ((Scriptable) rval).getDefaultValue(hint);
+ }
+ return rval;
+ }
+
+ Field field;
+ Object javaObject;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java
new file mode 100644
index 0000000..11ebedf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/JavaScriptException.java
@@ -0,0 +1,117 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Bojan Cekrlic
+ * Hannes Wallnoefer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Java reflection of JavaScript exceptions.
+ * Instances of this class are thrown by the JavaScript 'throw' keyword.
+ *
+ * @author Mike McCabe
+ */
+public class JavaScriptException extends RhinoException
+{
+ static final long serialVersionUID = -7666130513694669293L;
+
+ /**
+ * @deprecated
+ * Use {@link WrappedException#WrappedException(Throwable)} to report
+ * exceptions in Java code.
+ */
+ public JavaScriptException(Object value)
+ {
+ this(value, "", 0);
+ }
+
+ /**
+ * Create a JavaScript exception wrapping the given JavaScript value
+ *
+ * @param value the JavaScript value thrown.
+ */
+ public JavaScriptException(Object value, String sourceName, int lineNumber)
+ {
+ recordErrorOrigin(sourceName, lineNumber, null, 0);
+ this.value = value;
+ }
+
+ public String details()
+ {
+ try {
+ return ScriptRuntime.toString(value);
+ } catch (RuntimeException rte) {
+ // ScriptRuntime.toString may throw a RuntimeException
+ if (value == null) {
+ return "null";
+ } else if (value instanceof Scriptable) {
+ return ScriptRuntime.defaultObjectToString((Scriptable)value);
+ } else {
+ return value.toString();
+ }
+ }
+ }
+
+ /**
+ * @return the value wrapped by this exception
+ */
+ public Object getValue()
+ {
+ return value;
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#sourceName()} from the super class.
+ */
+ public String getSourceName()
+ {
+ return sourceName();
+ }
+
+ /**
+ * @deprecated Use {@link RhinoException#lineNumber()} from the super class.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber();
+ }
+
+ private Object value;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java
new file mode 100644
index 0000000..f7b4cad
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Kit.java
@@ -0,0 +1,486 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+
+/**
+ * Collection of utilities
+ */
+
+public class Kit
+{
+ /**
+ * Reflection of Throwable.initCause(Throwable) from JDK 1.4
+ * or nul if it is not available.
+ */
+ private static Method Throwable_initCause = null;
+
+ static {
+ // Are we running on a JDK 1.4 or later system?
+ try {
+ Class ThrowableClass = Kit.classOrNull("java.lang.Throwable");
+ Class[] signature = { ThrowableClass };
+ Throwable_initCause
+ = ThrowableClass.getMethod("initCause", signature);
+ } catch (Exception ex) {
+ // Assume any exceptions means the method does not exist.
+ }
+ }
+
+ public static Class classOrNull(String className)
+ {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException ex) {
+ } catch (SecurityException ex) {
+ } catch (LinkageError ex) {
+ } catch (IllegalArgumentException e) {
+ // Can be thrown if name has characters that a class name
+ // can not contain
+ }
+ return null;
+ }
+
+ public static Class classOrNull(ClassLoader loader, String className)
+ {
+ try {
+ return loader.loadClass(className);
+ } catch (ClassNotFoundException ex) {
+ } catch (SecurityException ex) {
+ } catch (LinkageError ex) {
+ } catch (IllegalArgumentException e) {
+ // Can be thrown if name has characters that a class name
+ // can not contain
+ }
+ return null;
+ }
+
+ static Object newInstanceOrNull(Class cl)
+ {
+ try {
+ return cl.newInstance();
+ } catch (SecurityException x) {
+ } catch (LinkageError ex) {
+ } catch (InstantiationException x) {
+ } catch (IllegalAccessException x) {
+ }
+ return null;
+ }
+
+ /**
+ * Check that testClass is accesible from the given loader.
+ */
+ static boolean testIfCanLoadRhinoClasses(ClassLoader loader)
+ {
+ Class testClass = ScriptRuntime.ContextFactoryClass;
+ Class x = Kit.classOrNull(loader, testClass.getName());
+ if (x != testClass) {
+ // The check covers the case when x == null =>
+ // loader does not know about testClass or the case
+ // when x != null && x != testClass =>
+ // loader loads a class unrelated to testClass
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * If initCause methods exists in Throwable, call
+ * <tt>ex.initCause(cause)</tt> or otherwise do nothing.
+ * @return The <tt>ex</tt> argument.
+ */
+ public static RuntimeException initCause(RuntimeException ex,
+ Throwable cause)
+ {
+ if (Throwable_initCause != null) {
+ Object[] args = { cause };
+ try {
+ Throwable_initCause.invoke(ex, args);
+ } catch (Exception e) {
+ // Ignore any exceptions
+ }
+ }
+ return ex;
+ }
+
+ /**
+ * Split string into array of strings using semicolon as string terminator
+ * (; after the last string is required).
+ */
+ public static String[] semicolonSplit(String s)
+ {
+ String[] array = null;
+ for (;;) {
+ // loop 2 times: first to count semicolons and then to fill array
+ int count = 0;
+ int cursor = 0;
+ for (;;) {
+ int next = s.indexOf(';', cursor);
+ if (next < 0) {
+ break;
+ }
+ if (array != null) {
+ array[count] = s.substring(cursor, next);
+ }
+ ++count;
+ cursor = next + 1;
+ }
+ // after the last semicolon
+ if (array == null) {
+ // array size counting state:
+ // check for required terminating ';'
+ if (cursor != s.length())
+ throw new IllegalArgumentException();
+ array = new String[count];
+ } else {
+ // array filling state: stop the loop
+ break;
+ }
+ }
+ return array;
+ }
+
+ /**
+ * If character <tt>c</tt> is a hexadecimal digit, return
+ * <tt>accumulator</tt> * 16 plus corresponding
+ * number. Otherise return -1.
+ */
+ public static int xDigitToInt(int c, int accumulator)
+ {
+ check: {
+ // Use 0..9 < A..Z < a..z
+ if (c <= '9') {
+ c -= '0';
+ if (0 <= c) { break check; }
+ } else if (c <= 'F') {
+ if ('A' <= c) {
+ c -= ('A' - 10);
+ break check;
+ }
+ } else if (c <= 'f') {
+ if ('a' <= c) {
+ c -= ('a' - 10);
+ break check;
+ }
+ }
+ return -1;
+ }
+ return (accumulator << 4) | c;
+ }
+
+ /**
+ * Add <i>listener</i> to <i>bag</i> of listeners.
+ * The function does not modify <i>bag</i> and return a new collection
+ * containing <i>listener</i> and all listeners from <i>bag</i>.
+ * Bag without listeners always represented as the null value.
+ * <p>
+ * Usage example:
+ * <pre>
+ * private volatile Object changeListeners;
+ *
+ * public void addMyListener(PropertyChangeListener l)
+ * {
+ * synchronized (this) {
+ * changeListeners = Kit.addListener(changeListeners, l);
+ * }
+ * }
+ *
+ * public void removeTextListener(PropertyChangeListener l)
+ * {
+ * synchronized (this) {
+ * changeListeners = Kit.removeListener(changeListeners, l);
+ * }
+ * }
+ *
+ * public void fireChangeEvent(Object oldValue, Object newValue)
+ * {
+ * // Get immune local copy
+ * Object listeners = changeListeners;
+ * if (listeners != null) {
+ * PropertyChangeEvent e = new PropertyChangeEvent(
+ * this, "someProperty" oldValue, newValue);
+ * for (int i = 0; ; ++i) {
+ * Object l = Kit.getListener(listeners, i);
+ * if (l == null)
+ * break;
+ * ((PropertyChangeListener)l).propertyChange(e);
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @param listener Listener to add to <i>bag</i>
+ * @param bag Current collection of listeners.
+ * @return A new bag containing all listeners from <i>bag</i> and
+ * <i>listener</i>.
+ * @see #removeListener(Object bag, Object listener)
+ * @see #getListener(Object bag, int index)
+ */
+ public static Object addListener(Object bag, Object listener)
+ {
+ if (listener == null) throw new IllegalArgumentException();
+ if (listener instanceof Object[]) throw new IllegalArgumentException();
+
+ if (bag == null) {
+ bag = listener;
+ } else if (!(bag instanceof Object[])) {
+ bag = new Object[] { bag, listener };
+ } else {
+ Object[] array = (Object[])bag;
+ int L = array.length;
+ // bag has at least 2 elements if it is array
+ if (L < 2) throw new IllegalArgumentException();
+ Object[] tmp = new Object[L + 1];
+ System.arraycopy(array, 0, tmp, 0, L);
+ tmp[L] = listener;
+ bag = tmp;
+ }
+
+ return bag;
+ }
+
+ /**
+ * Remove <i>listener</i> from <i>bag</i> of listeners.
+ * The function does not modify <i>bag</i> and return a new collection
+ * containing all listeners from <i>bag</i> except <i>listener</i>.
+ * If <i>bag</i> does not contain <i>listener</i>, the function returns
+ * <i>bag</i>.
+ * <p>
+ * For usage example, see {@link #addListener(Object bag, Object listener)}.
+ *
+ * @param listener Listener to remove from <i>bag</i>
+ * @param bag Current collection of listeners.
+ * @return A new bag containing all listeners from <i>bag</i> except
+ * <i>listener</i>.
+ * @see #addListener(Object bag, Object listener)
+ * @see #getListener(Object bag, int index)
+ */
+ public static Object removeListener(Object bag, Object listener)
+ {
+ if (listener == null) throw new IllegalArgumentException();
+ if (listener instanceof Object[]) throw new IllegalArgumentException();
+
+ if (bag == listener) {
+ bag = null;
+ } else if (bag instanceof Object[]) {
+ Object[] array = (Object[])bag;
+ int L = array.length;
+ // bag has at least 2 elements if it is array
+ if (L < 2) throw new IllegalArgumentException();
+ if (L == 2) {
+ if (array[1] == listener) {
+ bag = array[0];
+ } else if (array[0] == listener) {
+ bag = array[1];
+ }
+ } else {
+ int i = L;
+ do {
+ --i;
+ if (array[i] == listener) {
+ Object[] tmp = new Object[L - 1];
+ System.arraycopy(array, 0, tmp, 0, i);
+ System.arraycopy(array, i + 1, tmp, i, L - (i + 1));
+ bag = tmp;
+ break;
+ }
+ } while (i != 0);
+ }
+ }
+
+ return bag;
+ }
+
+ /**
+ * Get listener at <i>index</i> position in <i>bag</i> or null if
+ * <i>index</i> equals to number of listeners in <i>bag</i>.
+ * <p>
+ * For usage example, see {@link #addListener(Object bag, Object listener)}.
+ *
+ * @param bag Current collection of listeners.
+ * @param index Index of the listener to access.
+ * @return Listener at the given index or null.
+ * @see #addListener(Object bag, Object listener)
+ * @see #removeListener(Object bag, Object listener)
+ */
+ public static Object getListener(Object bag, int index)
+ {
+ if (index == 0) {
+ if (bag == null)
+ return null;
+ if (!(bag instanceof Object[]))
+ return bag;
+ Object[] array = (Object[])bag;
+ // bag has at least 2 elements if it is array
+ if (array.length < 2) throw new IllegalArgumentException();
+ return array[0];
+ } else if (index == 1) {
+ if (!(bag instanceof Object[])) {
+ if (bag == null) throw new IllegalArgumentException();
+ return null;
+ }
+ Object[] array = (Object[])bag;
+ // the array access will check for index on its own
+ return array[1];
+ } else {
+ // bag has to array
+ Object[] array = (Object[])bag;
+ int L = array.length;
+ if (L < 2) throw new IllegalArgumentException();
+ if (index == L)
+ return null;
+ return array[index];
+ }
+ }
+
+ static Object initHash(Hashtable h, Object key, Object initialValue)
+ {
+ synchronized (h) {
+ Object current = h.get(key);
+ if (current == null) {
+ h.put(key, initialValue);
+ } else {
+ initialValue = current;
+ }
+ }
+ return initialValue;
+ }
+
+ private final static class ComplexKey
+ {
+ private Object key1;
+ private Object key2;
+ private int hash;
+
+ ComplexKey(Object key1, Object key2)
+ {
+ this.key1 = key1;
+ this.key2 = key2;
+ }
+
+ public boolean equals(Object anotherObj)
+ {
+ if (!(anotherObj instanceof ComplexKey))
+ return false;
+ ComplexKey another = (ComplexKey)anotherObj;
+ return key1.equals(another.key1) && key2.equals(another.key2);
+ }
+
+ public int hashCode()
+ {
+ if (hash == 0) {
+ hash = key1.hashCode() ^ key2.hashCode();
+ }
+ return hash;
+ }
+ }
+
+ public static Object makeHashKeyFromPair(Object key1, Object key2)
+ {
+ if (key1 == null) throw new IllegalArgumentException();
+ if (key2 == null) throw new IllegalArgumentException();
+ return new ComplexKey(key1, key2);
+ }
+
+ public static String readReader(Reader r)
+ throws IOException
+ {
+ char[] buffer = new char[512];
+ int cursor = 0;
+ for (;;) {
+ int n = r.read(buffer, cursor, buffer.length - cursor);
+ if (n < 0) { break; }
+ cursor += n;
+ if (cursor == buffer.length) {
+ char[] tmp = new char[buffer.length * 2];
+ System.arraycopy(buffer, 0, tmp, 0, cursor);
+ buffer = tmp;
+ }
+ }
+ return new String(buffer, 0, cursor);
+ }
+
+ public static byte[] readStream(InputStream is, int initialBufferCapacity)
+ throws IOException
+ {
+ if (initialBufferCapacity <= 0) {
+ throw new IllegalArgumentException(
+ "Bad initialBufferCapacity: "+initialBufferCapacity);
+ }
+ byte[] buffer = new byte[initialBufferCapacity];
+ int cursor = 0;
+ for (;;) {
+ int n = is.read(buffer, cursor, buffer.length - cursor);
+ if (n < 0) { break; }
+ cursor += n;
+ if (cursor == buffer.length) {
+ byte[] tmp = new byte[buffer.length * 2];
+ System.arraycopy(buffer, 0, tmp, 0, cursor);
+ buffer = tmp;
+ }
+ }
+ if (cursor != buffer.length) {
+ byte[] tmp = new byte[cursor];
+ System.arraycopy(buffer, 0, tmp, 0, cursor);
+ buffer = tmp;
+ }
+ return buffer;
+ }
+
+ /**
+ * Throws RuntimeException to indicate failed assertion.
+ * The function never returns and its return type is RuntimeException
+ * only to be able to write <tt>throw Kit.codeBug()</tt> if plain
+ * <tt>Kit.codeBug()</tt> triggers unreachable code error.
+ */
+ public static RuntimeException codeBug()
+ throws RuntimeException
+ {
+ RuntimeException ex = new IllegalStateException("FAILED ASSERTION");
+ // Print stack trace ASAP
+ ex.printStackTrace(System.err);
+ throw ex;
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java
new file mode 100644
index 0000000..4153372
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/LazilyLoadedCtor.java
@@ -0,0 +1,136 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+
+/**
+ * Avoid loading classes unless they are used.
+ *
+ * <p> This improves startup time and average memory usage.
+ */
+public final class LazilyLoadedCtor implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private static final int STATE_BEFORE_INIT = 0;
+ private static final int STATE_INITIALIZING = 1;
+ private static final int STATE_WITH_VALUE = 2;
+
+ private final ScriptableObject scope;
+ private final String propertyName;
+ private final String className;
+ private final boolean sealed;
+ private Object initializedValue;
+ private int state;
+
+ public LazilyLoadedCtor(ScriptableObject scope, String propertyName,
+ String className, boolean sealed)
+ {
+
+ this.scope = scope;
+ this.propertyName = propertyName;
+ this.className = className;
+ this.sealed = sealed;
+ this.state = STATE_BEFORE_INIT;
+
+ scope.addLazilyInitializedValue(propertyName, 0, this,
+ ScriptableObject.DONTENUM);
+ }
+
+ void init()
+ {
+ synchronized (this) {
+ if (state == STATE_INITIALIZING)
+ throw new IllegalStateException(
+ "Recursive initialization for "+propertyName);
+ if (state == STATE_BEFORE_INIT) {
+ state = STATE_INITIALIZING;
+ // Set value now to have something to set in finally block if
+ // buildValue throws.
+ Object value = Scriptable.NOT_FOUND;
+ try {
+ value = buildValue();
+ } finally {
+ initializedValue = value;
+ state = STATE_WITH_VALUE;
+ }
+ }
+ }
+ }
+
+ Object getValue()
+ {
+ if (state != STATE_WITH_VALUE)
+ throw new IllegalStateException(propertyName);
+ return initializedValue;
+ }
+
+ private Object buildValue()
+ {
+ Class cl = Kit.classOrNull(className);
+ if (cl != null) {
+ try {
+ Object value = ScriptableObject.buildClassCtor(scope, cl,
+ sealed, false);
+ if (value != null) {
+ return value;
+ }
+ else {
+ // cl has own static initializer which is expected
+ // to set the property on its own.
+ value = scope.get(propertyName, scope);
+ if (value != Scriptable.NOT_FOUND)
+ return value;
+ }
+ } catch (InvocationTargetException ex) {
+ Throwable target = ex.getTargetException();
+ if (target instanceof RuntimeException) {
+ throw (RuntimeException)target;
+ }
+ } catch (RhinoException ex) {
+ } catch (InstantiationException ex) {
+ } catch (IllegalAccessException ex) {
+ } catch (SecurityException ex) {
+ }
+ }
+ return Scriptable.NOT_FOUND;
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java
new file mode 100644
index 0000000..2d3553f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/MemberBox.java
@@ -0,0 +1,362 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Felix Meschberger
+ * Norris Boyd
+ * Ulrike Mueller <umueller@demandware.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+import java.io.*;
+
+/**
+ * Wrappper class for Method and Constructor instances to cache
+ * getParameterTypes() results, recover from IllegalAccessException
+ * in some cases and provide serialization support.
+ *
+ * @author Igor Bukanov
+ */
+
+final class MemberBox implements Serializable
+{
+ static final long serialVersionUID = 6358550398665688245L;
+
+ private transient Member memberObject;
+ transient Class[] argTypes;
+ transient Object delegateTo;
+ transient boolean vararg;
+
+
+ MemberBox(Method method)
+ {
+ init(method);
+ }
+
+ MemberBox(Constructor constructor)
+ {
+ init(constructor);
+ }
+
+ private void init(Method method)
+ {
+ this.memberObject = method;
+ this.argTypes = method.getParameterTypes();
+ this.vararg = VMBridge.instance.isVarArgs(method);
+ }
+
+ private void init(Constructor constructor)
+ {
+ this.memberObject = constructor;
+ this.argTypes = constructor.getParameterTypes();
+ this.vararg = VMBridge.instance.isVarArgs(constructor);
+ }
+
+ Method method()
+ {
+ return (Method)memberObject;
+ }
+
+ Constructor ctor()
+ {
+ return (Constructor)memberObject;
+ }
+
+ Member member()
+ {
+ return memberObject;
+ }
+
+ boolean isMethod()
+ {
+ return memberObject instanceof Method;
+ }
+
+ boolean isCtor()
+ {
+ return memberObject instanceof Constructor;
+ }
+
+ boolean isStatic()
+ {
+ return Modifier.isStatic(memberObject.getModifiers());
+ }
+
+ String getName()
+ {
+ return memberObject.getName();
+ }
+
+ Class getDeclaringClass()
+ {
+ return memberObject.getDeclaringClass();
+ }
+
+ String toJavaDeclaration()
+ {
+ StringBuffer sb = new StringBuffer();
+ if (isMethod()) {
+ Method method = method();
+ sb.append(method.getReturnType());
+ sb.append(' ');
+ sb.append(method.getName());
+ } else {
+ Constructor ctor = ctor();
+ String name = ctor.getDeclaringClass().getName();
+ int lastDot = name.lastIndexOf('.');
+ if (lastDot >= 0) {
+ name = name.substring(lastDot + 1);
+ }
+ sb.append(name);
+ }
+ sb.append(JavaMembers.liveConnectSignature(argTypes));
+ return sb.toString();
+ }
+
+ public String toString()
+ {
+ return memberObject.toString();
+ }
+
+ Object invoke(Object target, Object[] args)
+ {
+ Method method = method();
+ try {
+ try {
+ return method.invoke(target, args);
+ } catch (IllegalAccessException ex) {
+ Method accessible = searchAccessibleMethod(method, argTypes);
+ if (accessible != null) {
+ memberObject = accessible;
+ method = accessible;
+ } else {
+ if (!VMBridge.instance.tryToMakeAccessible(method)) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+ // Retry after recovery
+ return method.invoke(target, args);
+ }
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+
+ Object newInstance(Object[] args)
+ {
+ Constructor ctor = ctor();
+ try {
+ try {
+ return ctor.newInstance(args);
+ } catch (IllegalAccessException ex) {
+ if (!VMBridge.instance.tryToMakeAccessible(ctor)) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+ return ctor.newInstance(args);
+ } catch (Exception ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+
+ private static Method searchAccessibleMethod(Method method, Class[] params)
+ {
+ int modifiers = method.getModifiers();
+ if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
+ Class c = method.getDeclaringClass();
+ if (!Modifier.isPublic(c.getModifiers())) {
+ String name = method.getName();
+ Class[] intfs = c.getInterfaces();
+ for (int i = 0, N = intfs.length; i != N; ++i) {
+ Class intf = intfs[i];
+ if (Modifier.isPublic(intf.getModifiers())) {
+ try {
+ return intf.getMethod(name, params);
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) { }
+ }
+ }
+ for (;;) {
+ c = c.getSuperclass();
+ if (c == null) { break; }
+ if (Modifier.isPublic(c.getModifiers())) {
+ try {
+ Method m = c.getMethod(name, params);
+ int mModifiers = m.getModifiers();
+ if (Modifier.isPublic(mModifiers)
+ && !Modifier.isStatic(mModifiers))
+ {
+ return m;
+ }
+ } catch (NoSuchMethodException ex) {
+ } catch (SecurityException ex) { }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ Member member = readMember(in);
+ if (member instanceof Method) {
+ init((Method)member);
+ } else {
+ init((Constructor)member);
+ }
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ writeMember(out, memberObject);
+ }
+
+ /**
+ * Writes a Constructor or Method object.
+ *
+ * Methods and Constructors are not serializable, so we must serialize
+ * information about the class, the name, and the parameters and
+ * recreate upon deserialization.
+ */
+ private static void writeMember(ObjectOutputStream out, Member member)
+ throws IOException
+ {
+ if (member == null) {
+ out.writeBoolean(false);
+ return;
+ }
+ out.writeBoolean(true);
+ if (!(member instanceof Method || member instanceof Constructor))
+ throw new IllegalArgumentException("not Method or Constructor");
+ out.writeBoolean(member instanceof Method);
+ out.writeObject(member.getName());
+ out.writeObject(member.getDeclaringClass());
+ if (member instanceof Method) {
+ writeParameters(out, ((Method) member).getParameterTypes());
+ } else {
+ writeParameters(out, ((Constructor) member).getParameterTypes());
+ }
+ }
+
+ /**
+ * Reads a Method or a Constructor from the stream.
+ */
+ private static Member readMember(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ if (!in.readBoolean())
+ return null;
+ boolean isMethod = in.readBoolean();
+ String name = (String) in.readObject();
+ Class declaring = (Class) in.readObject();
+ Class[] parms = readParameters(in);
+ try {
+ if (isMethod) {
+ return declaring.getMethod(name, parms);
+ } else {
+ return declaring.getConstructor(parms);
+ }
+ } catch (NoSuchMethodException e) {
+ throw new IOException("Cannot find member: " + e);
+ }
+ }
+
+ private static final Class[] primitives = {
+ Boolean.TYPE,
+ Byte.TYPE,
+ Character.TYPE,
+ Double.TYPE,
+ Float.TYPE,
+ Integer.TYPE,
+ Long.TYPE,
+ Short.TYPE,
+ Void.TYPE
+ };
+
+ /**
+ * Writes an array of parameter types to the stream.
+ *
+ * Requires special handling because primitive types cannot be
+ * found upon deserialization by the default Java implementation.
+ */
+ private static void writeParameters(ObjectOutputStream out, Class[] parms)
+ throws IOException
+ {
+ out.writeShort(parms.length);
+ outer:
+ for (int i=0; i < parms.length; i++) {
+ Class parm = parms[i];
+ boolean primitive = parm.isPrimitive();
+ out.writeBoolean(primitive);
+ if (!primitive) {
+ out.writeObject(parm);
+ continue;
+ }
+ for (int j=0; j < primitives.length; j++) {
+ if (parm.equals(primitives[j])) {
+ out.writeByte(j);
+ continue outer;
+ }
+ }
+ throw new IllegalArgumentException("Primitive " + parm +
+ " not found");
+ }
+ }
+
+ /**
+ * Reads an array of parameter types from the stream.
+ */
+ private static Class[] readParameters(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ Class[] result = new Class[in.readShort()];
+ for (int i=0; i < result.length; i++) {
+ if (!in.readBoolean()) {
+ result[i] = (Class) in.readObject();
+ continue;
+ }
+ result[i] = primitives[in.readByte()];
+ }
+ return result;
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java
new file mode 100644
index 0000000..b170ff4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeArray.java
@@ -0,0 +1,1727 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Mike McCabe
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Arrays;
+
+/**
+ * This class implements the Array native object.
+ * @author Norris Boyd
+ * @author Mike McCabe
+ */
+public class NativeArray extends IdScriptableObject
+{
+ static final long serialVersionUID = 7331366857676127338L;
+
+ /*
+ * Optimization possibilities and open issues:
+ * - Long vs. double schizophrenia. I suspect it might be better
+ * to use double throughout.
+ *
+ * - Functions that need a new Array call "new Array" in the
+ * current scope rather than using a hardwired constructor;
+ * "Array" could be redefined. It turns out that js calls the
+ * equivalent of "new Array" in the current scope, except that it
+ * always gets at least an object back, even when Array == null.
+ */
+
+ private static final Object ARRAY_TAG = new Object();
+ private static final Integer NEGATIVE_ONE = new Integer(-1);
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeArray obj = new NativeArray(0);
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ static int getMaximumInitialCapacity() {
+ return maximumInitialCapacity;
+ }
+
+ static void setMaximumInitialCapacity(int maximumInitialCapacity) {
+ NativeArray.maximumInitialCapacity = maximumInitialCapacity;
+ }
+
+ public NativeArray(long lengthArg)
+ {
+ denseOnly = lengthArg <= maximumInitialCapacity;
+ if (denseOnly) {
+ int intLength = (int) lengthArg;
+ if (intLength < DEFAULT_INITIAL_CAPACITY)
+ intLength = DEFAULT_INITIAL_CAPACITY;
+ dense = new Object[intLength];
+ Arrays.fill(dense, Scriptable.NOT_FOUND);
+ }
+ length = lengthArg;
+ }
+
+ public NativeArray(Object[] array)
+ {
+ denseOnly = true;
+ dense = array;
+ length = array.length;
+ }
+
+ public String getClassName()
+ {
+ return "Array";
+ }
+
+ private static final int
+ Id_length = 1,
+ MAX_INSTANCE_ID = 1;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ if (s.equals("length")) {
+ return instanceIdInfo(DONTENUM | PERMANENT, Id_length);
+ }
+ return super.findInstanceIdInfo(s);
+ }
+
+ protected String getInstanceIdName(int id)
+ {
+ if (id == Id_length) { return "length"; }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ if (id == Id_length) {
+ return ScriptRuntime.wrapNumber(length);
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ if (id == Id_length) {
+ setLength(value); return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_join,
+ "join", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_reverse,
+ "reverse", 1);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_sort,
+ "sort", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_push,
+ "push", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_pop,
+ "pop", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_shift,
+ "shift", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_unshift,
+ "unshift", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_splice,
+ "splice", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_concat,
+ "concat", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_slice,
+ "slice", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_indexOf,
+ "indexOf", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_lastIndexOf,
+ "lastIndexOf", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_every,
+ "every", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_filter,
+ "filter", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_forEach,
+ "forEach", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_map,
+ "map", 2);
+ addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_some,
+ "some", 2);
+ super.fillConstructorProperties(ctor);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toLocaleString: arity=1; s="toLocaleString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_join: arity=1; s="join"; break;
+ case Id_reverse: arity=0; s="reverse"; break;
+ case Id_sort: arity=1; s="sort"; break;
+ case Id_push: arity=1; s="push"; break;
+ case Id_pop: arity=1; s="pop"; break;
+ case Id_shift: arity=1; s="shift"; break;
+ case Id_unshift: arity=1; s="unshift"; break;
+ case Id_splice: arity=1; s="splice"; break;
+ case Id_concat: arity=1; s="concat"; break;
+ case Id_slice: arity=1; s="slice"; break;
+ case Id_indexOf: arity=1; s="indexOf"; break;
+ case Id_lastIndexOf: arity=1; s="lastIndexOf"; break;
+ case Id_every: arity=1; s="every"; break;
+ case Id_filter: arity=1; s="filter"; break;
+ case Id_forEach: arity=1; s="forEach"; break;
+ case Id_map: arity=1; s="map"; break;
+ case Id_some: arity=1; s="some"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(ARRAY_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(ARRAY_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ again:
+ for (;;) {
+ switch (id) {
+ case ConstructorId_join:
+ case ConstructorId_reverse:
+ case ConstructorId_sort:
+ case ConstructorId_push:
+ case ConstructorId_pop:
+ case ConstructorId_shift:
+ case ConstructorId_unshift:
+ case ConstructorId_splice:
+ case ConstructorId_concat:
+ case ConstructorId_slice:
+ case ConstructorId_indexOf:
+ case ConstructorId_lastIndexOf:
+ case ConstructorId_every:
+ case ConstructorId_filter:
+ case ConstructorId_forEach:
+ case ConstructorId_map:
+ case ConstructorId_some: {
+ thisObj = ScriptRuntime.toObject(scope, args[0]);
+ Object[] newArgs = new Object[args.length-1];
+ for (int i=0; i < newArgs.length; i++)
+ newArgs[i] = args[i+1];
+ args = newArgs;
+ id = -id;
+ continue again;
+ }
+
+ case Id_constructor: {
+ boolean inNewExpr = (thisObj == null);
+ if (!inNewExpr) {
+ // IdFunctionObject.construct will set up parent, proto
+ return f.construct(cx, scope, args);
+ }
+ return jsConstructor(cx, scope, args);
+ }
+
+ case Id_toString:
+ return toStringHelper(cx, scope, thisObj,
+ cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE), false);
+
+ case Id_toLocaleString:
+ return toStringHelper(cx, scope, thisObj, false, true);
+
+ case Id_toSource:
+ return toStringHelper(cx, scope, thisObj, true, false);
+
+ case Id_join:
+ return js_join(cx, thisObj, args);
+
+ case Id_reverse:
+ return js_reverse(cx, thisObj, args);
+
+ case Id_sort:
+ return js_sort(cx, scope, thisObj, args);
+
+ case Id_push:
+ return js_push(cx, thisObj, args);
+
+ case Id_pop:
+ return js_pop(cx, thisObj, args);
+
+ case Id_shift:
+ return js_shift(cx, thisObj, args);
+
+ case Id_unshift:
+ return js_unshift(cx, thisObj, args);
+
+ case Id_splice:
+ return js_splice(cx, scope, thisObj, args);
+
+ case Id_concat:
+ return js_concat(cx, scope, thisObj, args);
+
+ case Id_slice:
+ return js_slice(cx, thisObj, args);
+
+ case Id_indexOf:
+ return indexOfHelper(cx, thisObj, args, false);
+
+ case Id_lastIndexOf:
+ return indexOfHelper(cx, thisObj, args, true);
+
+ case Id_every:
+ case Id_filter:
+ case Id_forEach:
+ case Id_map:
+ case Id_some:
+ return iterativeMethod(cx, id, scope, thisObj, args);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+ public Object get(int index, Scriptable start)
+ {
+ if (!denseOnly && isGetterOrSetter(null, index, false))
+ return super.get(index, start);
+ if (dense != null && 0 <= index && index < dense.length)
+ return dense[index];
+ return super.get(index, start);
+ }
+
+ public boolean has(int index, Scriptable start)
+ {
+ if (!denseOnly && isGetterOrSetter(null, index, false))
+ return super.has(index, start);
+ if (dense != null && 0 <= index && index < dense.length)
+ return dense[index] != NOT_FOUND;
+ return super.has(index, start);
+ }
+
+ // if id is an array index (ECMA 15.4.0), return the number,
+ // otherwise return -1L
+ private static long toArrayIndex(String id)
+ {
+ double d = ScriptRuntime.toNumber(id);
+ if (d == d) {
+ long index = ScriptRuntime.toUint32(d);
+ if (index == d && index != 4294967295L) {
+ // Assume that ScriptRuntime.toString(index) is the same
+ // as java.lang.Long.toString(index) for long
+ if (Long.toString(index).equals(id)) {
+ return index;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public void put(String id, Scriptable start, Object value)
+ {
+ super.put(id, start, value);
+ if (start == this) {
+ // If the object is sealed, super will throw exception
+ long index = toArrayIndex(id);
+ if (index >= length) {
+ length = index + 1;
+ denseOnly = false;
+ }
+ }
+ }
+
+ private boolean ensureCapacity(int capacity)
+ {
+ if (capacity > dense.length) {
+ if (capacity > MAX_PRE_GROW_SIZE) {
+ denseOnly = false;
+ return false;
+ }
+ capacity = Math.max(capacity, (int)(dense.length * GROW_FACTOR));
+ Object[] newDense = new Object[capacity];
+ System.arraycopy(dense, 0, newDense, 0, dense.length);
+ Arrays.fill(newDense, dense.length, newDense.length,
+ Scriptable.NOT_FOUND);
+ dense = newDense;
+ }
+ return true;
+ }
+
+ public void put(int index, Scriptable start, Object value)
+ {
+ if (start == this && !isSealed() && dense != null && 0 <= index &&
+ (denseOnly || !isGetterOrSetter(null, index, true)))
+ {
+ if (index < dense.length) {
+ dense[index] = value;
+ if (this.length <= index)
+ this.length = (long)index + 1;
+ return;
+ } else if (denseOnly && index < dense.length * GROW_FACTOR &&
+ ensureCapacity(index+1))
+ {
+ dense[index] = value;
+ this.length = (long)index + 1;
+ return;
+ } else {
+ denseOnly = false;
+ }
+ }
+ super.put(index, start, value);
+ if (start == this) {
+ // only set the array length if given an array index (ECMA 15.4.0)
+ if (this.length <= index) {
+ // avoid overflowing index!
+ this.length = (long)index + 1;
+ }
+ }
+ }
+
+ public void delete(int index)
+ {
+ if (dense != null && 0 <= index && index < dense.length &&
+ !isSealed() && (denseOnly || !isGetterOrSetter(null, index, true)))
+ {
+ dense[index] = NOT_FOUND;
+ } else {
+ super.delete(index);
+ }
+ }
+
+ public Object[] getIds()
+ {
+ Object[] superIds = super.getIds();
+ if (dense == null) { return superIds; }
+ int N = dense.length;
+ long currentLength = length;
+ if (N > currentLength) {
+ N = (int)currentLength;
+ }
+ if (N == 0) { return superIds; }
+ int superLength = superIds.length;
+ Object[] ids = new Object[N + superLength];
+
+ int presentCount = 0;
+ for (int i = 0; i != N; ++i) {
+ // Replace existing elements by their indexes
+ if (dense[i] != NOT_FOUND) {
+ ids[presentCount] = new Integer(i);
+ ++presentCount;
+ }
+ }
+ if (presentCount != N) {
+ // dense contains deleted elems, need to shrink the result
+ Object[] tmp = new Object[presentCount + superLength];
+ System.arraycopy(ids, 0, tmp, 0, presentCount);
+ ids = tmp;
+ }
+ System.arraycopy(superIds, 0, ids, presentCount, superLength);
+ return ids;
+ }
+
+ public Object getDefaultValue(Class hint)
+ {
+ if (hint == ScriptRuntime.NumberClass) {
+ Context cx = Context.getContext();
+ if (cx.getLanguageVersion() == Context.VERSION_1_2)
+ return new Long(length);
+ }
+ return super.getDefaultValue(hint);
+ }
+
+ /**
+ * See ECMA 15.4.1,2
+ */
+ private static Object jsConstructor(Context cx, Scriptable scope,
+ Object[] args)
+ {
+ if (args.length == 0)
+ return new NativeArray(0);
+
+ // Only use 1 arg as first element for version 1.2; for
+ // any other version (including 1.3) follow ECMA and use it as
+ // a length.
+ if (cx.getLanguageVersion() == Context.VERSION_1_2) {
+ return new NativeArray(args);
+ } else {
+ Object arg0 = args[0];
+ if (args.length > 1 || !(arg0 instanceof Number)) {
+ return new NativeArray(args);
+ } else {
+ long len = ScriptRuntime.toUint32(arg0);
+ if (len != ((Number)arg0).doubleValue())
+ throw Context.reportRuntimeError0("msg.arraylength.bad");
+ return new NativeArray(len);
+ }
+ }
+ }
+
+ public long getLength() {
+ return length;
+ }
+
+ /** @deprecated Use {@link #getLength()} instead. */
+ public long jsGet_length() {
+ return getLength();
+ }
+
+ /**
+ * Change the value of the internal flag that determines whether all
+ * storage is handed by a dense backing array rather than an associative
+ * store.
+ * @param denseOnly new value for denseOnly flag
+ * @throws IllegalArgumentException if an attempt is made to enable
+ * denseOnly after it was disabled; NativeArray code is not written
+ * to handle switching back to a dense representation
+ */
+ void setDenseOnly(boolean denseOnly) {
+ if (denseOnly && !this.denseOnly)
+ throw new IllegalArgumentException();
+ this.denseOnly = denseOnly;
+ }
+
+ private void setLength(Object val) {
+ /* XXX do we satisfy this?
+ * 15.4.5.1 [[Put]](P, V):
+ * 1. Call the [[CanPut]] method of A with name P.
+ * 2. If Result(1) is false, return.
+ * ?
+ */
+
+ double d = ScriptRuntime.toNumber(val);
+ long longVal = ScriptRuntime.toUint32(d);
+ if (longVal != d)
+ throw Context.reportRuntimeError0("msg.arraylength.bad");
+
+ if (denseOnly) {
+ if (longVal < length) {
+ // downcast okay because denseOnly
+ Arrays.fill(dense, (int) longVal, dense.length, NOT_FOUND);
+ length = longVal;
+ return;
+ } else if (longVal < MAX_PRE_GROW_SIZE &&
+ longVal < (length * GROW_FACTOR) &&
+ ensureCapacity((int)longVal))
+ {
+ length = longVal;
+ return;
+ } else {
+ denseOnly = false;
+ }
+ }
+ if (longVal < length) {
+ // remove all properties between longVal and length
+ if (length - longVal > 0x1000) {
+ // assume that the representation is sparse
+ Object[] e = getIds(); // will only find in object itself
+ for (int i=0; i < e.length; i++) {
+ Object id = e[i];
+ if (id instanceof String) {
+ // > MAXINT will appear as string
+ String strId = (String)id;
+ long index = toArrayIndex(strId);
+ if (index >= longVal)
+ delete(strId);
+ } else {
+ int index = ((Integer)id).intValue();
+ if (index >= longVal)
+ delete(index);
+ }
+ }
+ } else {
+ // assume a dense representation
+ for (long i = longVal; i < length; i++) {
+ deleteElem(this, i);
+ }
+ }
+ }
+ length = longVal;
+ }
+
+ /* Support for generic Array-ish objects. Most of the Array
+ * functions try to be generic; anything that has a length
+ * property is assumed to be an array.
+ * getLengthProperty returns 0 if obj does not have the length property
+ * or its value is not convertible to a number.
+ */
+ static long getLengthProperty(Context cx, Scriptable obj) {
+ // These will both give numeric lengths within Uint32 range.
+ if (obj instanceof NativeString) {
+ return ((NativeString)obj).getLength();
+ } else if (obj instanceof NativeArray) {
+ return ((NativeArray)obj).getLength();
+ }
+ return ScriptRuntime.toUint32(
+ ScriptRuntime.getObjectProp(obj, "length", cx));
+ }
+
+ private static Object setLengthProperty(Context cx, Scriptable target,
+ long length)
+ {
+ return ScriptRuntime.setObjectProp(
+ target, "length", ScriptRuntime.wrapNumber(length), cx);
+ }
+
+ /* Utility functions to encapsulate index > Integer.MAX_VALUE
+ * handling. Also avoids unnecessary object creation that would
+ * be necessary to use the general ScriptRuntime.get/setElem
+ * functions... though this is probably premature optimization.
+ */
+ private static void deleteElem(Scriptable target, long index) {
+ int i = (int)index;
+ if (i == index) { target.delete(i); }
+ else { target.delete(Long.toString(index)); }
+ }
+
+ private static Object getElem(Context cx, Scriptable target, long index)
+ {
+ if (index > Integer.MAX_VALUE) {
+ String id = Long.toString(index);
+ return ScriptRuntime.getObjectProp(target, id, cx);
+ } else {
+ return ScriptRuntime.getObjectIndex(target, (int)index, cx);
+ }
+ }
+
+ private static void setElem(Context cx, Scriptable target, long index,
+ Object value)
+ {
+ if (index > Integer.MAX_VALUE) {
+ String id = Long.toString(index);
+ ScriptRuntime.setObjectProp(target, id, value, cx);
+ } else {
+ ScriptRuntime.setObjectIndex(target, (int)index, value, cx);
+ }
+ }
+
+ private static String toStringHelper(Context cx, Scriptable scope,
+ Scriptable thisObj,
+ boolean toSource, boolean toLocale)
+ {
+ /* It's probably redundant to handle long lengths in this
+ * function; StringBuffers are limited to 2^31 in java.
+ */
+
+ long length = getLengthProperty(cx, thisObj);
+
+ StringBuffer result = new StringBuffer(256);
+
+ // whether to return '4,unquoted,5' or '[4, "quoted", 5]'
+ String separator;
+
+ if (toSource) {
+ result.append('[');
+ separator = ", ";
+ } else {
+ separator = ",";
+ }
+
+ boolean haslast = false;
+ long i = 0;
+
+ boolean toplevel, iterating;
+ if (cx.iterating == null) {
+ toplevel = true;
+ iterating = false;
+ cx.iterating = new ObjToIntMap(31);
+ } else {
+ toplevel = false;
+ iterating = cx.iterating.has(thisObj);
+ }
+
+ // Make sure cx.iterating is set to null when done
+ // so we don't leak memory
+ try {
+ if (!iterating) {
+ cx.iterating.put(thisObj, 0); // stop recursion.
+ for (i = 0; i < length; i++) {
+ if (i > 0) result.append(separator);
+ Object elem = getElem(cx, thisObj, i);
+ if (elem == null || elem == Undefined.instance) {
+ haslast = false;
+ continue;
+ }
+ haslast = true;
+
+ if (toSource) {
+ result.append(ScriptRuntime.uneval(cx, scope, elem));
+
+ } else if (elem instanceof String) {
+ String s = (String)elem;
+ if (toSource) {
+ result.append('\"');
+ result.append(ScriptRuntime.escapeString(s));
+ result.append('\"');
+ } else {
+ result.append(s);
+ }
+
+ } else {
+ if (toLocale)
+ {
+ Callable fun;
+ Scriptable funThis;
+ fun = ScriptRuntime.getPropFunctionAndThis(
+ elem, "toLocaleString", cx);
+ funThis = ScriptRuntime.lastStoredScriptable(cx);
+ elem = fun.call(cx, scope, funThis,
+ ScriptRuntime.emptyArgs);
+ }
+ result.append(ScriptRuntime.toString(elem));
+ }
+ }
+ }
+ } finally {
+ if (toplevel) {
+ cx.iterating = null;
+ }
+ }
+
+ if (toSource) {
+ //for [,,].length behavior; we want toString to be symmetric.
+ if (!haslast && i > 0)
+ result.append(", ]");
+ else
+ result.append(']');
+ }
+ return result.toString();
+ }
+
+ /**
+ * See ECMA 15.4.4.3
+ */
+ private static String js_join(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ long llength = getLengthProperty(cx, thisObj);
+ int length = (int)llength;
+ if (llength != length) {
+ throw Context.reportRuntimeError1(
+ "msg.arraylength.too.big", String.valueOf(llength));
+ }
+ // if no args, use "," as separator
+ String separator = (args.length < 1 || args[0] == Undefined.instance)
+ ? ","
+ : ScriptRuntime.toString(args[0]);
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < length; i++) {
+ if (i != 0) {
+ sb.append(separator);
+ }
+ if (i < na.dense.length) {
+ Object temp = na.dense[i];
+ if (temp != null && temp != Undefined.instance &&
+ temp != Scriptable.NOT_FOUND)
+ {
+ sb.append(ScriptRuntime.toString(temp));
+ }
+ }
+ }
+ return sb.toString();
+ }
+ }
+ if (length == 0) {
+ return "";
+ }
+ String[] buf = new String[length];
+ int total_size = 0;
+ for (int i = 0; i != length; i++) {
+ Object temp = getElem(cx, thisObj, i);
+ if (temp != null && temp != Undefined.instance) {
+ String str = ScriptRuntime.toString(temp);
+ total_size += str.length();
+ buf[i] = str;
+ }
+ }
+ total_size += (length - 1) * separator.length();
+ StringBuffer sb = new StringBuffer(total_size);
+ for (int i = 0; i != length; i++) {
+ if (i != 0) {
+ sb.append(separator);
+ }
+ String str = buf[i];
+ if (str != null) {
+ // str == null for undefined or null
+ sb.append(str);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * See ECMA 15.4.4.4
+ */
+ private static Scriptable js_reverse(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly) {
+ for (int i=0, j=((int)na.length)-1; i < j; i++,j--) {
+ Object temp = na.dense[i];
+ na.dense[i] = na.dense[j];
+ na.dense[j] = temp;
+ }
+ return thisObj;
+ }
+ }
+ long len = getLengthProperty(cx, thisObj);
+
+ long half = len / 2;
+ for(long i=0; i < half; i++) {
+ long j = len - i - 1;
+ Object temp1 = getElem(cx, thisObj, i);
+ Object temp2 = getElem(cx, thisObj, j);
+ setElem(cx, thisObj, i, temp2);
+ setElem(cx, thisObj, j, temp1);
+ }
+ return thisObj;
+ }
+
+ /**
+ * See ECMA 15.4.4.5
+ */
+ private static Scriptable js_sort(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ long length = getLengthProperty(cx, thisObj);
+
+ if (length <= 1) { return thisObj; }
+
+ Object compare;
+ Object[] cmpBuf;
+
+ if (args.length > 0 && Undefined.instance != args[0]) {
+ // sort with given compare function
+ compare = args[0];
+ cmpBuf = new Object[2]; // Buffer for cmp arguments
+ } else {
+ // sort with default compare
+ compare = null;
+ cmpBuf = null;
+ }
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly) {
+ int ilength = (int) length;
+ heapsort(cx, scope, na.dense, ilength, compare, cmpBuf);
+ return thisObj;
+ }
+ }
+
+ // Should we use the extended sort function, or the faster one?
+ if (length >= Integer.MAX_VALUE) {
+ heapsort_extended(cx, scope, thisObj, length, compare, cmpBuf);
+ } else {
+ int ilength = (int)length;
+ // copy the JS array into a working array, so it can be
+ // sorted cheaply.
+ Object[] working = new Object[ilength];
+ for (int i = 0; i != ilength; ++i) {
+ working[i] = getElem(cx, thisObj, i);
+ }
+
+ heapsort(cx, scope, working, ilength, compare, cmpBuf);
+
+ // copy the working array back into thisObj
+ for (int i = 0; i != ilength; ++i) {
+ setElem(cx, thisObj, i, working[i]);
+ }
+ }
+ return thisObj;
+ }
+
+ // Return true only if x > y
+ private static boolean isBigger(Context cx, Scriptable scope,
+ Object x, Object y,
+ Object cmp, Object[] cmpBuf)
+ {
+ if (cmp == null) {
+ if (cmpBuf != null) Kit.codeBug();
+ } else {
+ if (cmpBuf == null || cmpBuf.length != 2) Kit.codeBug();
+ }
+
+ Object undef = Undefined.instance;
+ Object notfound = Scriptable.NOT_FOUND;
+
+ // sort undefined to end
+ if (y == undef || y == notfound) {
+ return false; // x can not be bigger then undef
+ } else if (x == undef || x == notfound) {
+ return true; // y != undef here, so x > y
+ }
+
+ if (cmp == null) {
+ // if no cmp function supplied, sort lexicographically
+ String a = ScriptRuntime.toString(x);
+ String b = ScriptRuntime.toString(y);
+ return a.compareTo(b) > 0;
+ }
+ else {
+ // assemble args and call supplied JS cmp function
+ cmpBuf[0] = x;
+ cmpBuf[1] = y;
+ Callable fun = ScriptRuntime.getValueFunctionAndThis(cmp, cx);
+ Scriptable funThis = ScriptRuntime.lastStoredScriptable(cx);
+
+ Object ret = fun.call(cx, scope, funThis, cmpBuf);
+ double d = ScriptRuntime.toNumber(ret);
+
+ // XXX what to do when cmp function returns NaN? ECMA states
+ // that it's then not a 'consistent comparison function'... but
+ // then what do we do? Back out and start over with the generic
+ // cmp function when we see a NaN? Throw an error?
+
+ // for now, just ignore it:
+
+ return d > 0;
+ }
+ }
+
+/** Heapsort implementation.
+ * See "Introduction to Algorithms" by Cormen, Leiserson, Rivest for details.
+ * Adjusted for zero based indexes.
+ */
+ private static void heapsort(Context cx, Scriptable scope,
+ Object[] array, int length,
+ Object cmp, Object[] cmpBuf)
+ {
+ if (length <= 1) Kit.codeBug();
+
+ // Build heap
+ for (int i = length / 2; i != 0;) {
+ --i;
+ Object pivot = array[i];
+ heapify(cx, scope, pivot, array, i, length, cmp, cmpBuf);
+ }
+
+ // Sort heap
+ for (int i = length; i != 1;) {
+ --i;
+ Object pivot = array[i];
+ array[i] = array[0];
+ heapify(cx, scope, pivot, array, 0, i, cmp, cmpBuf);
+ }
+ }
+
+/** pivot and child heaps of i should be made into heap starting at i,
+ * original array[i] is never used to have less array access during sorting.
+ */
+ private static void heapify(Context cx, Scriptable scope,
+ Object pivot, Object[] array, int i, int end,
+ Object cmp, Object[] cmpBuf)
+ {
+ for (;;) {
+ int child = i * 2 + 1;
+ if (child >= end) {
+ break;
+ }
+ Object childVal = array[child];
+ if (child + 1 < end) {
+ Object nextVal = array[child + 1];
+ if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {
+ ++child; childVal = nextVal;
+ }
+ }
+ if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {
+ break;
+ }
+ array[i] = childVal;
+ i = child;
+ }
+ array[i] = pivot;
+ }
+
+/** Version of heapsort that call getElem/setElem on target to query/assign
+ * array elements instead of Java array access
+ */
+ private static void heapsort_extended(Context cx, Scriptable scope,
+ Scriptable target, long length,
+ Object cmp, Object[] cmpBuf)
+ {
+ if (length <= 1) Kit.codeBug();
+
+ // Build heap
+ for (long i = length / 2; i != 0;) {
+ --i;
+ Object pivot = getElem(cx, target, i);
+ heapify_extended(cx, scope, pivot, target, i, length, cmp, cmpBuf);
+ }
+
+ // Sort heap
+ for (long i = length; i != 1;) {
+ --i;
+ Object pivot = getElem(cx, target, i);
+ setElem(cx, target, i, getElem(cx, target, 0));
+ heapify_extended(cx, scope, pivot, target, 0, i, cmp, cmpBuf);
+ }
+ }
+
+ private static void heapify_extended(Context cx, Scriptable scope,
+ Object pivot, Scriptable target,
+ long i, long end,
+ Object cmp, Object[] cmpBuf)
+ {
+ for (;;) {
+ long child = i * 2 + 1;
+ if (child >= end) {
+ break;
+ }
+ Object childVal = getElem(cx, target, child);
+ if (child + 1 < end) {
+ Object nextVal = getElem(cx, target, child + 1);
+ if (isBigger(cx, scope, nextVal, childVal, cmp, cmpBuf)) {
+ ++child; childVal = nextVal;
+ }
+ }
+ if (!isBigger(cx, scope, childVal, pivot, cmp, cmpBuf)) {
+ break;
+ }
+ setElem(cx, target, i, childVal);
+ i = child;
+ }
+ setElem(cx, target, i, pivot);
+ }
+
+ /**
+ * Non-ECMA methods.
+ */
+
+ private static Object js_push(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly &&
+ na.ensureCapacity((int) na.length + args.length))
+ {
+ for (int i = 0; i < args.length; i++) {
+ na.dense[(int)na.length++] = args[i];
+ }
+ return ScriptRuntime.wrapNumber(na.length);
+ }
+ }
+ long length = getLengthProperty(cx, thisObj);
+ for (int i = 0; i < args.length; i++) {
+ setElem(cx, thisObj, length + i, args[i]);
+ }
+
+ length += args.length;
+ Object lengthObj = setLengthProperty(cx, thisObj, length);
+
+ /*
+ * If JS1.2, follow Perl4 by returning the last thing pushed.
+ * Otherwise, return the new array length.
+ */
+ if (cx.getLanguageVersion() == Context.VERSION_1_2)
+ // if JS1.2 && no arguments, return undefined.
+ return args.length == 0
+ ? Undefined.instance
+ : args[args.length - 1];
+
+ else
+ return lengthObj;
+ }
+
+ private static Object js_pop(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ Object result;
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly && na.length > 0) {
+ na.length--;
+ result = na.dense[(int)na.length];
+ na.dense[(int)na.length] = NOT_FOUND;
+ return result;
+ }
+ }
+ long length = getLengthProperty(cx, thisObj);
+ if (length > 0) {
+ length--;
+
+ // Get the to-be-deleted property's value.
+ result = getElem(cx, thisObj, length);
+
+ // We don't need to delete the last property, because
+ // setLength does that for us.
+ } else {
+ result = Undefined.instance;
+ }
+ // necessary to match js even when length < 0; js pop will give a
+ // length property to any target it is called on.
+ setLengthProperty(cx, thisObj, length);
+
+ return result;
+ }
+
+ private static Object js_shift(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly && na.length > 0) {
+ na.length--;
+ Object result = na.dense[0];
+ System.arraycopy(na.dense, 1, na.dense, 0, (int)na.length);
+ na.dense[(int)na.length] = NOT_FOUND;
+ return result;
+ }
+ }
+ Object result;
+ long length = getLengthProperty(cx, thisObj);
+ if (length > 0) {
+ long i = 0;
+ length--;
+
+ // Get the to-be-deleted property's value.
+ result = getElem(cx, thisObj, i);
+
+ /*
+ * Slide down the array above the first element. Leave i
+ * set to point to the last element.
+ */
+ if (length > 0) {
+ for (i = 1; i <= length; i++) {
+ Object temp = getElem(cx, thisObj, i);
+ setElem(cx, thisObj, i - 1, temp);
+ }
+ }
+ // We don't need to delete the last property, because
+ // setLength does that for us.
+ } else {
+ result = Undefined.instance;
+ }
+ setLengthProperty(cx, thisObj, length);
+ return result;
+ }
+
+ private static Object js_unshift(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly &&
+ na.ensureCapacity((int)na.length + args.length))
+ {
+ System.arraycopy(na.dense, 0, na.dense, args.length,
+ (int) na.length);
+ for (int i = 0; i < args.length; i++) {
+ na.dense[i] = args[i];
+ }
+ na.length += args.length;
+ return ScriptRuntime.wrapNumber(na.length);
+ }
+ }
+ long length = getLengthProperty(cx, thisObj);
+ int argc = args.length;
+
+ if (args.length > 0) {
+ /* Slide up the array to make room for args at the bottom */
+ if (length > 0) {
+ for (long last = length - 1; last >= 0; last--) {
+ Object temp = getElem(cx, thisObj, last);
+ setElem(cx, thisObj, last + argc, temp);
+ }
+ }
+
+ /* Copy from argv to the bottom of the array. */
+ for (int i = 0; i < args.length; i++) {
+ setElem(cx, thisObj, i, args[i]);
+ }
+
+ /* Follow Perl by returning the new array length. */
+ length += args.length;
+ return setLengthProperty(cx, thisObj, length);
+ }
+ return ScriptRuntime.wrapNumber(length);
+ }
+
+ private static Object js_splice(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ NativeArray na = null;
+ boolean denseMode = false;
+ if (thisObj instanceof NativeArray) {
+ na = (NativeArray) thisObj;
+ denseMode = na.denseOnly;
+ }
+
+ /* create an empty Array to return. */
+ scope = getTopLevelScope(scope);
+ int argc = args.length;
+ if (argc == 0)
+ return ScriptRuntime.newObject(cx, scope, "Array", null);
+ long length = getLengthProperty(cx, thisObj);
+
+ /* Convert the first argument into a starting index. */
+ long begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length);
+ argc--;
+
+ /* Convert the second argument into count */
+ long count;
+ if (args.length == 1) {
+ count = length - begin;
+ } else {
+ double dcount = ScriptRuntime.toInteger(args[1]);
+ if (dcount < 0) {
+ count = 0;
+ } else if (dcount > (length - begin)) {
+ count = length - begin;
+ } else {
+ count = (long)dcount;
+ }
+ argc--;
+ }
+
+ long end = begin + count;
+
+ /* If there are elements to remove, put them into the return value. */
+ Object result;
+ if (count != 0) {
+ if (count == 1
+ && (cx.getLanguageVersion() == Context.VERSION_1_2))
+ {
+ /*
+ * JS lacks "list context", whereby in Perl one turns the
+ * single scalar that's spliced out into an array just by
+ * assigning it to @single instead of $single, or by using it
+ * as Perl push's first argument, for instance.
+ *
+ * JS1.2 emulated Perl too closely and returned a non-Array for
+ * the single-splice-out case, requiring callers to test and
+ * wrap in [] if necessary. So JS1.3, default, and other
+ * versions all return an array of length 1 for uniformity.
+ */
+ result = getElem(cx, thisObj, begin);
+ } else {
+ if (denseMode) {
+ int intLen = (int) (end - begin);
+ Object[] copy = new Object[intLen];
+ System.arraycopy(na.dense, (int) begin, copy, 0, intLen);
+ result = cx.newArray(scope, copy);
+ } else {
+ Scriptable resultArray = ScriptRuntime.newObject(cx, scope,
+ "Array", null);
+ for (long last = begin; last != end; last++) {
+ Object temp = getElem(cx, thisObj, last);
+ setElem(cx, resultArray, last - begin, temp);
+ }
+ result = resultArray;
+ }
+ }
+ } else { // (count == 0)
+ if (cx.getLanguageVersion() == Context.VERSION_1_2) {
+ /* Emulate C JS1.2; if no elements are removed, return undefined. */
+ result = Undefined.instance;
+ } else {
+ result = ScriptRuntime.newObject(cx, scope, "Array", null);
+ }
+ }
+
+ /* Find the direction (up or down) to copy and make way for argv. */
+ long delta = argc - count;
+ if (denseMode && length + delta < Integer.MAX_VALUE &&
+ na.ensureCapacity((int) (length + delta)))
+ {
+ System.arraycopy(na.dense, (int) end, na.dense,
+ (int) (begin + argc), (int) (length - end));
+ if (argc > 0) {
+ System.arraycopy(args, 2, na.dense, (int) begin, argc);
+ }
+ if (delta < 0) {
+ Arrays.fill(na.dense, (int) (length + delta), (int) length,
+ NOT_FOUND);
+ }
+ na.length = length + delta;
+ return result;
+ }
+
+ if (delta > 0) {
+ for (long last = length - 1; last >= end; last--) {
+ Object temp = getElem(cx, thisObj, last);
+ setElem(cx, thisObj, last + delta, temp);
+ }
+ } else if (delta < 0) {
+ for (long last = end; last < length; last++) {
+ Object temp = getElem(cx, thisObj, last);
+ setElem(cx, thisObj, last + delta, temp);
+ }
+ }
+
+ /* Copy from argv into the hole to complete the splice. */
+ int argoffset = args.length - argc;
+ for (int i = 0; i < argc; i++) {
+ setElem(cx, thisObj, begin + i, args[i + argoffset]);
+ }
+
+ /* Update length in case we deleted elements from the end. */
+ setLengthProperty(cx, thisObj, length + delta);
+ return result;
+ }
+
+ /*
+ * See Ecma 262v3 15.4.4.4
+ */
+ private static Scriptable js_concat(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ // create an empty Array to return.
+ scope = getTopLevelScope(scope);
+ Function ctor = ScriptRuntime.getExistingCtor(cx, scope, "Array");
+ Scriptable result = ctor.construct(cx, scope, ScriptRuntime.emptyArgs);
+ if (thisObj instanceof NativeArray && result instanceof NativeArray) {
+ NativeArray denseThis = (NativeArray) thisObj;
+ NativeArray denseResult = (NativeArray) result;
+ if (denseThis.denseOnly && denseResult.denseOnly) {
+ // First calculate length of resulting array
+ boolean canUseDense = true;
+ int length = (int) denseThis.length;
+ for (int i = 0; i < args.length && canUseDense; i++) {
+ if (ScriptRuntime.instanceOf(args[i], ctor, cx)) {
+ // only try to use dense approach for Array-like
+ // objects that are actually NativeArrays
+ canUseDense = args[i] instanceof NativeArray;
+ length += ((NativeArray) args[i]).length;
+ } else {
+ length++;
+ }
+ }
+ if (canUseDense && denseResult.ensureCapacity(length)) {
+ System.arraycopy(denseThis.dense, 0, denseResult.dense,
+ 0, (int) denseThis.length);
+ int cursor = (int) denseThis.length;
+ for (int i = 0; i < args.length && canUseDense; i++) {
+ if (args[i] instanceof NativeArray) {
+ NativeArray arg = (NativeArray) args[i];
+ System.arraycopy(arg.dense, 0,
+ denseResult.dense, cursor,
+ (int)arg.length);
+ cursor += (int)arg.length;
+ } else {
+ denseResult.dense[cursor++] = args[i];
+ }
+ }
+ denseResult.length = length;
+ return result;
+ }
+ }
+ }
+
+ long length;
+ long slot = 0;
+
+ /* Put the target in the result array; only add it as an array
+ * if it looks like one.
+ */
+ if (ScriptRuntime.instanceOf(thisObj, ctor, cx)) {
+ length = getLengthProperty(cx, thisObj);
+
+ // Copy from the target object into the result
+ for (slot = 0; slot < length; slot++) {
+ Object temp = getElem(cx, thisObj, slot);
+ setElem(cx, result, slot, temp);
+ }
+ } else {
+ setElem(cx, result, slot++, thisObj);
+ }
+
+ /* Copy from the arguments into the result. If any argument
+ * has a numeric length property, treat it as an array and add
+ * elements separately; otherwise, just copy the argument.
+ */
+ for (int i = 0; i < args.length; i++) {
+ if (ScriptRuntime.instanceOf(args[i], ctor, cx)) {
+ // ScriptRuntime.instanceOf => instanceof Scriptable
+ Scriptable arg = (Scriptable)args[i];
+ length = getLengthProperty(cx, arg);
+ for (long j = 0; j < length; j++, slot++) {
+ Object temp = getElem(cx, arg, j);
+ setElem(cx, result, slot, temp);
+ }
+ } else {
+ setElem(cx, result, slot++, args[i]);
+ }
+ }
+ return result;
+ }
+
+ private Scriptable js_slice(Context cx, Scriptable thisObj,
+ Object[] args)
+ {
+ Scriptable scope = getTopLevelScope(this);
+ Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
+ long length = getLengthProperty(cx, thisObj);
+
+ long begin, end;
+ if (args.length == 0) {
+ begin = 0;
+ end = length;
+ } else {
+ begin = toSliceIndex(ScriptRuntime.toInteger(args[0]), length);
+ if (args.length == 1) {
+ end = length;
+ } else {
+ end = toSliceIndex(ScriptRuntime.toInteger(args[1]), length);
+ }
+ }
+
+ for (long slot = begin; slot < end; slot++) {
+ Object temp = getElem(cx, thisObj, slot);
+ setElem(cx, result, slot - begin, temp);
+ }
+
+ return result;
+ }
+
+ private static long toSliceIndex(double value, long length) {
+ long result;
+ if (value < 0.0) {
+ if (value + length < 0.0) {
+ result = 0;
+ } else {
+ result = (long)(value + length);
+ }
+ } else if (value > length) {
+ result = length;
+ } else {
+ result = (long)value;
+ }
+ return result;
+ }
+
+ /**
+ * Implements the methods "indexOf" and "lastIndexOf".
+ */
+ private Object indexOfHelper(Context cx, Scriptable thisObj,
+ Object[] args, boolean isLast)
+ {
+ Object compareTo = args.length > 0 ? args[0] : Undefined.instance;
+ long length = getLengthProperty(cx, thisObj);
+ long start;
+ if (isLast) {
+ // lastIndexOf
+ /*
+ * From http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:lastIndexOf
+ * The index at which to start searching backwards. Defaults to the
+ * array's length, i.e. the whole array will be searched. If the
+ * index is greater than or equal to the length of the array, the
+ * whole array will be searched. If negative, it is taken as the
+ * offset from the end of the array. Note that even when the index
+ * is negative, the array is still searched from back to front. If
+ * the calculated index is less than 0, -1 is returned, i.e. the
+ * array will not be searched.
+ */
+ if (args.length < 2) {
+ // default
+ start = length-1;
+ } else {
+ start = ScriptRuntime.toInt32(ScriptRuntime.toNumber(args[1]));
+ if (start >= length)
+ start = length-1;
+ else if (start < 0)
+ start += length;
+ // Note that start may be negative, but that's okay
+ // as the result of -1 will fall out from the code below
+ }
+ } else {
+ // indexOf
+ /*
+ * From http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf
+ * The index at which to begin the search. Defaults to 0, i.e. the
+ * whole array will be searched. If the index is greater than or
+ * equal to the length of the array, -1 is returned, i.e. the array
+ * will not be searched. If negative, it is taken as the offset from
+ * the end of the array. Note that even when the index is negative,
+ * the array is still searched from front to back. If the calculated
+ * index is less than 0, the whole array will be searched.
+ */
+ if (args.length < 2) {
+ // default
+ start = 0;
+ } else {
+ start = ScriptRuntime.toInt32(ScriptRuntime.toNumber(args[1]));
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ // Note that start may be > length-1, but that's okay
+ // as the result of -1 will fall out from the code below
+ }
+ }
+ if (thisObj instanceof NativeArray) {
+ NativeArray na = (NativeArray) thisObj;
+ if (na.denseOnly) {
+ if (isLast) {
+ for (int i=(int)start; i >= 0; i--) {
+ if (na.dense[i] != Scriptable.NOT_FOUND &&
+ ScriptRuntime.shallowEq(na.dense[i], compareTo))
+ {
+ return new Long(i);
+ }
+ }
+ } else {
+ for (int i=(int)start; i < length; i++) {
+ if (na.dense[i] != Scriptable.NOT_FOUND &&
+ ScriptRuntime.shallowEq(na.dense[i], compareTo))
+ {
+ return new Long(i);
+ }
+ }
+ }
+ return NEGATIVE_ONE;
+ }
+ }
+ if (isLast) {
+ for (long i=start; i >= 0; i--) {
+ if (ScriptRuntime.shallowEq(getElem(cx, thisObj, i), compareTo)) {
+ return new Long(i);
+ }
+ }
+ } else {
+ for (long i=start; i < length; i++) {
+ if (ScriptRuntime.shallowEq(getElem(cx, thisObj, i), compareTo)) {
+ return new Long(i);
+ }
+ }
+ }
+ return NEGATIVE_ONE;
+ }
+
+ /**
+ * Implements the methods "every", "filter", "forEach", "map", and "some".
+ */
+ private Object iterativeMethod(Context cx, int id, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ Object callbackArg = args.length > 0 ? args[0] : Undefined.instance;
+ if (callbackArg == null || !(callbackArg instanceof Function)) {
+ throw ScriptRuntime.notFunctionError(
+ ScriptRuntime.toString(callbackArg));
+ }
+ Function f = (Function) callbackArg;
+ Scriptable parent = ScriptableObject.getTopLevelScope(f);
+ Scriptable thisArg;
+ if (args.length < 2 || args[1] == null || args[1] == Undefined.instance)
+ {
+ thisArg = parent;
+ } else {
+ thisArg = ScriptRuntime.toObject(cx, scope, args[1]);
+ }
+ long length = getLengthProperty(cx, thisObj);
+ Scriptable array = ScriptRuntime.newObject(cx, scope, "Array", null);
+ long j=0;
+ for (long i=0; i < length; i++) {
+ Object[] innerArgs = new Object[3];
+ Object elem = (i > Integer.MAX_VALUE)
+ ? ScriptableObject.getProperty(thisObj, Long.toString(i))
+ : ScriptableObject.getProperty(thisObj, (int)i);
+ if (elem == Scriptable.NOT_FOUND) {
+ continue;
+ }
+ innerArgs[0] = elem;
+ innerArgs[1] = new Long(i);
+ innerArgs[2] = thisObj;
+ Object result = f.call(cx, parent, thisArg, innerArgs);
+ switch (id) {
+ case Id_every:
+ if (!ScriptRuntime.toBoolean(result))
+ return Boolean.FALSE;
+ break;
+ case Id_filter:
+ if (ScriptRuntime.toBoolean(result))
+ setElem(cx, array, j++, innerArgs[0]);
+ break;
+ case Id_forEach:
+ break;
+ case Id_map:
+ setElem(cx, array, i, result);
+ break;
+ case Id_some:
+ if (ScriptRuntime.toBoolean(result))
+ return Boolean.TRUE;
+ break;
+ }
+ }
+ switch (id) {
+ case Id_every:
+ return Boolean.TRUE;
+ case Id_filter:
+ case Id_map:
+ return array;
+ case Id_some:
+ return Boolean.FALSE;
+ case Id_forEach:
+ default:
+ return Undefined.instance;
+ }
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2005-09-26 15:47:42 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 3: c=s.charAt(0);
+ if (c=='m') { if (s.charAt(2)=='p' && s.charAt(1)=='a') {id=Id_map; break L0;} }
+ else if (c=='p') { if (s.charAt(2)=='p' && s.charAt(1)=='o') {id=Id_pop; break L0;} }
+ break L;
+ case 4: switch (s.charAt(2)) {
+ case 'i': X="join";id=Id_join; break L;
+ case 'm': X="some";id=Id_some; break L;
+ case 'r': X="sort";id=Id_sort; break L;
+ case 's': X="push";id=Id_push; break L;
+ } break L;
+ case 5: c=s.charAt(1);
+ if (c=='h') { X="shift";id=Id_shift; }
+ else if (c=='l') { X="slice";id=Id_slice; }
+ else if (c=='v') { X="every";id=Id_every; }
+ break L;
+ case 6: c=s.charAt(0);
+ if (c=='c') { X="concat";id=Id_concat; }
+ else if (c=='f') { X="filter";id=Id_filter; }
+ else if (c=='s') { X="splice";id=Id_splice; }
+ break L;
+ case 7: switch (s.charAt(0)) {
+ case 'f': X="forEach";id=Id_forEach; break L;
+ case 'i': X="indexOf";id=Id_indexOf; break L;
+ case 'r': X="reverse";id=Id_reverse; break L;
+ case 'u': X="unshift";id=Id_unshift; break L;
+ } break L;
+ case 8: c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ break L;
+ case 11: c=s.charAt(0);
+ if (c=='c') { X="constructor";id=Id_constructor; }
+ else if (c=='l') { X="lastIndexOf";id=Id_lastIndexOf; }
+ break L;
+ case 14: X="toLocaleString";id=Id_toLocaleString; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toLocaleString = 3,
+ Id_toSource = 4,
+ Id_join = 5,
+ Id_reverse = 6,
+ Id_sort = 7,
+ Id_push = 8,
+ Id_pop = 9,
+ Id_shift = 10,
+ Id_unshift = 11,
+ Id_splice = 12,
+ Id_concat = 13,
+ Id_slice = 14,
+ Id_indexOf = 15,
+ Id_lastIndexOf = 16,
+ Id_every = 17,
+ Id_filter = 18,
+ Id_forEach = 19,
+ Id_map = 20,
+ Id_some = 21,
+
+ MAX_PROTOTYPE_ID = 21;
+
+// #/string_id_map#
+
+ private static final int
+ ConstructorId_join = -Id_join,
+ ConstructorId_reverse = -Id_reverse,
+ ConstructorId_sort = -Id_sort,
+ ConstructorId_push = -Id_push,
+ ConstructorId_pop = -Id_pop,
+ ConstructorId_shift = -Id_shift,
+ ConstructorId_unshift = -Id_unshift,
+ ConstructorId_splice = -Id_splice,
+ ConstructorId_concat = -Id_concat,
+ ConstructorId_slice = -Id_slice,
+ ConstructorId_indexOf = -Id_indexOf,
+ ConstructorId_lastIndexOf = -Id_lastIndexOf,
+ ConstructorId_every = -Id_every,
+ ConstructorId_filter = -Id_filter,
+ ConstructorId_forEach = -Id_forEach,
+ ConstructorId_map = -Id_map,
+ ConstructorId_some = -Id_some;
+
+ /**
+ * Internal representation of the JavaScript array's length property.
+ */
+ private long length;
+
+ /**
+ * Fast storage for dense arrays. Sparse arrays will use the superclass's
+ * hashtable storage scheme.
+ */
+ private Object[] dense;
+
+ /**
+ * True if all numeric properties are stored in <code>dense</code>.
+ */
+ private boolean denseOnly;
+
+ /**
+ * The maximum size of <code>dense</code> that will be allocated initially.
+ */
+ private static int maximumInitialCapacity = 10000;
+
+ /**
+ * The default capacity for <code>dense</code>.
+ */
+ private static final int DEFAULT_INITIAL_CAPACITY = 10;
+
+ /**
+ * The factor to grow <code>dense</code> by.
+ */
+ private static final double GROW_FACTOR = 1.5;
+ private static final int MAX_PRE_GROW_SIZE = (int)(Integer.MAX_VALUE / GROW_FACTOR);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java
new file mode 100644
index 0000000..b6a106a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeBoolean.java
@@ -0,0 +1,170 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the Boolean native object.
+ * See ECMA 15.6.
+ * @author Norris Boyd
+ */
+final class NativeBoolean extends IdScriptableObject
+{
+ static final long serialVersionUID = -3716996899943880933L;
+
+ private static final Object BOOLEAN_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeBoolean obj = new NativeBoolean(false);
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ private NativeBoolean(boolean b)
+ {
+ booleanValue = b;
+ }
+
+ public String getClassName()
+ {
+ return "Boolean";
+ }
+
+ public Object getDefaultValue(Class typeHint) {
+ // This is actually non-ECMA, but will be proposed
+ // as a change in round 2.
+ if (typeHint == ScriptRuntime.BooleanClass)
+ return ScriptRuntime.wrapBoolean(booleanValue);
+ return super.getDefaultValue(typeHint);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(BOOLEAN_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(BOOLEAN_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+
+ if (id == Id_constructor) {
+ boolean b;
+ if (args.length == 0) {
+ b = false;
+ } else {
+ b = args[0] instanceof ScriptableObject &&
+ ((ScriptableObject) args[0]).avoidObjectDetection()
+ ? true
+ : ScriptRuntime.toBoolean(args[0]);
+ }
+ if (thisObj == null) {
+ // new Boolean(val) creates a new boolean object.
+ return new NativeBoolean(b);
+ }
+ // Boolean(val) converts val to a boolean.
+ return ScriptRuntime.wrapBoolean(b);
+ }
+
+ // The rest of Boolean.prototype methods require thisObj to be Boolean
+
+ if (!(thisObj instanceof NativeBoolean))
+ throw incompatibleCallError(f);
+ boolean value = ((NativeBoolean)thisObj).booleanValue;
+
+ switch (id) {
+
+ case Id_toString:
+ return value ? "true" : "false";
+
+ case Id_toSource:
+ return value ? "(new Boolean(true))" : "(new Boolean(false))";
+
+ case Id_valueOf:
+ return ScriptRuntime.wrapBoolean(value);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:31 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==7) { X="valueOf";id=Id_valueOf; }
+ else if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ Id_valueOf = 4,
+ MAX_PROTOTYPE_ID = 4;
+
+// #/string_id_map#
+
+ private boolean booleanValue;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java
new file mode 100644
index 0000000..b196ac3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeCall.java
@@ -0,0 +1,154 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Bob Jervis
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the activation object.
+ *
+ * See ECMA 10.1.6
+ *
+ * @see org.mozilla.javascript.Arguments
+ * @author Norris Boyd
+ */
+public final class NativeCall extends IdScriptableObject
+{
+ static final long serialVersionUID = -7471457301304454454L;
+
+ private static final Object CALL_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeCall obj = new NativeCall();
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ NativeCall() { }
+
+ NativeCall(NativeFunction function, Scriptable scope, Object[] args)
+ {
+ this.function = function;
+
+ setParentScope(scope);
+ // leave prototype null
+
+ this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args;
+
+ // initialize values of arguments
+ int paramAndVarCount = function.getParamAndVarCount();
+ int paramCount = function.getParamCount();
+ if (paramAndVarCount != 0) {
+ for (int i = 0; i < paramCount; ++i) {
+ String name = function.getParamOrVarName(i);
+ Object val = i < args.length ? args[i]
+ : Undefined.instance;
+ defineProperty(name, val, PERMANENT);
+ }
+ }
+
+ // initialize "arguments" property but only if it was not overridden by
+ // the parameter with the same name
+ if (!super.has("arguments", this)) {
+ defineProperty("arguments", new Arguments(this), PERMANENT);
+ }
+
+ if (paramAndVarCount != 0) {
+ for (int i = paramCount; i < paramAndVarCount; ++i) {
+ String name = function.getParamOrVarName(i);
+ if (!super.has(name, this)) {
+ if (function.getParamOrVarConst(i))
+ defineProperty(name, Undefined.instance, CONST);
+ else
+ defineProperty(name, Undefined.instance, PERMANENT);
+ }
+ }
+ }
+ }
+
+ public String getClassName()
+ {
+ return "Call";
+ }
+
+ protected int findPrototypeId(String s)
+ {
+ return s.equals("constructor") ? Id_constructor : 0;
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ if (id == Id_constructor) {
+ arity=1; s="constructor";
+ } else {
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(CALL_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(CALL_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ if (id == Id_constructor) {
+ if (thisObj != null) {
+ throw Context.reportRuntimeError1("msg.only.from.new", "Call");
+ }
+ ScriptRuntime.checkDeprecated(cx, "Call");
+ NativeCall result = new NativeCall();
+ result.setPrototype(getObjectPrototype(scope));
+ return result;
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static final int
+ Id_constructor = 1,
+ MAX_PROTOTYPE_ID = 1;
+
+ NativeFunction function;
+ Object[] originalArgs;
+
+ transient NativeCall parentActivationCall;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java
new file mode 100644
index 0000000..75d41ab
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeDate.java
@@ -0,0 +1,1604 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Peter Annema
+ * Norris Boyd
+ * Mike McCabe
+ * Ilya Frank
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Date;
+import java.text.DateFormat;
+
+/**
+ * This class implements the Date native object.
+ * See ECMA 15.9.
+ * @author Mike McCabe
+ */
+final class NativeDate extends IdScriptableObject
+{
+ static final long serialVersionUID = -8307438915861678966L;
+
+ private static final Object DATE_TAG = new Object();
+
+ private static final String js_NaN_date_str = "Invalid Date";
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeDate obj = new NativeDate();
+ // Set the value of the prototype Date to NaN ('invalid date');
+ obj.date = ScriptRuntime.NaN;
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ private NativeDate()
+ {
+ if (thisTimeZone == null) {
+ // j.u.TimeZone is synchronized, so setting class statics from it
+ // should be OK.
+ thisTimeZone = java.util.TimeZone.getDefault();
+ LocalTZA = thisTimeZone.getRawOffset();
+ }
+ }
+
+ public String getClassName()
+ {
+ return "Date";
+ }
+
+ public Object getDefaultValue(Class typeHint)
+ {
+ if (typeHint == null)
+ typeHint = ScriptRuntime.StringClass;
+ return super.getDefaultValue(typeHint);
+ }
+
+ double getJSTimeValue()
+ {
+ return date;
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_now,
+ "now", 0);
+ addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_parse,
+ "parse", 1);
+ addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_UTC,
+ "UTC", 1);
+ super.fillConstructorProperties(ctor);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toTimeString: arity=0; s="toTimeString"; break;
+ case Id_toDateString: arity=0; s="toDateString"; break;
+ case Id_toLocaleString: arity=0; s="toLocaleString"; break;
+ case Id_toLocaleTimeString: arity=0; s="toLocaleTimeString"; break;
+ case Id_toLocaleDateString: arity=0; s="toLocaleDateString"; break;
+ case Id_toUTCString: arity=0; s="toUTCString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+ case Id_getTime: arity=0; s="getTime"; break;
+ case Id_getYear: arity=0; s="getYear"; break;
+ case Id_getFullYear: arity=0; s="getFullYear"; break;
+ case Id_getUTCFullYear: arity=0; s="getUTCFullYear"; break;
+ case Id_getMonth: arity=0; s="getMonth"; break;
+ case Id_getUTCMonth: arity=0; s="getUTCMonth"; break;
+ case Id_getDate: arity=0; s="getDate"; break;
+ case Id_getUTCDate: arity=0; s="getUTCDate"; break;
+ case Id_getDay: arity=0; s="getDay"; break;
+ case Id_getUTCDay: arity=0; s="getUTCDay"; break;
+ case Id_getHours: arity=0; s="getHours"; break;
+ case Id_getUTCHours: arity=0; s="getUTCHours"; break;
+ case Id_getMinutes: arity=0; s="getMinutes"; break;
+ case Id_getUTCMinutes: arity=0; s="getUTCMinutes"; break;
+ case Id_getSeconds: arity=0; s="getSeconds"; break;
+ case Id_getUTCSeconds: arity=0; s="getUTCSeconds"; break;
+ case Id_getMilliseconds: arity=0; s="getMilliseconds"; break;
+ case Id_getUTCMilliseconds: arity=0; s="getUTCMilliseconds"; break;
+ case Id_getTimezoneOffset: arity=0; s="getTimezoneOffset"; break;
+ case Id_setTime: arity=1; s="setTime"; break;
+ case Id_setMilliseconds: arity=1; s="setMilliseconds"; break;
+ case Id_setUTCMilliseconds: arity=1; s="setUTCMilliseconds"; break;
+ case Id_setSeconds: arity=2; s="setSeconds"; break;
+ case Id_setUTCSeconds: arity=2; s="setUTCSeconds"; break;
+ case Id_setMinutes: arity=3; s="setMinutes"; break;
+ case Id_setUTCMinutes: arity=3; s="setUTCMinutes"; break;
+ case Id_setHours: arity=4; s="setHours"; break;
+ case Id_setUTCHours: arity=4; s="setUTCHours"; break;
+ case Id_setDate: arity=1; s="setDate"; break;
+ case Id_setUTCDate: arity=1; s="setUTCDate"; break;
+ case Id_setMonth: arity=2; s="setMonth"; break;
+ case Id_setUTCMonth: arity=2; s="setUTCMonth"; break;
+ case Id_setFullYear: arity=3; s="setFullYear"; break;
+ case Id_setUTCFullYear: arity=3; s="setUTCFullYear"; break;
+ case Id_setYear: arity=1; s="setYear"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(DATE_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(DATE_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case ConstructorId_now:
+ return ScriptRuntime.wrapNumber(now());
+
+ case ConstructorId_parse:
+ {
+ String dataStr = ScriptRuntime.toString(args, 0);
+ return ScriptRuntime.wrapNumber(date_parseString(dataStr));
+ }
+
+ case ConstructorId_UTC:
+ return ScriptRuntime.wrapNumber(jsStaticFunction_UTC(args));
+
+ case Id_constructor:
+ {
+ // if called as a function, just return a string
+ // representing the current time.
+ if (thisObj != null)
+ return date_format(now(), Id_toString);
+ return jsConstructor(args);
+ }
+ }
+
+ // The rest of Date.prototype methods require thisObj to be Date
+
+ if (!(thisObj instanceof NativeDate))
+ throw incompatibleCallError(f);
+ NativeDate realThis = (NativeDate)thisObj;
+ double t = realThis.date;
+
+ switch (id) {
+
+ case Id_toString:
+ case Id_toTimeString:
+ case Id_toDateString:
+ if (t == t) {
+ return date_format(t, id);
+ }
+ return js_NaN_date_str;
+
+ case Id_toLocaleString:
+ case Id_toLocaleTimeString:
+ case Id_toLocaleDateString:
+ if (t == t) {
+ return toLocale_helper(t, id);
+ }
+ return js_NaN_date_str;
+
+ case Id_toUTCString:
+ if (t == t) {
+ return js_toUTCString(t);
+ }
+ return js_NaN_date_str;
+
+ case Id_toSource:
+ return "(new Date("+ScriptRuntime.toString(t)+"))";
+
+ case Id_valueOf:
+ case Id_getTime:
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getYear:
+ case Id_getFullYear:
+ case Id_getUTCFullYear:
+ if (t == t) {
+ if (id != Id_getUTCFullYear) t = LocalTime(t);
+ t = YearFromTime(t);
+ if (id == Id_getYear) {
+ if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) {
+ if (1900 <= t && t < 2000) {
+ t -= 1900;
+ }
+ } else {
+ t -= 1900;
+ }
+ }
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getMonth:
+ case Id_getUTCMonth:
+ if (t == t) {
+ if (id == Id_getMonth) t = LocalTime(t);
+ t = MonthFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getDate:
+ case Id_getUTCDate:
+ if (t == t) {
+ if (id == Id_getDate) t = LocalTime(t);
+ t = DateFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getDay:
+ case Id_getUTCDay:
+ if (t == t) {
+ if (id == Id_getDay) t = LocalTime(t);
+ t = WeekDay(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getHours:
+ case Id_getUTCHours:
+ if (t == t) {
+ if (id == Id_getHours) t = LocalTime(t);
+ t = HourFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getMinutes:
+ case Id_getUTCMinutes:
+ if (t == t) {
+ if (id == Id_getMinutes) t = LocalTime(t);
+ t = MinFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getSeconds:
+ case Id_getUTCSeconds:
+ if (t == t) {
+ if (id == Id_getSeconds) t = LocalTime(t);
+ t = SecFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getMilliseconds:
+ case Id_getUTCMilliseconds:
+ if (t == t) {
+ if (id == Id_getMilliseconds) t = LocalTime(t);
+ t = msFromTime(t);
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_getTimezoneOffset:
+ if (t == t) {
+ t = (t - LocalTime(t)) / msPerMinute;
+ }
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_setTime:
+ t = TimeClip(ScriptRuntime.toNumber(args, 0));
+ realThis.date = t;
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_setMilliseconds:
+ case Id_setUTCMilliseconds:
+ case Id_setSeconds:
+ case Id_setUTCSeconds:
+ case Id_setMinutes:
+ case Id_setUTCMinutes:
+ case Id_setHours:
+ case Id_setUTCHours:
+ t = makeTime(t, args, id);
+ realThis.date = t;
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_setDate:
+ case Id_setUTCDate:
+ case Id_setMonth:
+ case Id_setUTCMonth:
+ case Id_setFullYear:
+ case Id_setUTCFullYear:
+ t = makeDate(t, args, id);
+ realThis.date = t;
+ return ScriptRuntime.wrapNumber(t);
+
+ case Id_setYear:
+ {
+ double year = ScriptRuntime.toNumber(args, 0);
+
+ if (year != year || Double.isInfinite(year)) {
+ t = ScriptRuntime.NaN;
+ } else {
+ if (t != t) {
+ t = 0;
+ } else {
+ t = LocalTime(t);
+ }
+
+ if (year >= 0 && year <= 99)
+ year += 1900;
+
+ double day = MakeDay(year, MonthFromTime(t),
+ DateFromTime(t));
+ t = MakeDate(day, TimeWithinDay(t));
+ t = internalUTC(t);
+ t = TimeClip(t);
+ }
+ }
+ realThis.date = t;
+ return ScriptRuntime.wrapNumber(t);
+
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ }
+
+ /* ECMA helper functions */
+
+ private static final double HalfTimeDomain = 8.64e15;
+ private static final double HoursPerDay = 24.0;
+ private static final double MinutesPerHour = 60.0;
+ private static final double SecondsPerMinute = 60.0;
+ private static final double msPerSecond = 1000.0;
+ private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour);
+ private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute);
+ private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute);
+ private static final double msPerDay = (SecondsPerDay * msPerSecond);
+ private static final double msPerHour = (SecondsPerHour * msPerSecond);
+ private static final double msPerMinute = (SecondsPerMinute * msPerSecond);
+
+ private static double Day(double t)
+ {
+ return Math.floor(t / msPerDay);
+ }
+
+ private static double TimeWithinDay(double t)
+ {
+ double result;
+ result = t % msPerDay;
+ if (result < 0)
+ result += msPerDay;
+ return result;
+ }
+
+ private static boolean IsLeapYear(int year)
+ {
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+ }
+
+ /* math here has to be f.p, because we need
+ * floor((1968 - 1969) / 4) == -1
+ */
+ private static double DayFromYear(double y)
+ {
+ return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0)
+ - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0)));
+ }
+
+ private static double TimeFromYear(double y)
+ {
+ return DayFromYear(y) * msPerDay;
+ }
+
+ private static int YearFromTime(double t)
+ {
+ int lo = (int) Math.floor((t / msPerDay) / 366) + 1970;
+ int hi = (int) Math.floor((t / msPerDay) / 365) + 1970;
+ int mid;
+
+ /* above doesn't work for negative dates... */
+ if (hi < lo) {
+ int temp = lo;
+ lo = hi;
+ hi = temp;
+ }
+
+ /* Use a simple binary search algorithm to find the right
+ year. This seems like brute force... but the computation
+ of hi and lo years above lands within one year of the
+ correct answer for years within a thousand years of
+ 1970; the loop below only requires six iterations
+ for year 270000. */
+ while (hi > lo) {
+ mid = (hi + lo) / 2;
+ if (TimeFromYear(mid) > t) {
+ hi = mid - 1;
+ } else {
+ lo = mid + 1;
+ if (TimeFromYear(lo) > t) {
+ return mid;
+ }
+ }
+ }
+ return lo;
+ }
+
+ private static double DayFromMonth(int m, int year)
+ {
+ int day = m * 30;
+
+ if (m >= 7) { day += m / 2 - 1; }
+ else if (m >= 2) { day += (m - 1) / 2 - 1; }
+ else { day += m; }
+
+ if (m >= 2 && IsLeapYear(year)) { ++day; }
+
+ return day;
+ }
+
+ private static int MonthFromTime(double t)
+ {
+ int year = YearFromTime(t);
+ int d = (int)(Day(t) - DayFromYear(year));
+
+ d -= 31 + 28;
+ if (d < 0) {
+ return (d < -28) ? 0 : 1;
+ }
+
+ if (IsLeapYear(year)) {
+ if (d == 0)
+ return 1; // 29 February
+ --d;
+ }
+
+ // d: date count from 1 March
+ int estimate = d / 30; // approx number of month since March
+ int mstart;
+ switch (estimate) {
+ case 0: return 2;
+ case 1: mstart = 31; break;
+ case 2: mstart = 31+30; break;
+ case 3: mstart = 31+30+31; break;
+ case 4: mstart = 31+30+31+30; break;
+ case 5: mstart = 31+30+31+30+31; break;
+ case 6: mstart = 31+30+31+30+31+31; break;
+ case 7: mstart = 31+30+31+30+31+31+30; break;
+ case 8: mstart = 31+30+31+30+31+31+30+31; break;
+ case 9: mstart = 31+30+31+30+31+31+30+31+30; break;
+ case 10: return 11; //Late december
+ default: throw Kit.codeBug();
+ }
+ // if d < mstart then real month since March == estimate - 1
+ return (d >= mstart) ? estimate + 2 : estimate + 1;
+ }
+
+ private static int DateFromTime(double t)
+ {
+ int year = YearFromTime(t);
+ int d = (int)(Day(t) - DayFromYear(year));
+
+ d -= 31 + 28;
+ if (d < 0) {
+ return (d < -28) ? d + 31 + 28 + 1 : d + 28 + 1;
+ }
+
+ if (IsLeapYear(year)) {
+ if (d == 0)
+ return 29; // 29 February
+ --d;
+ }
+
+ // d: date count from 1 March
+ int mdays, mstart;
+ switch (d / 30) { // approx number of month since March
+ case 0: return d + 1;
+ case 1: mdays = 31; mstart = 31; break;
+ case 2: mdays = 30; mstart = 31+30; break;
+ case 3: mdays = 31; mstart = 31+30+31; break;
+ case 4: mdays = 30; mstart = 31+30+31+30; break;
+ case 5: mdays = 31; mstart = 31+30+31+30+31; break;
+ case 6: mdays = 31; mstart = 31+30+31+30+31+31; break;
+ case 7: mdays = 30; mstart = 31+30+31+30+31+31+30; break;
+ case 8: mdays = 31; mstart = 31+30+31+30+31+31+30+31; break;
+ case 9: mdays = 30; mstart = 31+30+31+30+31+31+30+31+30; break;
+ case 10:
+ return d - (31+30+31+30+31+31+30+31+30) + 1; //Late december
+ default: throw Kit.codeBug();
+ }
+ d -= mstart;
+ if (d < 0) {
+ // wrong estimate: sfhift to previous month
+ d += mdays;
+ }
+ return d + 1;
+ }
+
+ private static int WeekDay(double t)
+ {
+ double result;
+ result = Day(t) + 4;
+ result = result % 7;
+ if (result < 0)
+ result += 7;
+ return (int) result;
+ }
+
+ private static double now()
+ {
+ return System.currentTimeMillis();
+ }
+
+ /* Should be possible to determine the need for this dynamically
+ * if we go with the workaround... I'm not using it now, because I
+ * can't think of any clean way to make toLocaleString() and the
+ * time zone (comment) in toString match the generated string
+ * values. Currently it's wrong-but-consistent in all but the
+ * most recent betas of the JRE - seems to work in 1.1.7.
+ */
+ private final static boolean TZO_WORKAROUND = false;
+ private static double DaylightSavingTA(double t)
+ {
+ // Another workaround! The JRE doesn't seem to know about DST
+ // before year 1 AD, so we map to equivalent dates for the
+ // purposes of finding dst. To be safe, we do this for years
+ // outside 1970-2038.
+ if (t < 0.0 || t > 2145916800000.0) {
+ int year = EquivalentYear(YearFromTime(t));
+ double day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
+ t = MakeDate(day, TimeWithinDay(t));
+ }
+ if (!TZO_WORKAROUND) {
+ Date date = new Date((long) t);
+ if (thisTimeZone.inDaylightTime(date))
+ return msPerHour;
+ else
+ return 0;
+ } else {
+ /* Use getOffset if inDaylightTime() is broken, because it
+ * seems to work acceptably. We don't switch over to it
+ * entirely, because it requires (expensive) exploded date arguments,
+ * and the api makes it impossible to handle dst
+ * changeovers cleanly.
+ */
+
+ // Hardcode the assumption that the changeover always
+ // happens at 2:00 AM:
+ t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0);
+
+ int year = YearFromTime(t);
+ double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0,
+ year,
+ MonthFromTime(t),
+ DateFromTime(t),
+ WeekDay(t),
+ (int)TimeWithinDay(t));
+
+ if ((offset - LocalTZA) != 0)
+ return msPerHour;
+ else
+ return 0;
+ // return offset - LocalTZA;
+ }
+ }
+
+ /*
+ * Find a year for which any given date will fall on the same weekday.
+ *
+ * This function should be used with caution when used other than
+ * for determining DST; it hasn't been proven not to produce an
+ * incorrect year for times near year boundaries.
+ */
+ private static int EquivalentYear(int year)
+ {
+ int day = (int) DayFromYear(year) + 4;
+ day = day % 7;
+ if (day < 0)
+ day += 7;
+ // Years and leap years on which Jan 1 is a Sunday, Monday, etc.
+ if (IsLeapYear(year)) {
+ switch (day) {
+ case 0: return 1984;
+ case 1: return 1996;
+ case 2: return 1980;
+ case 3: return 1992;
+ case 4: return 1976;
+ case 5: return 1988;
+ case 6: return 1972;
+ }
+ } else {
+ switch (day) {
+ case 0: return 1978;
+ case 1: return 1973;
+ case 2: return 1974;
+ case 3: return 1975;
+ case 4: return 1981;
+ case 5: return 1971;
+ case 6: return 1977;
+ }
+ }
+ // Unreachable
+ throw Kit.codeBug();
+ }
+
+ private static double LocalTime(double t)
+ {
+ return t + LocalTZA + DaylightSavingTA(t);
+ }
+
+ private static double internalUTC(double t)
+ {
+ return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
+ }
+
+ private static int HourFromTime(double t)
+ {
+ double result;
+ result = Math.floor(t / msPerHour) % HoursPerDay;
+ if (result < 0)
+ result += HoursPerDay;
+ return (int) result;
+ }
+
+ private static int MinFromTime(double t)
+ {
+ double result;
+ result = Math.floor(t / msPerMinute) % MinutesPerHour;
+ if (result < 0)
+ result += MinutesPerHour;
+ return (int) result;
+ }
+
+ private static int SecFromTime(double t)
+ {
+ double result;
+ result = Math.floor(t / msPerSecond) % SecondsPerMinute;
+ if (result < 0)
+ result += SecondsPerMinute;
+ return (int) result;
+ }
+
+ private static int msFromTime(double t)
+ {
+ double result;
+ result = t % msPerSecond;
+ if (result < 0)
+ result += msPerSecond;
+ return (int) result;
+ }
+
+ private static double MakeTime(double hour, double min,
+ double sec, double ms)
+ {
+ return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec)
+ * msPerSecond + ms;
+ }
+
+ private static double MakeDay(double year, double month, double date)
+ {
+ year += Math.floor(month / 12);
+
+ month = month % 12;
+ if (month < 0)
+ month += 12;
+
+ double yearday = Math.floor(TimeFromYear(year) / msPerDay);
+ double monthday = DayFromMonth((int)month, (int)year);
+
+ return yearday + monthday + date - 1;
+ }
+
+ private static double MakeDate(double day, double time)
+ {
+ return day * msPerDay + time;
+ }
+
+ private static double TimeClip(double d)
+ {
+ if (d != d ||
+ d == Double.POSITIVE_INFINITY ||
+ d == Double.NEGATIVE_INFINITY ||
+ Math.abs(d) > HalfTimeDomain)
+ {
+ return ScriptRuntime.NaN;
+ }
+ if (d > 0.0)
+ return Math.floor(d + 0.);
+ else
+ return Math.ceil(d + 0.);
+ }
+
+ /* end of ECMA helper functions */
+
+ /* find UTC time from given date... no 1900 correction! */
+ private static double date_msecFromDate(double year, double mon,
+ double mday, double hour,
+ double min, double sec,
+ double msec)
+ {
+ double day;
+ double time;
+ double result;
+
+ day = MakeDay(year, mon, mday);
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(day, time);
+ return result;
+ }
+
+ /* compute the time in msec (unclipped) from the given args */
+ private static final int MAXARGS = 7;
+ private static double date_msecFromArgs(Object[] args)
+ {
+ double array[] = new double[MAXARGS];
+ int loop;
+ double d;
+
+ for (loop = 0; loop < MAXARGS; loop++) {
+ if (loop < args.length) {
+ d = ScriptRuntime.toNumber(args[loop]);
+ if (d != d || Double.isInfinite(d)) {
+ return ScriptRuntime.NaN;
+ }
+ array[loop] = ScriptRuntime.toInteger(args[loop]);
+ } else {
+ if (loop == 2) {
+ array[loop] = 1; /* Default the date argument to 1. */
+ } else {
+ array[loop] = 0;
+ }
+ }
+ }
+
+ /* adjust 2-digit years into the 20th century */
+ if (array[0] >= 0 && array[0] <= 99)
+ array[0] += 1900;
+
+ return date_msecFromDate(array[0], array[1], array[2],
+ array[3], array[4], array[5], array[6]);
+ }
+
+ private static double jsStaticFunction_UTC(Object[] args)
+ {
+ return TimeClip(date_msecFromArgs(args));
+ }
+
+ private static double date_parseString(String s)
+ {
+ int year = -1;
+ int mon = -1;
+ int mday = -1;
+ int hour = -1;
+ int min = -1;
+ int sec = -1;
+ char c = 0;
+ char si = 0;
+ int i = 0;
+ int n = -1;
+ double tzoffset = -1;
+ char prevc = 0;
+ int limit = 0;
+ boolean seenplusminus = false;
+
+ limit = s.length();
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c <= ' ' || c == ',' || c == '-') {
+ if (i < limit) {
+ si = s.charAt(i);
+ if (c == '-' && '0' <= si && si <= '9') {
+ prevc = c;
+ }
+ }
+ continue;
+ }
+ if (c == '(') { /* comments) */
+ int depth = 1;
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c == '(')
+ depth++;
+ else if (c == ')')
+ if (--depth <= 0)
+ break;
+ }
+ continue;
+ }
+ if ('0' <= c && c <= '9') {
+ n = c - '0';
+ while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
+ n = n * 10 + c - '0';
+ i++;
+ }
+
+ /* allow TZA before the year, so
+ * 'Wed Nov 05 21:49:11 GMT-0800 1997'
+ * works */
+
+ /* uses of seenplusminus allow : in TZA, so Java
+ * no-timezone style of GMT+4:30 works
+ */
+ if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
+ /* make ':' case below change tzoffset */
+ seenplusminus = true;
+
+ /* offset */
+ if (n < 24)
+ n = n * 60; /* EG. "GMT-3" */
+ else
+ n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
+ if (prevc == '+') /* plus means east of GMT */
+ n = -n;
+ if (tzoffset != 0 && tzoffset != -1)
+ return ScriptRuntime.NaN;
+ tzoffset = n;
+ } else if (n >= 70 ||
+ (prevc == '/' && mon >= 0 && mday >= 0
+ && year < 0))
+ {
+ if (year >= 0)
+ return ScriptRuntime.NaN;
+ else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
+ year = n < 100 ? n + 1900 : n;
+ else
+ return ScriptRuntime.NaN;
+ } else if (c == ':') {
+ if (hour < 0)
+ hour = /*byte*/ n;
+ else if (min < 0)
+ min = /*byte*/ n;
+ else
+ return ScriptRuntime.NaN;
+ } else if (c == '/') {
+ if (mon < 0)
+ mon = /*byte*/ n-1;
+ else if (mday < 0)
+ mday = /*byte*/ n;
+ else
+ return ScriptRuntime.NaN;
+ } else if (i < limit && c != ',' && c > ' ' && c != '-') {
+ return ScriptRuntime.NaN;
+ } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
+ if (tzoffset < 0)
+ tzoffset -= n;
+ else
+ tzoffset += n;
+ } else if (hour >= 0 && min < 0) {
+ min = /*byte*/ n;
+ } else if (min >= 0 && sec < 0) {
+ sec = /*byte*/ n;
+ } else if (mday < 0) {
+ mday = /*byte*/ n;
+ } else {
+ return ScriptRuntime.NaN;
+ }
+ prevc = 0;
+ } else if (c == '/' || c == ':' || c == '+' || c == '-') {
+ prevc = c;
+ } else {
+ int st = i - 1;
+ while (i < limit) {
+ c = s.charAt(i);
+ if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
+ break;
+ i++;
+ }
+ int letterCount = i - st;
+ if (letterCount < 2)
+ return ScriptRuntime.NaN;
+ /*
+ * Use ported code from jsdate.c rather than the locale-specific
+ * date-parsing code from Java, to keep js and rhino consistent.
+ * Is this the right strategy?
+ */
+ String wtb = "am;pm;"
+ +"monday;tuesday;wednesday;thursday;friday;"
+ +"saturday;sunday;"
+ +"january;february;march;april;may;june;"
+ +"july;august;september;october;november;december;"
+ +"gmt;ut;utc;est;edt;cst;cdt;mst;mdt;pst;pdt;";
+ int index = 0;
+ for (int wtbOffset = 0; ;) {
+ int wtbNext = wtb.indexOf(';', wtbOffset);
+ if (wtbNext < 0)
+ return ScriptRuntime.NaN;
+ if (wtb.regionMatches(true, wtbOffset, s, st, letterCount))
+ break;
+ wtbOffset = wtbNext + 1;
+ ++index;
+ }
+ if (index < 2) {
+ /*
+ * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
+ * 12:30, instead of blindly adding 12 if PM.
+ */
+ if (hour > 12 || hour < 0) {
+ return ScriptRuntime.NaN;
+ } else if (index == 0) {
+ // AM
+ if (hour == 12)
+ hour = 0;
+ } else {
+ // PM
+ if (hour != 12)
+ hour += 12;
+ }
+ } else if ((index -= 2) < 7) {
+ // ignore week days
+ } else if ((index -= 7) < 12) {
+ // month
+ if (mon < 0) {
+ mon = index;
+ } else {
+ return ScriptRuntime.NaN;
+ }
+ } else {
+ index -= 12;
+ // timezones
+ switch (index) {
+ case 0 /* gmt */: tzoffset = 0; break;
+ case 1 /* ut */: tzoffset = 0; break;
+ case 2 /* utc */: tzoffset = 0; break;
+ case 3 /* est */: tzoffset = 5 * 60; break;
+ case 4 /* edt */: tzoffset = 4 * 60; break;
+ case 5 /* cst */: tzoffset = 6 * 60; break;
+ case 6 /* cdt */: tzoffset = 5 * 60; break;
+ case 7 /* mst */: tzoffset = 7 * 60; break;
+ case 8 /* mdt */: tzoffset = 6 * 60; break;
+ case 9 /* pst */: tzoffset = 8 * 60; break;
+ case 10 /* pdt */:tzoffset = 7 * 60; break;
+ default: Kit.codeBug();
+ }
+ }
+ }
+ }
+ if (year < 0 || mon < 0 || mday < 0)
+ return ScriptRuntime.NaN;
+ if (sec < 0)
+ sec = 0;
+ if (min < 0)
+ min = 0;
+ if (hour < 0)
+ hour = 0;
+
+ double msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+ if (tzoffset == -1) { /* no time zone specified, have to use local */
+ return internalUTC(msec);
+ } else {
+ return msec + tzoffset * msPerMinute;
+ }
+ }
+
+ private static String date_format(double t, int methodId)
+ {
+ StringBuffer result = new StringBuffer(60);
+ double local = LocalTime(t);
+
+ /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */
+ /* Tue Oct 31 2000 */
+ /* 09:41:40 GMT-0800 (PST) */
+
+ if (methodId != Id_toTimeString) {
+ appendWeekDayName(result, WeekDay(local));
+ result.append(' ');
+ appendMonthName(result, MonthFromTime(local));
+ result.append(' ');
+ append0PaddedUint(result, DateFromTime(local), 2);
+ result.append(' ');
+ int year = YearFromTime(local);
+ if (year < 0) {
+ result.append('-');
+ year = -year;
+ }
+ append0PaddedUint(result, year, 4);
+ if (methodId != Id_toDateString)
+ result.append(' ');
+ }
+
+ if (methodId != Id_toDateString) {
+ append0PaddedUint(result, HourFromTime(local), 2);
+ result.append(':');
+ append0PaddedUint(result, MinFromTime(local), 2);
+ result.append(':');
+ append0PaddedUint(result, SecFromTime(local), 2);
+
+ // offset from GMT in minutes. The offset includes daylight
+ // savings, if it applies.
+ int minutes = (int) Math.floor((LocalTZA + DaylightSavingTA(t))
+ / msPerMinute);
+ // map 510 minutes to 0830 hours
+ int offset = (minutes / 60) * 100 + minutes % 60;
+ if (offset > 0) {
+ result.append(" GMT+");
+ } else {
+ result.append(" GMT-");
+ offset = -offset;
+ }
+ append0PaddedUint(result, offset, 4);
+
+ if (timeZoneFormatter == null)
+ timeZoneFormatter = new java.text.SimpleDateFormat("zzz");
+
+ // Find an equivalent year before getting the timezone
+ // comment. See DaylightSavingTA.
+ if (t < 0.0 || t > 2145916800000.0) {
+ int equiv = EquivalentYear(YearFromTime(local));
+ double day = MakeDay(equiv, MonthFromTime(t), DateFromTime(t));
+ t = MakeDate(day, TimeWithinDay(t));
+ }
+ result.append(" (");
+ java.util.Date date = new Date((long) t);
+ synchronized (timeZoneFormatter) {
+ result.append(timeZoneFormatter.format(date));
+ }
+ result.append(')');
+ }
+ return result.toString();
+ }
+
+ /* the javascript constructor */
+ private static Object jsConstructor(Object[] args)
+ {
+ NativeDate obj = new NativeDate();
+
+ // if called as a constructor with no args,
+ // return a new Date with the current time.
+ if (args.length == 0) {
+ obj.date = now();
+ return obj;
+ }
+
+ // if called with just one arg -
+ if (args.length == 1) {
+ Object arg0 = args[0];
+ if (arg0 instanceof Scriptable)
+ arg0 = ((Scriptable) arg0).getDefaultValue(null);
+ double date;
+ if (arg0 instanceof String) {
+ // it's a string; parse it.
+ date = date_parseString((String)arg0);
+ } else {
+ // if it's not a string, use it as a millisecond date
+ date = ScriptRuntime.toNumber(arg0);
+ }
+ obj.date = TimeClip(date);
+ return obj;
+ }
+
+ double time = date_msecFromArgs(args);
+
+ if (!Double.isNaN(time) && !Double.isInfinite(time))
+ time = TimeClip(internalUTC(time));
+
+ obj.date = time;
+
+ return obj;
+ }
+
+ private static String toLocale_helper(double t, int methodId)
+ {
+ java.text.DateFormat formatter;
+ switch (methodId) {
+ case Id_toLocaleString:
+ if (localeDateTimeFormatter == null) {
+ localeDateTimeFormatter
+ = DateFormat.getDateTimeInstance(DateFormat.LONG,
+ DateFormat.LONG);
+ }
+ formatter = localeDateTimeFormatter;
+ break;
+ case Id_toLocaleTimeString:
+ if (localeTimeFormatter == null) {
+ localeTimeFormatter
+ = DateFormat.getTimeInstance(DateFormat.LONG);
+ }
+ formatter = localeTimeFormatter;
+ break;
+ case Id_toLocaleDateString:
+ if (localeDateFormatter == null) {
+ localeDateFormatter
+ = DateFormat.getDateInstance(DateFormat.LONG);
+ }
+ formatter = localeDateFormatter;
+ break;
+ default: formatter = null; // unreachable
+ }
+
+ synchronized (formatter) {
+ return formatter.format(new Date((long) t));
+ }
+ }
+
+ private static String js_toUTCString(double date)
+ {
+ StringBuffer result = new StringBuffer(60);
+
+ appendWeekDayName(result, WeekDay(date));
+ result.append(", ");
+ append0PaddedUint(result, DateFromTime(date), 2);
+ result.append(' ');
+ appendMonthName(result, MonthFromTime(date));
+ result.append(' ');
+ int year = YearFromTime(date);
+ if (year < 0) {
+ result.append('-'); year = -year;
+ }
+ append0PaddedUint(result, year, 4);
+ result.append(' ');
+ append0PaddedUint(result, HourFromTime(date), 2);
+ result.append(':');
+ append0PaddedUint(result, MinFromTime(date), 2);
+ result.append(':');
+ append0PaddedUint(result, SecFromTime(date), 2);
+ result.append(" GMT");
+ return result.toString();
+ }
+
+ private static void append0PaddedUint(StringBuffer sb, int i, int minWidth)
+ {
+ if (i < 0) Kit.codeBug();
+ int scale = 1;
+ --minWidth;
+ if (i >= 10) {
+ if (i < 1000 * 1000 * 1000) {
+ for (;;) {
+ int newScale = scale * 10;
+ if (i < newScale) { break; }
+ --minWidth;
+ scale = newScale;
+ }
+ } else {
+ // Separated case not to check against 10 * 10^9 overflow
+ minWidth -= 9;
+ scale = 1000 * 1000 * 1000;
+ }
+ }
+ while (minWidth > 0) {
+ sb.append('0');
+ --minWidth;
+ }
+ while (scale != 1) {
+ sb.append((char)('0' + (i / scale)));
+ i %= scale;
+ scale /= 10;
+ }
+ sb.append((char)('0' + i));
+ }
+
+ private static void appendMonthName(StringBuffer sb, int index)
+ {
+ // Take advantage of the fact that all month abbreviations
+ // have the same length to minimize amount of strings runtime has
+ // to keep in memory
+ String months = "Jan"+"Feb"+"Mar"+"Apr"+"May"+"Jun"
+ +"Jul"+"Aug"+"Sep"+"Oct"+"Nov"+"Dec";
+ index *= 3;
+ for (int i = 0; i != 3; ++i) {
+ sb.append(months.charAt(index + i));
+ }
+ }
+
+ private static void appendWeekDayName(StringBuffer sb, int index)
+ {
+ String days = "Sun"+"Mon"+"Tue"+"Wed"+"Thu"+"Fri"+"Sat";
+ index *= 3;
+ for (int i = 0; i != 3; ++i) {
+ sb.append(days.charAt(index + i));
+ }
+ }
+
+ private static double makeTime(double date, Object[] args, int methodId)
+ {
+ int maxargs;
+ boolean local = true;
+ switch (methodId) {
+ case Id_setUTCMilliseconds:
+ local = false;
+ // fallthrough
+ case Id_setMilliseconds:
+ maxargs = 1;
+ break;
+
+ case Id_setUTCSeconds:
+ local = false;
+ // fallthrough
+ case Id_setSeconds:
+ maxargs = 2;
+ break;
+
+ case Id_setUTCMinutes:
+ local = false;
+ // fallthrough
+ case Id_setMinutes:
+ maxargs = 3;
+ break;
+
+ case Id_setUTCHours:
+ local = false;
+ // fallthrough
+ case Id_setHours:
+ maxargs = 4;
+ break;
+
+ default:
+ Kit.codeBug();
+ maxargs = 0;
+ }
+
+ int i;
+ double conv[] = new double[4];
+ double hour, min, sec, msec;
+ double lorutime; /* Local or UTC version of date */
+
+ double time;
+ double result;
+
+ /* just return NaN if the date is already NaN */
+ if (date != date)
+ return date;
+
+ /* Satisfy the ECMA rule that if a function is called with
+ * fewer arguments than the specified formal arguments, the
+ * remaining arguments are set to undefined. Seems like all
+ * the Date.setWhatever functions in ECMA are only varargs
+ * beyond the first argument; this should be set to undefined
+ * if it's not given. This means that "d = new Date();
+ * d.setMilliseconds()" returns NaN. Blech.
+ */
+ if (args.length == 0)
+ args = ScriptRuntime.padArguments(args, 1);
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = ScriptRuntime.toNumber(args[i]);
+
+ // limit checks that happen in MakeTime in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ return ScriptRuntime.NaN;
+ }
+ conv[i] = ScriptRuntime.toInteger(conv[i]);
+ }
+
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 4 && i < stop)
+ hour = conv[i++];
+ else
+ hour = HourFromTime(lorutime);
+
+ if (maxargs >= 3 && i < stop)
+ min = conv[i++];
+ else
+ min = MinFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ sec = conv[i++];
+ else
+ sec = SecFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ msec = conv[i++];
+ else
+ msec = msFromTime(lorutime);
+
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(Day(lorutime), time);
+
+ if (local)
+ result = internalUTC(result);
+ date = TimeClip(result);
+
+ return date;
+ }
+
+ private static double makeDate(double date, Object[] args, int methodId)
+ {
+ int maxargs;
+ boolean local = true;
+ switch (methodId) {
+ case Id_setUTCDate:
+ local = false;
+ // fallthrough
+ case Id_setDate:
+ maxargs = 1;
+ break;
+
+ case Id_setUTCMonth:
+ local = false;
+ // fallthrough
+ case Id_setMonth:
+ maxargs = 2;
+ break;
+
+ case Id_setUTCFullYear:
+ local = false;
+ // fallthrough
+ case Id_setFullYear:
+ maxargs = 3;
+ break;
+
+ default:
+ Kit.codeBug();
+ maxargs = 0;
+ }
+
+ int i;
+ double conv[] = new double[3];
+ double year, month, day;
+ double lorutime; /* local or UTC version of date */
+ double result;
+
+ /* See arg padding comment in makeTime.*/
+ if (args.length == 0)
+ args = ScriptRuntime.padArguments(args, 1);
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = ScriptRuntime.toNumber(args[i]);
+
+ // limit checks that happen in MakeDate in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ return ScriptRuntime.NaN;
+ }
+ conv[i] = ScriptRuntime.toInteger(conv[i]);
+ }
+
+ /* return NaN if date is NaN and we're not setting the year,
+ * If we are, use 0 as the time. */
+ if (date != date) {
+ if (args.length < 3) {
+ return ScriptRuntime.NaN;
+ } else {
+ lorutime = 0;
+ }
+ } else {
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+ }
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 3 && i < stop)
+ year = conv[i++];
+ else
+ year = YearFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ month = conv[i++];
+ else
+ month = MonthFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ day = conv[i++];
+ else
+ day = DateFromTime(lorutime);
+
+ day = MakeDay(year, month, day); /* day within year */
+ result = MakeDate(day, TimeWithinDay(lorutime));
+
+ if (local)
+ result = internalUTC(result);
+
+ date = TimeClip(result);
+
+ return date;
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:38 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 6: X="getDay";id=Id_getDay; break L;
+ case 7: switch (s.charAt(3)) {
+ case 'D': c=s.charAt(0);
+ if (c=='g') { X="getDate";id=Id_getDate; }
+ else if (c=='s') { X="setDate";id=Id_setDate; }
+ break L;
+ case 'T': c=s.charAt(0);
+ if (c=='g') { X="getTime";id=Id_getTime; }
+ else if (c=='s') { X="setTime";id=Id_setTime; }
+ break L;
+ case 'Y': c=s.charAt(0);
+ if (c=='g') { X="getYear";id=Id_getYear; }
+ else if (c=='s') { X="setYear";id=Id_setYear; }
+ break L;
+ case 'u': X="valueOf";id=Id_valueOf; break L;
+ } break L;
+ case 8: switch (s.charAt(3)) {
+ case 'H': c=s.charAt(0);
+ if (c=='g') { X="getHours";id=Id_getHours; }
+ else if (c=='s') { X="setHours";id=Id_setHours; }
+ break L;
+ case 'M': c=s.charAt(0);
+ if (c=='g') { X="getMonth";id=Id_getMonth; }
+ else if (c=='s') { X="setMonth";id=Id_setMonth; }
+ break L;
+ case 'o': X="toSource";id=Id_toSource; break L;
+ case 't': X="toString";id=Id_toString; break L;
+ } break L;
+ case 9: X="getUTCDay";id=Id_getUTCDay; break L;
+ case 10: c=s.charAt(3);
+ if (c=='M') {
+ c=s.charAt(0);
+ if (c=='g') { X="getMinutes";id=Id_getMinutes; }
+ else if (c=='s') { X="setMinutes";id=Id_setMinutes; }
+ }
+ else if (c=='S') {
+ c=s.charAt(0);
+ if (c=='g') { X="getSeconds";id=Id_getSeconds; }
+ else if (c=='s') { X="setSeconds";id=Id_setSeconds; }
+ }
+ else if (c=='U') {
+ c=s.charAt(0);
+ if (c=='g') { X="getUTCDate";id=Id_getUTCDate; }
+ else if (c=='s') { X="setUTCDate";id=Id_setUTCDate; }
+ }
+ break L;
+ case 11: switch (s.charAt(3)) {
+ case 'F': c=s.charAt(0);
+ if (c=='g') { X="getFullYear";id=Id_getFullYear; }
+ else if (c=='s') { X="setFullYear";id=Id_setFullYear; }
+ break L;
+ case 'M': X="toGMTString";id=Id_toGMTString; break L;
+ case 'T': X="toUTCString";id=Id_toUTCString; break L;
+ case 'U': c=s.charAt(0);
+ if (c=='g') {
+ c=s.charAt(9);
+ if (c=='r') { X="getUTCHours";id=Id_getUTCHours; }
+ else if (c=='t') { X="getUTCMonth";id=Id_getUTCMonth; }
+ }
+ else if (c=='s') {
+ c=s.charAt(9);
+ if (c=='r') { X="setUTCHours";id=Id_setUTCHours; }
+ else if (c=='t') { X="setUTCMonth";id=Id_setUTCMonth; }
+ }
+ break L;
+ case 's': X="constructor";id=Id_constructor; break L;
+ } break L;
+ case 12: c=s.charAt(2);
+ if (c=='D') { X="toDateString";id=Id_toDateString; }
+ else if (c=='T') { X="toTimeString";id=Id_toTimeString; }
+ break L;
+ case 13: c=s.charAt(0);
+ if (c=='g') {
+ c=s.charAt(6);
+ if (c=='M') { X="getUTCMinutes";id=Id_getUTCMinutes; }
+ else if (c=='S') { X="getUTCSeconds";id=Id_getUTCSeconds; }
+ }
+ else if (c=='s') {
+ c=s.charAt(6);
+ if (c=='M') { X="setUTCMinutes";id=Id_setUTCMinutes; }
+ else if (c=='S') { X="setUTCSeconds";id=Id_setUTCSeconds; }
+ }
+ break L;
+ case 14: c=s.charAt(0);
+ if (c=='g') { X="getUTCFullYear";id=Id_getUTCFullYear; }
+ else if (c=='s') { X="setUTCFullYear";id=Id_setUTCFullYear; }
+ else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; }
+ break L;
+ case 15: c=s.charAt(0);
+ if (c=='g') { X="getMilliseconds";id=Id_getMilliseconds; }
+ else if (c=='s') { X="setMilliseconds";id=Id_setMilliseconds; }
+ break L;
+ case 17: X="getTimezoneOffset";id=Id_getTimezoneOffset; break L;
+ case 18: c=s.charAt(0);
+ if (c=='g') { X="getUTCMilliseconds";id=Id_getUTCMilliseconds; }
+ else if (c=='s') { X="setUTCMilliseconds";id=Id_setUTCMilliseconds; }
+ else if (c=='t') {
+ c=s.charAt(8);
+ if (c=='D') { X="toLocaleDateString";id=Id_toLocaleDateString; }
+ else if (c=='T') { X="toLocaleTimeString";id=Id_toLocaleTimeString; }
+ }
+ break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ ConstructorId_now = -3,
+ ConstructorId_parse = -2,
+ ConstructorId_UTC = -1,
+
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toTimeString = 3,
+ Id_toDateString = 4,
+ Id_toLocaleString = 5,
+ Id_toLocaleTimeString = 6,
+ Id_toLocaleDateString = 7,
+ Id_toUTCString = 8,
+ Id_toSource = 9,
+ Id_valueOf = 10,
+ Id_getTime = 11,
+ Id_getYear = 12,
+ Id_getFullYear = 13,
+ Id_getUTCFullYear = 14,
+ Id_getMonth = 15,
+ Id_getUTCMonth = 16,
+ Id_getDate = 17,
+ Id_getUTCDate = 18,
+ Id_getDay = 19,
+ Id_getUTCDay = 20,
+ Id_getHours = 21,
+ Id_getUTCHours = 22,
+ Id_getMinutes = 23,
+ Id_getUTCMinutes = 24,
+ Id_getSeconds = 25,
+ Id_getUTCSeconds = 26,
+ Id_getMilliseconds = 27,
+ Id_getUTCMilliseconds = 28,
+ Id_getTimezoneOffset = 29,
+ Id_setTime = 30,
+ Id_setMilliseconds = 31,
+ Id_setUTCMilliseconds = 32,
+ Id_setSeconds = 33,
+ Id_setUTCSeconds = 34,
+ Id_setMinutes = 35,
+ Id_setUTCMinutes = 36,
+ Id_setHours = 37,
+ Id_setUTCHours = 38,
+ Id_setDate = 39,
+ Id_setUTCDate = 40,
+ Id_setMonth = 41,
+ Id_setUTCMonth = 42,
+ Id_setFullYear = 43,
+ Id_setUTCFullYear = 44,
+ Id_setYear = 45,
+
+ MAX_PROTOTYPE_ID = 45;
+
+ private static final int
+ Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6
+// #/string_id_map#
+
+ /* cached values */
+ private static java.util.TimeZone thisTimeZone;
+ private static double LocalTZA;
+ private static java.text.DateFormat timeZoneFormatter;
+ private static java.text.DateFormat localeDateTimeFormatter;
+ private static java.text.DateFormat localeDateFormatter;
+ private static java.text.DateFormat localeTimeFormatter;
+
+ private double date;
+}
+
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java
new file mode 100644
index 0000000..4aff10c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeError.java
@@ -0,0 +1,227 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript;
+
+/**
+ *
+ * The class of error objects
+ *
+ * ECMA 15.11
+ */
+final class NativeError extends IdScriptableObject
+{
+ static final long serialVersionUID = -5338413581437645187L;
+
+ private static final Object ERROR_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeError obj = new NativeError();
+ ScriptableObject.putProperty(obj, "name", "Error");
+ ScriptableObject.putProperty(obj, "message", "");
+ ScriptableObject.putProperty(obj, "fileName", "");
+ ScriptableObject.putProperty(obj, "lineNumber", new Integer(0));
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ static NativeError make(Context cx, Scriptable scope,
+ IdFunctionObject ctorObj, Object[] args)
+ {
+ Scriptable proto = (Scriptable)(ctorObj.get("prototype", ctorObj));
+
+ NativeError obj = new NativeError();
+ obj.setPrototype(proto);
+ obj.setParentScope(scope);
+
+ int arglen = args.length;
+ if (arglen >= 1) {
+ ScriptableObject.putProperty(obj, "message",
+ ScriptRuntime.toString(args[0]));
+ if (arglen >= 2) {
+ ScriptableObject.putProperty(obj, "fileName", args[1]);
+ if (arglen >= 3) {
+ int line = ScriptRuntime.toInt32(args[2]);
+ ScriptableObject.putProperty(obj, "lineNumber",
+ new Integer(line));
+ }
+ }
+ }
+ if(arglen < 3 && cx.hasFeature(Context.FEATURE_LOCATION_INFORMATION_IN_ERROR)) {
+ // Fill in fileName and lineNumber automatically when not specified
+ // explicitly, see Bugzilla issue #342807
+ int[] linep = new int[1];
+ String fileName = Context.getSourcePositionFromStack(linep);
+ ScriptableObject.putProperty(obj, "lineNumber",
+ new Integer(linep[0]));
+ if(arglen < 2) {
+ ScriptableObject.putProperty(obj, "fileName", fileName);
+ }
+ }
+ return obj;
+ }
+
+ public String getClassName()
+ {
+ return "Error";
+ }
+
+ public String toString()
+ {
+ return js_toString(this);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(ERROR_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(ERROR_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return make(cx, scope, f, args);
+
+ case Id_toString:
+ return js_toString(thisObj);
+
+ case Id_toSource:
+ return js_toSource(cx, scope, thisObj);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static String js_toString(Scriptable thisObj)
+ {
+ return getString(thisObj, "name")+": "+getString(thisObj, "message");
+ }
+
+ private static String js_toSource(Context cx, Scriptable scope,
+ Scriptable thisObj)
+ {
+ // Emulation of SpiderMonkey behavior
+ Object name = ScriptableObject.getProperty(thisObj, "name");
+ Object message = ScriptableObject.getProperty(thisObj, "message");
+ Object fileName = ScriptableObject.getProperty(thisObj, "fileName");
+ Object lineNumber = ScriptableObject.getProperty(thisObj, "lineNumber");
+
+ StringBuffer sb = new StringBuffer();
+ sb.append("(new ");
+ if (name == NOT_FOUND) {
+ name = Undefined.instance;
+ }
+ sb.append(ScriptRuntime.toString(name));
+ sb.append("(");
+ if (message != NOT_FOUND
+ || fileName != NOT_FOUND
+ || lineNumber != NOT_FOUND)
+ {
+ if (message == NOT_FOUND) {
+ message = "";
+ }
+ sb.append(ScriptRuntime.uneval(cx, scope, message));
+ if (fileName != NOT_FOUND || lineNumber != NOT_FOUND) {
+ sb.append(", ");
+ if (fileName == NOT_FOUND) {
+ fileName = "";
+ }
+ sb.append(ScriptRuntime.uneval(cx, scope, fileName));
+ if (lineNumber != NOT_FOUND) {
+ int line = ScriptRuntime.toInt32(lineNumber);
+ if (line != 0) {
+ sb.append(", ");
+ sb.append(ScriptRuntime.toString(line));
+ }
+ }
+ }
+ }
+ sb.append("))");
+ return sb.toString();
+ }
+
+ private static String getString(Scriptable obj, String id)
+ {
+ Object value = ScriptableObject.getProperty(obj, id);
+ if (value == NOT_FOUND) return "";
+ return ScriptRuntime.toString(value);
+ }
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #string_id_map#
+// #generated# Last update: 2007-05-09 08:15:45 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+
+ MAX_PROTOTYPE_ID = 3;
+
+// #/string_id_map#
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java
new file mode 100644
index 0000000..ac70556
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeFunction.java
@@ -0,0 +1,169 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Bob Jervis
+ * Roger Lawrence
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import org.mozilla.javascript.debug.DebuggableScript;
+
+/**
+ * This class implements the Function native object.
+ * See ECMA 15.3.
+ * @author Norris Boyd
+ */
+public abstract class NativeFunction extends BaseFunction
+{
+
+ public final void initScriptFunction(Context cx, Scriptable scope)
+ {
+ ScriptRuntime.setFunctionProtoAndParent(this, scope);
+ }
+
+ /**
+ * @param indent How much to indent the decompiled result
+ *
+ * @param flags Flags specifying format of decompilation output
+ */
+ final String decompile(int indent, int flags)
+ {
+ String encodedSource = getEncodedSource();
+ if (encodedSource == null) {
+ return super.decompile(indent, flags);
+ } else {
+ UintMap properties = new UintMap(1);
+ properties.put(Decompiler.INITIAL_INDENT_PROP, indent);
+ return Decompiler.decompile(encodedSource, flags, properties);
+ }
+ }
+
+ public int getLength()
+ {
+ int paramCount = getParamCount();
+ if (getLanguageVersion() != Context.VERSION_1_2) {
+ return paramCount;
+ }
+ Context cx = Context.getContext();
+ NativeCall activation = ScriptRuntime.findFunctionActivation(cx, this);
+ if (activation == null) {
+ return paramCount;
+ }
+ return activation.originalArgs.length;
+ }
+
+ public int getArity()
+ {
+ return getParamCount();
+ }
+
+ /**
+ * @deprecated Use {@link BaseFunction#getFunctionName()} instead.
+ * For backwards compatibility keep an old method name used by
+ * Batik and possibly others.
+ */
+ public String jsGet_name()
+ {
+ return getFunctionName();
+ }
+
+ /**
+ * Get encoded source string.
+ */
+ public String getEncodedSource()
+ {
+ return null;
+ }
+
+ public DebuggableScript getDebuggableView()
+ {
+ return null;
+ }
+
+ /**
+ * Resume execution of a suspended generator.
+ * @param cx The current context
+ * @param scope Scope for the parent generator function
+ * @param operation The resumption operation (next, send, etc.. )
+ * @param state The generator state (has locals, stack, etc.)
+ * @param value The return value of yield (if required).
+ * @return The next yielded value (if any)
+ */
+ public Object resumeGenerator(Context cx, Scriptable scope,
+ int operation, Object state, Object value)
+ {
+ throw new EvaluatorException("resumeGenerator() not implemented");
+ }
+
+
+ protected abstract int getLanguageVersion();
+
+ /**
+ * Get number of declared parameters. It should be 0 for scripts.
+ */
+ protected abstract int getParamCount();
+
+ /**
+ * Get number of declared parameters and variables defined through var
+ * statements.
+ */
+ protected abstract int getParamAndVarCount();
+
+ /**
+ * Get parameter or variable name.
+ * If <tt>index < {@link #getParamCount()}</tt>, then return the name of the
+ * corresponding parameter. Otherwise return the name of variable.
+ */
+ protected abstract String getParamOrVarName(int index);
+
+ /**
+ * Get parameter or variable const-ness.
+ * If <tt>index < {@link #getParamCount()}</tt>, then return the const-ness
+ * of the corresponding parameter. Otherwise return whether the variable is
+ * const.
+ */
+ protected boolean getParamOrVarConst(int index)
+ {
+ // By default return false to preserve compatibility with existing
+ // classes subclassing this class, which are mostly generated by jsc
+ // from earlier Rhino versions. See Bugzilla #396117.
+ return false;
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java
new file mode 100644
index 0000000..0a8da9f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGenerator.java
@@ -0,0 +1,281 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements generator objects. See
+ * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Generators
+ *
+ * @author Norris Boyd
+ */
+public final class NativeGenerator extends IdScriptableObject {
+ private static final Object GENERATOR_TAG = new Object();
+
+ static NativeGenerator init(ScriptableObject scope, boolean sealed) {
+ // Generator
+ // Can't use "NativeGenerator().exportAsJSClass" since we don't want
+ // to define "Generator" as a constructor in the top-level scope.
+
+ NativeGenerator prototype = new NativeGenerator();
+ if (scope != null) {
+ prototype.setParentScope(scope);
+ prototype.setPrototype(getObjectPrototype(scope));
+ }
+ prototype.activatePrototypeMap(MAX_PROTOTYPE_ID);
+ if (sealed) {
+ prototype.sealObject();
+ }
+
+ // Need to access Generator prototype when constructing
+ // Generator instances, but don't have a generator constructor
+ // to use to find the prototype. Use the "associateValue"
+ // approach instead.
+ if (scope != null) {
+ scope.associateValue(GENERATOR_TAG, prototype);
+ }
+
+ return prototype;
+ }
+
+ /**
+ * Only for constructing the prototype object.
+ */
+ private NativeGenerator() { }
+
+ public NativeGenerator(Scriptable scope, NativeFunction function,
+ Object savedState)
+ {
+ this.function = function;
+ this.savedState = savedState;
+ // Set parent and prototype properties. Since we don't have a
+ // "Generator" constructor in the top scope, we stash the
+ // prototype in the top scope's associated value.
+ Scriptable top = ScriptableObject.getTopLevelScope(scope);
+ this.setParentScope(top);
+ NativeGenerator prototype = (NativeGenerator)
+ ScriptableObject.getTopScopeValue(top, GENERATOR_TAG);
+ this.setPrototype(prototype);
+ }
+
+ public static final int GENERATOR_SEND = 0,
+ GENERATOR_THROW = 1,
+ GENERATOR_CLOSE = 2;
+
+ public String getClassName() {
+ return "Generator";
+ }
+
+ /**
+ * Close the generator if it is still open.
+ */
+ public void finalize() throws Throwable {
+ if (savedState != null) {
+ // This is a little tricky since we are most likely running in
+ // a different thread. We need to get a Context to run this, and
+ // we must call "doTopCall" since this will likely be the outermost
+ // JavaScript frame on this thread.
+ Context cx = Context.getCurrentContext();
+ ContextFactory factory = cx != null ? cx.getFactory()
+ : ContextFactory.getGlobal();
+ Scriptable scope = ScriptableObject.getTopLevelScope(this);
+ factory.call(new CloseGeneratorAction(this));
+ }
+ }
+
+ private static class CloseGeneratorAction implements ContextAction {
+ private NativeGenerator generator;
+
+ CloseGeneratorAction(NativeGenerator generator) {
+ this.generator = generator;
+ }
+
+ public Object run(Context cx) {
+ Scriptable scope = ScriptableObject.getTopLevelScope(generator);
+ Callable closeGenerator = new Callable() {
+ public Object call(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args) {
+ return ((NativeGenerator)thisObj).resume(cx, scope,
+ GENERATOR_CLOSE, new GeneratorClosedException());
+ }
+ };
+ return ScriptRuntime.doTopCall(closeGenerator, cx, scope,
+ generator, null);
+ }
+ }
+
+ protected void initPrototypeId(int id) {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_close: arity=1; s="close"; break;
+ case Id_next: arity=1; s="next"; break;
+ case Id_send: arity=0; s="send"; break;
+ case Id_throw: arity=0; s="throw"; break;
+ case Id___iterator__: arity=1; s="__iterator__"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(GENERATOR_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(GENERATOR_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+
+ if (!(thisObj instanceof NativeGenerator))
+ throw incompatibleCallError(f);
+
+ NativeGenerator generator = (NativeGenerator) thisObj;
+
+ switch (id) {
+
+ case Id_close:
+ // need to run any pending finally clauses
+ return generator.resume(cx, scope, GENERATOR_CLOSE,
+ new GeneratorClosedException());
+
+ case Id_next:
+ // arguments to next() are ignored
+ generator.firstTime = false;
+ return generator.resume(cx, scope, GENERATOR_SEND,
+ Undefined.instance);
+
+ case Id_send: {
+ Object arg = args.length > 0 ? args[0] : Undefined.instance;
+ if (generator.firstTime && !arg.equals(Undefined.instance)) {
+ throw ScriptRuntime.typeError0("msg.send.newborn");
+ }
+ return generator.resume(cx, scope, GENERATOR_SEND, arg);
+ }
+
+ case Id_throw:
+ return generator.resume(cx, scope, GENERATOR_THROW,
+ args.length > 0 ? args[0] : Undefined.instance);
+
+ case Id___iterator__:
+ return thisObj;
+
+ default:
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+ private Object resume(Context cx, Scriptable scope, int operation,
+ Object value)
+ {
+ if (savedState == null) {
+ if (operation == GENERATOR_CLOSE)
+ return Undefined.instance;
+ Object thrown;
+ if (operation == GENERATOR_THROW) {
+ thrown = value;
+ } else {
+ thrown = NativeIterator.getStopIterationObject(scope);
+ }
+ throw new JavaScriptException(thrown, lineSource, lineNumber);
+ }
+ try {
+ synchronized (this) {
+ // generator execution is necessarily single-threaded and
+ // non-reentrant.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=349263
+ if (locked)
+ throw ScriptRuntime.typeError0("msg.already.exec.gen");
+ locked = true;
+ }
+ return function.resumeGenerator(cx, scope, operation, savedState,
+ value);
+ } catch (GeneratorClosedException e) {
+ // On closing a generator in the compile path, the generator
+ // throws a special exception. This ensures execution of all pending
+ // finalizers and will not get caught by user code.
+ return Undefined.instance;
+ } catch (RhinoException e) {
+ lineNumber = e.lineNumber();
+ lineSource = e.lineSource();
+ savedState = null;
+ throw e;
+ } finally {
+ synchronized (this) {
+ locked = false;
+ }
+ if (operation == GENERATOR_CLOSE)
+ savedState = null;
+ }
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s) {
+ int id;
+// #generated# Last update: 2007-06-14 13:13:03 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==4) {
+ c=s.charAt(0);
+ if (c=='n') { X="next";id=Id_next; }
+ else if (c=='s') { X="send";id=Id_send; }
+ }
+ else if (s_length==5) {
+ c=s.charAt(0);
+ if (c=='c') { X="close";id=Id_close; }
+ else if (c=='t') { X="throw";id=Id_throw; }
+ }
+ else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_close = 1,
+ Id_next = 2,
+ Id_send = 3,
+ Id_throw = 4,
+ Id___iterator__ = 5,
+ MAX_PROTOTYPE_ID = 5;
+
+// #/string_id_map#
+ private NativeFunction function;
+ private Object savedState;
+ private String lineSource;
+ private int lineNumber;
+ private boolean firstTime = true;
+ private boolean locked;
+
+ public static class GeneratorClosedException extends RuntimeException {
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java
new file mode 100644
index 0000000..58faad4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeGlobal.java
@@ -0,0 +1,790 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+import org.mozilla.javascript.xml.XMLLib;
+
+/**
+ * This class implements the global native object (function and value
+ * properties only).
+ *
+ * See ECMA 15.1.[12].
+ *
+ * @author Mike Shaver
+ */
+
+public class NativeGlobal implements Serializable, IdFunctionCall
+{
+ static final long serialVersionUID = 6080442165748707530L;
+
+ public static void init(Context cx, Scriptable scope, boolean sealed) {
+ NativeGlobal obj = new NativeGlobal();
+
+ for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id) {
+ String name;
+ int arity = 1;
+ switch (id) {
+ case Id_decodeURI:
+ name = "decodeURI";
+ break;
+ case Id_decodeURIComponent:
+ name = "decodeURIComponent";
+ break;
+ case Id_encodeURI:
+ name = "encodeURI";
+ break;
+ case Id_encodeURIComponent:
+ name = "encodeURIComponent";
+ break;
+ case Id_escape:
+ name = "escape";
+ break;
+ case Id_eval:
+ name = "eval";
+ break;
+ case Id_isFinite:
+ name = "isFinite";
+ break;
+ case Id_isNaN:
+ name = "isNaN";
+ break;
+ case Id_isXMLName:
+ name = "isXMLName";
+ break;
+ case Id_parseFloat:
+ name = "parseFloat";
+ break;
+ case Id_parseInt:
+ name = "parseInt";
+ arity = 2;
+ break;
+ case Id_unescape:
+ name = "unescape";
+ break;
+ case Id_uneval:
+ name = "uneval";
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name,
+ arity, scope);
+ if (sealed) {
+ f.sealObject();
+ }
+ f.exportAsScopeProperty();
+ }
+
+ ScriptableObject.defineProperty(
+ scope, "NaN", ScriptRuntime.NaNobj,
+ ScriptableObject.DONTENUM);
+ ScriptableObject.defineProperty(
+ scope, "Infinity",
+ ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY),
+ ScriptableObject.DONTENUM);
+ ScriptableObject.defineProperty(
+ scope, "undefined", Undefined.instance,
+ ScriptableObject.DONTENUM);
+
+ String[] errorMethods = Kit.semicolonSplit(""
+ +"ConversionError;"
+ +"EvalError;"
+ +"RangeError;"
+ +"ReferenceError;"
+ +"SyntaxError;"
+ +"TypeError;"
+ +"URIError;"
+ +"InternalError;"
+ +"JavaException;"
+ );
+
+ /*
+ Each error constructor gets its own Error object as a prototype,
+ with the 'name' property set to the name of the error.
+ */
+ for (int i = 0; i < errorMethods.length; i++) {
+ String name = errorMethods[i];
+ Scriptable errorProto = ScriptRuntime.
+ newObject(cx, scope, "Error",
+ ScriptRuntime.emptyArgs);
+ errorProto.put("name", errorProto, name);
+ if (sealed) {
+ if (errorProto instanceof ScriptableObject) {
+ ((ScriptableObject)errorProto).sealObject();
+ }
+ }
+ IdFunctionObject ctor = new IdFunctionObject(obj, FTAG,
+ Id_new_CommonError,
+ name, 1, scope);
+ ctor.markAsConstructor(errorProto);
+ if (sealed) {
+ ctor.sealObject();
+ }
+ ctor.exportAsScopeProperty();
+ }
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (f.hasTag(FTAG)) {
+ int methodId = f.methodId();
+ switch (methodId) {
+ case Id_decodeURI:
+ case Id_decodeURIComponent: {
+ String str = ScriptRuntime.toString(args, 0);
+ return decode(str, methodId == Id_decodeURI);
+ }
+
+ case Id_encodeURI:
+ case Id_encodeURIComponent: {
+ String str = ScriptRuntime.toString(args, 0);
+ return encode(str, methodId == Id_encodeURI);
+ }
+
+ case Id_escape:
+ return js_escape(args);
+
+ case Id_eval:
+ return js_eval(cx, scope, args);
+
+ case Id_isFinite: {
+ boolean result;
+ if (args.length < 1) {
+ result = false;
+ } else {
+ double d = ScriptRuntime.toNumber(args[0]);
+ result = (d == d
+ && d != Double.POSITIVE_INFINITY
+ && d != Double.NEGATIVE_INFINITY);
+ }
+ return ScriptRuntime.wrapBoolean(result);
+ }
+
+ case Id_isNaN: {
+ // The global method isNaN, as per ECMA-262 15.1.2.6.
+ boolean result;
+ if (args.length < 1) {
+ result = true;
+ } else {
+ double d = ScriptRuntime.toNumber(args[0]);
+ result = (d != d);
+ }
+ return ScriptRuntime.wrapBoolean(result);
+ }
+
+ case Id_isXMLName: {
+ Object name = (args.length == 0)
+ ? Undefined.instance : args[0];
+ XMLLib xmlLib = XMLLib.extractFromScope(scope);
+ return ScriptRuntime.wrapBoolean(
+ xmlLib.isXMLName(cx, name));
+ }
+
+ case Id_parseFloat:
+ return js_parseFloat(args);
+
+ case Id_parseInt:
+ return js_parseInt(args);
+
+ case Id_unescape:
+ return js_unescape(args);
+
+ case Id_uneval: {
+ Object value = (args.length != 0)
+ ? args[0] : Undefined.instance;
+ return ScriptRuntime.uneval(cx, scope, value);
+ }
+
+ case Id_new_CommonError:
+ // The implementation of all the ECMA error constructors
+ // (SyntaxError, TypeError, etc.)
+ return NativeError.make(cx, scope, f, args);
+ }
+ }
+ throw f.unknown();
+ }
+
+ /**
+ * The global method parseInt, as per ECMA-262 15.1.2.2.
+ */
+ private Object js_parseInt(Object[] args) {
+ String s = ScriptRuntime.toString(args, 0);
+ int radix = ScriptRuntime.toInt32(args, 1);
+
+ int len = s.length();
+ if (len == 0)
+ return ScriptRuntime.NaNobj;
+
+ boolean negative = false;
+ int start = 0;
+ char c;
+ do {
+ c = s.charAt(start);
+ if (!Character.isWhitespace(c))
+ break;
+ start++;
+ } while (start < len);
+
+ if (c == '+' || (negative = (c == '-')))
+ start++;
+
+ final int NO_RADIX = -1;
+ if (radix == 0) {
+ radix = NO_RADIX;
+ } else if (radix < 2 || radix > 36) {
+ return ScriptRuntime.NaNobj;
+ } else if (radix == 16 && len - start > 1 && s.charAt(start) == '0') {
+ c = s.charAt(start+1);
+ if (c == 'x' || c == 'X')
+ start += 2;
+ }
+
+ if (radix == NO_RADIX) {
+ radix = 10;
+ if (len - start > 1 && s.charAt(start) == '0') {
+ c = s.charAt(start+1);
+ if (c == 'x' || c == 'X') {
+ radix = 16;
+ start += 2;
+ } else if ('0' <= c && c <= '9') {
+ radix = 8;
+ start++;
+ }
+ }
+ }
+
+ double d = ScriptRuntime.stringToNumber(s, start, radix);
+ return ScriptRuntime.wrapNumber(negative ? -d : d);
+ }
+
+ /**
+ * The global method parseFloat, as per ECMA-262 15.1.2.3.
+ *
+ * @param args the arguments to parseFloat, ignoring args[>=1]
+ */
+ private Object js_parseFloat(Object[] args)
+ {
+ if (args.length < 1)
+ return ScriptRuntime.NaNobj;
+
+ String s = ScriptRuntime.toString(args[0]);
+ int len = s.length();
+ int start = 0;
+ // Scan forward to skip whitespace
+ char c;
+ for (;;) {
+ if (start == len) {
+ return ScriptRuntime.NaNobj;
+ }
+ c = s.charAt(start);
+ if (!TokenStream.isJSSpace(c)) {
+ break;
+ }
+ ++start;
+ }
+
+ int i = start;
+ if (c == '+' || c == '-') {
+ ++i;
+ if (i == len) {
+ return ScriptRuntime.NaNobj;
+ }
+ c = s.charAt(i);
+ }
+
+ if (c == 'I') {
+ // check for "Infinity"
+ if (i+8 <= len && s.regionMatches(i, "Infinity", 0, 8)) {
+ double d;
+ if (s.charAt(start) == '-') {
+ d = Double.NEGATIVE_INFINITY;
+ } else {
+ d = Double.POSITIVE_INFINITY;
+ }
+ return ScriptRuntime.wrapNumber(d);
+ }
+ return ScriptRuntime.NaNobj;
+ }
+
+ // Find the end of the legal bit
+ int decimal = -1;
+ int exponent = -1;
+ for (; i < len; i++) {
+ switch (s.charAt(i)) {
+ case '.':
+ if (decimal != -1) // Only allow a single decimal point.
+ break;
+ decimal = i;
+ continue;
+
+ case 'e':
+ case 'E':
+ if (exponent != -1)
+ break;
+ exponent = i;
+ continue;
+
+ case '+':
+ case '-':
+ // Only allow '+' or '-' after 'e' or 'E'
+ if (exponent != i-1)
+ break;
+ continue;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ continue;
+
+ default:
+ break;
+ }
+ break;
+ }
+ s = s.substring(start, i);
+ try {
+ return Double.valueOf(s);
+ }
+ catch (NumberFormatException ex) {
+ return ScriptRuntime.NaNobj;
+ }
+ }
+
+ /**
+ * The global method escape, as per ECMA-262 15.1.2.4.
+
+ * Includes code for the 'mask' argument supported by the C escape
+ * method, which used to be part of the browser imbedding. Blame
+ * for the strange constant names should be directed there.
+ */
+
+ private Object js_escape(Object[] args) {
+ final int
+ URL_XALPHAS = 1,
+ URL_XPALPHAS = 2,
+ URL_PATH = 4;
+
+ String s = ScriptRuntime.toString(args, 0);
+
+ int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
+ if (args.length > 1) { // the 'mask' argument. Non-ECMA.
+ double d = ScriptRuntime.toNumber(args[1]);
+ if (d != d || ((mask = (int) d) != d) ||
+ 0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)))
+ {
+ throw Context.reportRuntimeError0("msg.bad.esc.mask");
+ }
+ }
+
+ StringBuffer sb = null;
+ for (int k = 0, L = s.length(); k != L; ++k) {
+ int c = s.charAt(k);
+ if (mask != 0
+ && ((c >= '0' && c <= '9')
+ || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
+ || c == '@' || c == '*' || c == '_' || c == '-' || c == '.'
+ || (0 != (mask & URL_PATH) && (c == '/' || c == '+'))))
+ {
+ if (sb != null) {
+ sb.append((char)c);
+ }
+ } else {
+ if (sb == null) {
+ sb = new StringBuffer(L + 3);
+ sb.append(s);
+ sb.setLength(k);
+ }
+
+ int hexSize;
+ if (c < 256) {
+ if (c == ' ' && mask == URL_XPALPHAS) {
+ sb.append('+');
+ continue;
+ }
+ sb.append('%');
+ hexSize = 2;
+ } else {
+ sb.append('%');
+ sb.append('u');
+ hexSize = 4;
+ }
+
+ // append hexadecimal form of c left-padded with 0
+ for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
+ int digit = 0xf & (c >> shift);
+ int hc = (digit < 10) ? '0' + digit : 'A' - 10 + digit;
+ sb.append((char)hc);
+ }
+ }
+ }
+
+ return (sb == null) ? s : sb.toString();
+ }
+
+ /**
+ * The global unescape method, as per ECMA-262 15.1.2.5.
+ */
+
+ private Object js_unescape(Object[] args)
+ {
+ String s = ScriptRuntime.toString(args, 0);
+ int firstEscapePos = s.indexOf('%');
+ if (firstEscapePos >= 0) {
+ int L = s.length();
+ char[] buf = s.toCharArray();
+ int destination = firstEscapePos;
+ for (int k = firstEscapePos; k != L;) {
+ char c = buf[k];
+ ++k;
+ if (c == '%' && k != L) {
+ int end, start;
+ if (buf[k] == 'u') {
+ start = k + 1;
+ end = k + 5;
+ } else {
+ start = k;
+ end = k + 2;
+ }
+ if (end <= L) {
+ int x = 0;
+ for (int i = start; i != end; ++i) {
+ x = Kit.xDigitToInt(buf[i], x);
+ }
+ if (x >= 0) {
+ c = (char)x;
+ k = end;
+ }
+ }
+ }
+ buf[destination] = c;
+ ++destination;
+ }
+ s = new String(buf, 0, destination);
+ }
+ return s;
+ }
+
+ private Object js_eval(Context cx, Scriptable scope, Object[] args)
+ {
+ String m = ScriptRuntime.getMessage1("msg.cant.call.indirect", "eval");
+ throw NativeGlobal.constructError(cx, "EvalError", m, scope);
+ }
+
+ static boolean isEvalFunction(Object functionObj)
+ {
+ if (functionObj instanceof IdFunctionObject) {
+ IdFunctionObject function = (IdFunctionObject)functionObj;
+ if (function.hasTag(FTAG) && function.methodId() == Id_eval) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @deprecated Use {@link ScriptRuntime#constructError(String,String)}
+ * instead.
+ */
+ public static EcmaError constructError(Context cx,
+ String error,
+ String message,
+ Scriptable scope)
+ {
+ return ScriptRuntime.constructError(error, message);
+ }
+
+ /**
+ * @deprecated Use
+ * {@link ScriptRuntime#constructError(String,String,String,int,String,int)}
+ * instead.
+ */
+ public static EcmaError constructError(Context cx,
+ String error,
+ String message,
+ Scriptable scope,
+ String sourceName,
+ int lineNumber,
+ int columnNumber,
+ String lineSource)
+ {
+ return ScriptRuntime.constructError(error, message,
+ sourceName, lineNumber,
+ lineSource, columnNumber);
+ }
+
+ /*
+ * ECMA 3, 15.1.3 URI Handling Function Properties
+ *
+ * The following are implementations of the algorithms
+ * given in the ECMA specification for the hidden functions
+ * 'Encode' and 'Decode'.
+ */
+ private static String encode(String str, boolean fullUri) {
+ byte[] utf8buf = null;
+ StringBuffer sb = null;
+
+ for (int k = 0, length = str.length(); k != length; ++k) {
+ char C = str.charAt(k);
+ if (encodeUnescaped(C, fullUri)) {
+ if (sb != null) {
+ sb.append(C);
+ }
+ } else {
+ if (sb == null) {
+ sb = new StringBuffer(length + 3);
+ sb.append(str);
+ sb.setLength(k);
+ utf8buf = new byte[6];
+ }
+ if (0xDC00 <= C && C <= 0xDFFF) {
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ }
+ int V;
+ if (C < 0xD800 || 0xDBFF < C) {
+ V = C;
+ } else {
+ k++;
+ if (k == length) {
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ }
+ char C2 = str.charAt(k);
+ if (!(0xDC00 <= C2 && C2 <= 0xDFFF)) {
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ }
+ V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000;
+ }
+ int L = oneUcs4ToUtf8Char(utf8buf, V);
+ for (int j = 0; j < L; j++) {
+ int d = 0xff & utf8buf[j];
+ sb.append('%');
+ sb.append(toHexChar(d >>> 4));
+ sb.append(toHexChar(d & 0xf));
+ }
+ }
+ }
+ return (sb == null) ? str : sb.toString();
+ }
+
+ private static char toHexChar(int i) {
+ if (i >> 4 != 0) Kit.codeBug();
+ return (char)((i < 10) ? i + '0' : i - 10 + 'a');
+ }
+
+ private static int unHex(char c) {
+ if ('A' <= c && c <= 'F') {
+ return c - 'A' + 10;
+ } else if ('a' <= c && c <= 'f') {
+ return c - 'a' + 10;
+ } else if ('0' <= c && c <= '9') {
+ return c - '0';
+ } else {
+ return -1;
+ }
+ }
+
+ private static int unHex(char c1, char c2) {
+ int i1 = unHex(c1);
+ int i2 = unHex(c2);
+ if (i1 >= 0 && i2 >= 0) {
+ return (i1 << 4) | i2;
+ }
+ return -1;
+ }
+
+ private static String decode(String str, boolean fullUri) {
+ char[] buf = null;
+ int bufTop = 0;
+
+ for (int k = 0, length = str.length(); k != length;) {
+ char C = str.charAt(k);
+ if (C != '%') {
+ if (buf != null) {
+ buf[bufTop++] = C;
+ }
+ ++k;
+ } else {
+ if (buf == null) {
+ // decode always compress so result can not be bigger then
+ // str.length()
+ buf = new char[length];
+ str.getChars(0, k, buf, 0);
+ bufTop = k;
+ }
+ int start = k;
+ if (k + 3 > length)
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ int B = unHex(str.charAt(k + 1), str.charAt(k + 2));
+ if (B < 0) throw Context.reportRuntimeError0("msg.bad.uri");
+ k += 3;
+ if ((B & 0x80) == 0) {
+ C = (char)B;
+ } else {
+ // Decode UTF-8 sequence into ucs4Char and encode it into
+ // UTF-16
+ int utf8Tail, ucs4Char, minUcs4Char;
+ if ((B & 0xC0) == 0x80) {
+ // First UTF-8 should be ouside 0x80..0xBF
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ } else if ((B & 0x20) == 0) {
+ utf8Tail = 1; ucs4Char = B & 0x1F;
+ minUcs4Char = 0x80;
+ } else if ((B & 0x10) == 0) {
+ utf8Tail = 2; ucs4Char = B & 0x0F;
+ minUcs4Char = 0x800;
+ } else if ((B & 0x08) == 0) {
+ utf8Tail = 3; ucs4Char = B & 0x07;
+ minUcs4Char = 0x10000;
+ } else if ((B & 0x04) == 0) {
+ utf8Tail = 4; ucs4Char = B & 0x03;
+ minUcs4Char = 0x200000;
+ } else if ((B & 0x02) == 0) {
+ utf8Tail = 5; ucs4Char = B & 0x01;
+ minUcs4Char = 0x4000000;
+ } else {
+ // First UTF-8 can not be 0xFF or 0xFE
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ }
+ if (k + 3 * utf8Tail > length)
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ for (int j = 0; j != utf8Tail; j++) {
+ if (str.charAt(k) != '%')
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ B = unHex(str.charAt(k + 1), str.charAt(k + 2));
+ if (B < 0 || (B & 0xC0) != 0x80)
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ ucs4Char = (ucs4Char << 6) | (B & 0x3F);
+ k += 3;
+ }
+ // Check for overlongs and other should-not-present codes
+ if (ucs4Char < minUcs4Char
+ || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF)
+ {
+ ucs4Char = 0xFFFD;
+ }
+ if (ucs4Char >= 0x10000) {
+ ucs4Char -= 0x10000;
+ if (ucs4Char > 0xFFFFF)
+ throw Context.reportRuntimeError0("msg.bad.uri");
+ char H = (char)((ucs4Char >>> 10) + 0xD800);
+ C = (char)((ucs4Char & 0x3FF) + 0xDC00);
+ buf[bufTop++] = H;
+ } else {
+ C = (char)ucs4Char;
+ }
+ }
+ if (fullUri && URI_DECODE_RESERVED.indexOf(C) >= 0) {
+ for (int x = start; x != k; x++) {
+ buf[bufTop++] = str.charAt(x);
+ }
+ } else {
+ buf[bufTop++] = C;
+ }
+ }
+ }
+ return (buf == null) ? str : new String(buf, 0, bufTop);
+ }
+
+ private static boolean encodeUnescaped(char c, boolean fullUri) {
+ if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')
+ || ('0' <= c && c <= '9'))
+ {
+ return true;
+ }
+ if ("-_.!~*'()".indexOf(c) >= 0)
+ return true;
+ if (fullUri) {
+ return URI_DECODE_RESERVED.indexOf(c) >= 0;
+ }
+ return false;
+ }
+
+ private static final String URI_DECODE_RESERVED = ";/?:@&=+$,#";
+
+ /* Convert one UCS-4 char and write it into a UTF-8 buffer, which must be
+ * at least 6 bytes long. Return the number of UTF-8 bytes of data written.
+ */
+ private static int oneUcs4ToUtf8Char(byte[] utf8Buffer, int ucs4Char) {
+ int utf8Length = 1;
+
+ //JS_ASSERT(ucs4Char <= 0x7FFFFFFF);
+ if ((ucs4Char & ~0x7F) == 0)
+ utf8Buffer[0] = (byte)ucs4Char;
+ else {
+ int i;
+ int a = ucs4Char >>> 11;
+ utf8Length = 2;
+ while (a != 0) {
+ a >>>= 5;
+ utf8Length++;
+ }
+ i = utf8Length;
+ while (--i > 0) {
+ utf8Buffer[i] = (byte)((ucs4Char & 0x3F) | 0x80);
+ ucs4Char >>>= 6;
+ }
+ utf8Buffer[0] = (byte)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
+ }
+ return utf8Length;
+ }
+
+ private static final Object FTAG = new Object();
+
+ private static final int
+ Id_decodeURI = 1,
+ Id_decodeURIComponent = 2,
+ Id_encodeURI = 3,
+ Id_encodeURIComponent = 4,
+ Id_escape = 5,
+ Id_eval = 6,
+ Id_isFinite = 7,
+ Id_isNaN = 8,
+ Id_isXMLName = 9,
+ Id_parseFloat = 10,
+ Id_parseInt = 11,
+ Id_unescape = 12,
+ Id_uneval = 13,
+
+ LAST_SCOPE_FUNCTION_ID = 13,
+
+ Id_new_CommonError = 14;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java
new file mode 100644
index 0000000..c61f417
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeIterator.java
@@ -0,0 +1,260 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Iterator;
+
+/**
+ * This class implements iterator objects. See
+ * http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Iterators
+ *
+ * @author Norris Boyd
+ */
+public final class NativeIterator extends IdScriptableObject {
+ private static final Object ITERATOR_TAG = new Object();
+
+ static void init(ScriptableObject scope, boolean sealed) {
+ // Iterator
+ NativeIterator iterator = new NativeIterator();
+ iterator.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+
+ // Generator
+ NativeGenerator.init(scope, sealed);
+
+ // StopIteration
+ NativeObject obj = new StopIteration();
+ obj.setPrototype(getObjectPrototype(scope));
+ obj.setParentScope(scope);
+ if (sealed) { obj.sealObject(); }
+ ScriptableObject.defineProperty(scope, STOP_ITERATION, obj,
+ ScriptableObject.DONTENUM);
+ // Use "associateValue" so that generators can continue to
+ // throw StopIteration even if the property of the global
+ // scope is replaced or deleted.
+ scope.associateValue(ITERATOR_TAG, obj);
+ }
+
+ /**
+ * Only for constructing the prototype object.
+ */
+ private NativeIterator() {
+ }
+
+ private NativeIterator(Object objectIterator) {
+ this.objectIterator = objectIterator;
+ }
+
+ /**
+ * Get the value of the "StopIteration" object. Note that this value
+ * is stored in the top-level scope using "associateValue" so the
+ * value can still be found even if a script overwrites or deletes
+ * the global "StopIteration" property.
+ * @param scope a scope whose parent chain reaches a top-level scope
+ * @return the StopIteration object
+ */
+ public static Object getStopIterationObject(Scriptable scope) {
+ Scriptable top = ScriptableObject.getTopLevelScope(scope);
+ return ScriptableObject.getTopScopeValue(top, ITERATOR_TAG);
+ }
+
+ private static final String STOP_ITERATION = "StopIteration";
+ public static final String ITERATOR_PROPERTY_NAME = "__iterator__";
+
+ static class StopIteration extends NativeObject {
+ public String getClassName() {
+ return STOP_ITERATION;
+ }
+
+ /* StopIteration has custom instanceof behavior since it
+ * doesn't have a constructor.
+ */
+ public boolean hasInstance(Scriptable instance) {
+ return instance instanceof StopIteration;
+ }
+ }
+
+ public String getClassName() {
+ return "Iterator";
+ }
+
+ protected void initPrototypeId(int id) {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=2; s="constructor"; break;
+ case Id_next: arity=0; s="next"; break;
+ case Id___iterator__: arity=1; s=ITERATOR_PROPERTY_NAME; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(ITERATOR_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(ITERATOR_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+
+ if (id == Id_constructor) {
+ return jsConstructor(cx, scope, thisObj, args);
+ }
+
+ if (!(thisObj instanceof NativeIterator))
+ throw incompatibleCallError(f);
+
+ NativeIterator iterator = (NativeIterator) thisObj;
+
+ switch (id) {
+
+ case Id_next:
+ return iterator.next(cx, scope);
+
+ case Id___iterator__:
+ /// XXX: what about argument? SpiderMonkey apparently ignores it
+ return thisObj;
+
+ default:
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+ /* the javascript constructor */
+ private static Object jsConstructor(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (args.length == 0 || args[0] == null ||
+ args[0] == Undefined.instance)
+ {
+ throw ScriptRuntime.typeError1("msg.no.properties",
+ ScriptRuntime.toString(args[0]));
+ }
+ Scriptable obj = ScriptRuntime.toObject(scope, args[0]);
+ boolean keyOnly = args.length > 1 && ScriptRuntime.toBoolean(args[1]);
+ if (thisObj != null) {
+ // Called as a function. Convert to iterator if possible.
+
+ // For objects that implement java.lang.Iterable or
+ // java.util.Iterator, have JavaScript Iterator call the underlying
+ // iteration methods
+ Iterator iterator =
+ VMBridge.instance.getJavaIterator(cx, scope, obj);
+ if (iterator != null) {
+ scope = ScriptableObject.getTopLevelScope(scope);
+ return cx.getWrapFactory().wrap(cx, scope,
+ new WrappedJavaIterator(iterator, scope),
+ WrappedJavaIterator.class);
+ }
+
+ // Otherwise, just call the runtime routine
+ Scriptable jsIterator = ScriptRuntime.toIterator(cx, scope, obj,
+ keyOnly);
+ if (jsIterator != null) {
+ return jsIterator;
+ }
+ }
+
+ // Otherwise, just set up to iterate over the properties of the object.
+ // Do not call __iterator__ method.
+ Object objectIterator = ScriptRuntime.enumInit(obj, cx,
+ keyOnly ? ScriptRuntime.ENUMERATE_KEYS_NO_ITERATOR
+ : ScriptRuntime.ENUMERATE_ARRAY_NO_ITERATOR);
+ ScriptRuntime.setEnumNumbers(objectIterator, true);
+ NativeIterator result = new NativeIterator(objectIterator);
+ result.setPrototype(NativeIterator.getClassPrototype(scope,
+ result.getClassName()));
+ result.setParentScope(scope);
+ return result;
+ }
+
+ private Object next(Context cx, Scriptable scope) {
+ Boolean b = ScriptRuntime.enumNext(this.objectIterator);
+ if (!b.booleanValue()) {
+ // Out of values. Throw StopIteration.
+ throw new JavaScriptException(
+ NativeIterator.getStopIterationObject(scope), null, 0);
+ }
+ return ScriptRuntime.enumId(this.objectIterator, cx);
+ }
+
+ static public class WrappedJavaIterator
+ {
+ WrappedJavaIterator(Iterator iterator, Scriptable scope) {
+ this.iterator = iterator;
+ this.scope = scope;
+ }
+
+ public Object next() {
+ if (!iterator.hasNext()) {
+ // Out of values. Throw StopIteration.
+ throw new JavaScriptException(
+ NativeIterator.getStopIterationObject(scope), null, 0);
+ }
+ return iterator.next();
+ }
+
+ public Object __iterator__(boolean b) {
+ return this;
+ }
+
+ private Iterator iterator;
+ private Scriptable scope;
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s) {
+ int id;
+// #generated# Last update: 2007-06-11 09:43:19 EDT
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==4) { X="next";id=Id_next; }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ else if (s_length==12) { X="__iterator__";id=Id___iterator__; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_next = 2,
+ Id___iterator__ = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+// #/string_id_map#
+
+ private Object objectIterator;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java
new file mode 100644
index 0000000..2f711a0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaArray.java
@@ -0,0 +1,168 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Frank Mitchell
+ * Mike Shaver
+ * Kemal Bayram
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.Array;
+
+/**
+ * This class reflects Java arrays into the JavaScript environment.
+ *
+ * @author Mike Shaver
+ * @see NativeJavaClass
+ * @see NativeJavaObject
+ * @see NativeJavaPackage
+ */
+
+public class NativeJavaArray extends NativeJavaObject
+{
+ static final long serialVersionUID = -924022554283675333L;
+
+ public String getClassName() {
+ return "JavaArray";
+ }
+
+ public static NativeJavaArray wrap(Scriptable scope, Object array) {
+ return new NativeJavaArray(scope, array);
+ }
+
+ public Object unwrap() {
+ return array;
+ }
+
+ public NativeJavaArray(Scriptable scope, Object array) {
+ super(scope, null, ScriptRuntime.ObjectClass);
+ Class cl = array.getClass();
+ if (!cl.isArray()) {
+ throw new RuntimeException("Array expected");
+ }
+ this.array = array;
+ this.length = Array.getLength(array);
+ this.cls = cl.getComponentType();
+ }
+
+ public boolean has(String id, Scriptable start) {
+ return id.equals("length") || super.has(id, start);
+ }
+
+ public boolean has(int index, Scriptable start) {
+ return 0 <= index && index < length;
+ }
+
+ public Object get(String id, Scriptable start) {
+ if (id.equals("length"))
+ return new Integer(length);
+ Object result = super.get(id, start);
+ if (result == NOT_FOUND &&
+ !ScriptableObject.hasProperty(getPrototype(), id))
+ {
+ throw Context.reportRuntimeError2(
+ "msg.java.member.not.found", array.getClass().getName(), id);
+ }
+ return result;
+ }
+
+ public Object get(int index, Scriptable start) {
+ if (0 <= index && index < length) {
+ Context cx = Context.getContext();
+ Object obj = Array.get(array, index);
+ return cx.getWrapFactory().wrap(cx, this, obj, cls);
+ }
+ return Undefined.instance;
+ }
+
+ public void put(String id, Scriptable start, Object value) {
+ // Ignore assignments to "length"--it's readonly.
+ if (!id.equals("length"))
+ throw Context.reportRuntimeError1(
+ "msg.java.array.member.not.found", id);
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ if (0 <= index && index < length) {
+ Array.set(array, index, Context.jsToJava(value, cls));
+ }
+ else {
+ throw Context.reportRuntimeError2(
+ "msg.java.array.index.out.of.bounds", String.valueOf(index),
+ String.valueOf(length - 1));
+ }
+ }
+
+ public Object getDefaultValue(Class hint) {
+ if (hint == null || hint == ScriptRuntime.StringClass)
+ return array.toString();
+ if (hint == ScriptRuntime.BooleanClass)
+ return Boolean.TRUE;
+ if (hint == ScriptRuntime.NumberClass)
+ return ScriptRuntime.NaNobj;
+ return this;
+ }
+
+ public Object[] getIds() {
+ Object[] result = new Object[length];
+ int i = length;
+ while (--i >= 0)
+ result[i] = new Integer(i);
+ return result;
+ }
+
+ public boolean hasInstance(Scriptable value) {
+ if (!(value instanceof Wrapper))
+ return false;
+ Object instance = ((Wrapper)value).unwrap();
+ return cls.isInstance(instance);
+ }
+
+ public Scriptable getPrototype() {
+ if (prototype == null) {
+ prototype =
+ ScriptableObject.getClassPrototype(this.getParentScope(),
+ "Array");
+ }
+ return prototype;
+ }
+
+ Object array;
+ int length;
+ Class cls;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java
new file mode 100644
index 0000000..ab8af5c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaClass.java
@@ -0,0 +1,320 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Frank Mitchell
+ * Mike Shaver
+ * Kurt Westerfeld
+ * Kemal Bayram
+ * Ulrike Mueller <umueller@demandware.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+import java.util.Hashtable;
+
+/**
+ * This class reflects Java classes into the JavaScript environment, mainly
+ * for constructors and static members. We lazily reflect properties,
+ * and currently do not guarantee that a single j.l.Class is only
+ * reflected once into the JS environment, although we should.
+ * The only known case where multiple reflections
+ * are possible occurs when a j.l.Class is wrapped as part of a
+ * method return or property access, rather than by walking the
+ * Packages/java tree.
+ *
+ * @author Mike Shaver
+ * @see NativeJavaArray
+ * @see NativeJavaObject
+ * @see NativeJavaPackage
+ */
+
+public class NativeJavaClass extends NativeJavaObject implements Function
+{
+ static final long serialVersionUID = -6460763940409461664L;
+
+ // Special property for getting the underlying Java class object.
+ static final String javaClassPropertyName = "__javaObject__";
+
+ public NativeJavaClass() {
+ }
+
+ public NativeJavaClass(Scriptable scope, Class cl) {
+ this.parent = scope;
+ this.javaObject = cl;
+ initMembers();
+ }
+
+ protected void initMembers() {
+ Class cl = (Class)javaObject;
+ members = JavaMembers.lookupClass(parent, cl, cl, false);
+ staticFieldAndMethods
+ = members.getFieldAndMethodsObjects(this, cl, true);
+ }
+
+ public String getClassName() {
+ return "JavaClass";
+ }
+
+ public boolean has(String name, Scriptable start) {
+ return members.has(name, true) || javaClassPropertyName.equals(name);
+ }
+
+ public Object get(String name, Scriptable start) {
+ // When used as a constructor, ScriptRuntime.newObject() asks
+ // for our prototype to create an object of the correct type.
+ // We don't really care what the object is, since we're returning
+ // one constructed out of whole cloth, so we return null.
+ if (name.equals("prototype"))
+ return null;
+
+ if (staticFieldAndMethods != null) {
+ Object result = staticFieldAndMethods.get(name);
+ if (result != null)
+ return result;
+ }
+
+ if (members.has(name, true)) {
+ return members.get(this, name, javaObject, true);
+ }
+
+ if (javaClassPropertyName.equals(name)) {
+ Context cx = Context.getContext();
+ Scriptable scope = ScriptableObject.getTopLevelScope(start);
+ return cx.getWrapFactory().wrap(cx, scope, javaObject,
+ ScriptRuntime.ClassClass);
+ }
+
+ // experimental: look for nested classes by appending $name to
+ // current class' name.
+ Class nestedClass = findNestedClass(getClassObject(), name);
+ if (nestedClass != null) {
+ NativeJavaClass nestedValue = new NativeJavaClass
+ (ScriptableObject.getTopLevelScope(this), nestedClass);
+ nestedValue.setParentScope(this);
+ return nestedValue;
+ }
+
+ throw members.reportMemberNotFound(name);
+ }
+
+ public void put(String name, Scriptable start, Object value) {
+ members.put(this, name, javaObject, value, true);
+ }
+
+ public Object[] getIds() {
+ return members.getIds(true);
+ }
+
+ public Class getClassObject() {
+ return (Class) super.unwrap();
+ }
+
+ public Object getDefaultValue(Class hint) {
+ if (hint == null || hint == ScriptRuntime.StringClass)
+ return this.toString();
+ if (hint == ScriptRuntime.BooleanClass)
+ return Boolean.TRUE;
+ if (hint == ScriptRuntime.NumberClass)
+ return ScriptRuntime.NaNobj;
+ return this;
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ // If it looks like a "cast" of an object to this class type,
+ // walk the prototype chain to see if there's a wrapper of a
+ // object that's an instanceof this class.
+ if (args.length == 1 && args[0] instanceof Scriptable) {
+ Class c = getClassObject();
+ Scriptable p = (Scriptable) args[0];
+ do {
+ if (p instanceof Wrapper) {
+ Object o = ((Wrapper) p).unwrap();
+ if (c.isInstance(o))
+ return p;
+ }
+ p = p.getPrototype();
+ } while (p != null);
+ }
+ return construct(cx, scope, args);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ Class classObject = getClassObject();
+ int modifiers = classObject.getModifiers();
+ if (! (Modifier.isInterface(modifiers) ||
+ Modifier.isAbstract(modifiers)))
+ {
+ MemberBox[] ctors = members.ctors;
+ int index = NativeJavaMethod.findFunction(cx, ctors, args);
+ if (index < 0) {
+ String sig = NativeJavaMethod.scriptSignature(args);
+ throw Context.reportRuntimeError2(
+ "msg.no.java.ctor", classObject.getName(), sig);
+ }
+
+ // Found the constructor, so try invoking it.
+ return constructSpecific(cx, scope, args, ctors[index]);
+ } else {
+ Scriptable topLevel = ScriptableObject.getTopLevelScope(this);
+ String msg = "";
+ try {
+ // trying to construct an interface; use JavaAdapter to
+ // construct a new class on the fly that implements this
+ // interface.
+ Object v = topLevel.get("JavaAdapter", topLevel);
+ if (v != NOT_FOUND) {
+ Function f = (Function) v;
+ Object[] adapterArgs = { this, args[0] };
+ return f.construct(cx, topLevel,adapterArgs);
+ }
+ } catch (Exception ex) {
+ // fall through to error
+ String m = ex.getMessage();
+ if (m != null)
+ msg = m;
+ }
+ throw Context.reportRuntimeError2(
+ "msg.cant.instantiate", msg, classObject.getName());
+ }
+ }
+
+ static Scriptable constructSpecific(Context cx, Scriptable scope,
+ Object[] args, MemberBox ctor)
+ {
+ Scriptable topLevel = ScriptableObject.getTopLevelScope(scope);
+ Class[] argTypes = ctor.argTypes;
+
+ if (ctor.vararg) {
+ // marshall the explicit parameter
+ Object[] newArgs = new Object[argTypes.length];
+ for (int i = 0; i < argTypes.length-1; i++) {
+ newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
+ }
+
+ Object varArgs;
+
+ // Handle special situation where a single variable parameter
+ // is given and it is a Java or ECMA array.
+ if (args.length == argTypes.length &&
+ (args[args.length-1] == null ||
+ args[args.length-1] instanceof NativeArray ||
+ args[args.length-1] instanceof NativeJavaArray))
+ {
+ // convert the ECMA array into a native array
+ varArgs = Context.jsToJava(args[args.length-1],
+ argTypes[argTypes.length - 1]);
+ } else {
+ // marshall the variable parameter
+ Class componentType = argTypes[argTypes.length - 1].
+ getComponentType();
+ varArgs = Array.newInstance(componentType,
+ args.length - argTypes.length + 1);
+ for (int i=0; i < Array.getLength(varArgs); i++) {
+ Object value = Context.jsToJava(args[argTypes.length-1 + i],
+ componentType);
+ Array.set(varArgs, i, value);
+ }
+ }
+
+ // add varargs
+ newArgs[argTypes.length-1] = varArgs;
+ // replace the original args with the new one
+ args = newArgs;
+ } else {
+ Object[] origArgs = args;
+ for (int i = 0; i < args.length; i++) {
+ Object arg = args[i];
+ Object x = Context.jsToJava(arg, argTypes[i]);
+ if (x != arg) {
+ if (args == origArgs) {
+ args = origArgs.clone();
+ }
+ args[i] = x;
+ }
+ }
+ }
+
+ Object instance = ctor.newInstance(args);
+ // we need to force this to be wrapped, because construct _has_
+ // to return a scriptable
+ return cx.getWrapFactory().wrapNewObject(cx, topLevel, instance);
+ }
+
+ public String toString() {
+ return "[JavaClass " + getClassObject().getName() + "]";
+ }
+
+ /**
+ * Determines if prototype is a wrapped Java object and performs
+ * a Java "instanceof".
+ * Exception: if value is an instance of NativeJavaClass, it isn't
+ * considered an instance of the Java class; this forestalls any
+ * name conflicts between java.lang.Class's methods and the
+ * static methods exposed by a JavaNativeClass.
+ */
+ public boolean hasInstance(Scriptable value) {
+
+ if (value instanceof Wrapper &&
+ !(value instanceof NativeJavaClass)) {
+ Object instance = ((Wrapper)value).unwrap();
+
+ return getClassObject().isInstance(instance);
+ }
+
+ // value wasn't something we understand
+ return false;
+ }
+
+ private static Class findNestedClass(Class parentClass, String name) {
+ String nestedClassName = parentClass.getName() + '$' + name;
+ ClassLoader loader = parentClass.getClassLoader();
+ if (loader == null) {
+ // ALERT: if loader is null, nested class should be loaded
+ // via system class loader which can be different from the
+ // loader that brought Rhino classes that Class.forName() would
+ // use, but ClassLoader.getSystemClassLoader() is Java 2 only
+ return Kit.classOrNull(nestedClassName);
+ } else {
+ return Kit.classOrNull(loader, nestedClassName);
+ }
+ }
+
+ private Hashtable staticFieldAndMethods;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java
new file mode 100644
index 0000000..530bf81
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaConstructor.java
@@ -0,0 +1,85 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Frank Mitchell
+ * Mike Shaver
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class reflects a single Java constructor into the JavaScript
+ * environment. It satisfies a request for an overloaded constructor,
+ * as introduced in LiveConnect 3.
+ * All NativeJavaConstructors behave as JSRef `bound' methods, in that they
+ * always construct the same NativeJavaClass regardless of any reparenting
+ * that may occur.
+ *
+ * @author Frank Mitchell
+ * @see NativeJavaMethod
+ * @see NativeJavaPackage
+ * @see NativeJavaClass
+ */
+
+public class NativeJavaConstructor extends BaseFunction
+{
+ static final long serialVersionUID = -8149253217482668463L;
+
+ MemberBox ctor;
+
+ public NativeJavaConstructor(MemberBox ctor)
+ {
+ this.ctor = ctor;
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return NativeJavaClass.constructSpecific(cx, scope, args, ctor);
+ }
+
+ public String getFunctionName()
+ {
+ String sig = JavaMembers.liveConnectSignature(ctor.argTypes);
+ return "<init>".concat(sig);
+ }
+
+ public String toString()
+ {
+ return "[JavaConstructor " + ctor.getName() + "]";
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java
new file mode 100644
index 0000000..eb66f40
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaMethod.java
@@ -0,0 +1,576 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Frank Mitchell
+ * Mike Shaver
+ * Ulrike Mueller <umueller@demandware.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+
+/**
+ * This class reflects Java methods into the JavaScript environment and
+ * handles overloading of methods.
+ *
+ * @author Mike Shaver
+ * @see NativeJavaArray
+ * @see NativeJavaPackage
+ * @see NativeJavaClass
+ */
+
+public class NativeJavaMethod extends BaseFunction
+{
+ static final long serialVersionUID = -3440381785576412928L;
+
+ NativeJavaMethod(MemberBox[] methods)
+ {
+ this.functionName = methods[0].getName();
+ this.methods = methods;
+ }
+
+ NativeJavaMethod(MemberBox method, String name)
+ {
+ this.functionName = name;
+ this.methods = new MemberBox[] { method };
+ }
+
+ public NativeJavaMethod(Method method, String name)
+ {
+ this(new MemberBox(method), name);
+ }
+
+ public String getFunctionName()
+ {
+ return functionName;
+ }
+
+ static String scriptSignature(Object[] values)
+ {
+ StringBuffer sig = new StringBuffer();
+ for (int i = 0; i != values.length; ++i) {
+ Object value = values[i];
+
+ String s;
+ if (value == null) {
+ s = "null";
+ } else if (value instanceof Boolean) {
+ s = "boolean";
+ } else if (value instanceof String) {
+ s = "string";
+ } else if (value instanceof Number) {
+ s = "number";
+ } else if (value instanceof Scriptable) {
+ if (value instanceof Undefined) {
+ s = "undefined";
+ } else if (value instanceof Wrapper) {
+ Object wrapped = ((Wrapper)value).unwrap();
+ s = wrapped.getClass().getName();
+ } else if (value instanceof Function) {
+ s = "function";
+ } else {
+ s = "object";
+ }
+ } else {
+ s = JavaMembers.javaSignature(value.getClass());
+ }
+
+ if (i != 0) {
+ sig.append(',');
+ }
+ sig.append(s);
+ }
+ return sig.toString();
+ }
+
+ String decompile(int indent, int flags)
+ {
+ StringBuffer sb = new StringBuffer();
+ boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ if (!justbody) {
+ sb.append("function ");
+ sb.append(getFunctionName());
+ sb.append("() {");
+ }
+ sb.append("/*\n");
+ sb.append(toString());
+ sb.append(justbody ? "*/\n" : "*/}\n");
+ return sb.toString();
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, N = methods.length; i != N; ++i) {
+ Method method = methods[i].method();
+ sb.append(JavaMembers.javaSignature(method.getReturnType()));
+ sb.append(' ');
+ sb.append(method.getName());
+ sb.append(JavaMembers.liveConnectSignature(methods[i].argTypes));
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ // Find a method that matches the types given.
+ if (methods.length == 0) {
+ throw new RuntimeException("No methods defined for call");
+ }
+
+ int index = findFunction(cx, methods, args);
+ if (index < 0) {
+ Class c = methods[0].method().getDeclaringClass();
+ String sig = c.getName() + '.' + getFunctionName() + '(' +
+ scriptSignature(args) + ')';
+ throw Context.reportRuntimeError1("msg.java.no_such_method", sig);
+ }
+
+ MemberBox meth = methods[index];
+ Class[] argTypes = meth.argTypes;
+
+ if (meth.vararg) {
+ // marshall the explicit parameters
+ Object[] newArgs = new Object[argTypes.length];
+ for (int i = 0; i < argTypes.length-1; i++) {
+ newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
+ }
+
+ Object varArgs;
+
+ // Handle special situation where a single variable parameter
+ // is given and it is a Java or ECMA array or is null.
+ if (args.length == argTypes.length &&
+ (args[args.length-1] == null ||
+ args[args.length-1] instanceof NativeArray ||
+ args[args.length-1] instanceof NativeJavaArray))
+ {
+ // convert the ECMA array into a native array
+ varArgs = Context.jsToJava(args[args.length-1],
+ argTypes[argTypes.length - 1]);
+ } else {
+ // marshall the variable parameters
+ Class componentType = argTypes[argTypes.length - 1].
+ getComponentType();
+ varArgs = Array.newInstance(componentType,
+ args.length - argTypes.length + 1);
+ for (int i = 0; i < Array.getLength(varArgs); i++) {
+ Object value = Context.jsToJava(args[argTypes.length-1 + i],
+ componentType);
+ Array.set(varArgs, i, value);
+ }
+ }
+
+ // add varargs
+ newArgs[argTypes.length-1] = varArgs;
+ // replace the original args with the new one
+ args = newArgs;
+ } else {
+ // First, we marshall the args.
+ Object[] origArgs = args;
+ for (int i = 0; i < args.length; i++) {
+ Object arg = args[i];
+ Object coerced = Context.jsToJava(arg, argTypes[i]);
+ if (coerced != arg) {
+ if (origArgs == args) {
+ args = args.clone();
+ }
+ args[i] = coerced;
+ }
+ }
+ }
+ Object javaObject;
+ if (meth.isStatic()) {
+ javaObject = null; // don't need an object
+ } else {
+ Scriptable o = thisObj;
+ Class c = meth.getDeclaringClass();
+ for (;;) {
+ if (o == null) {
+ throw Context.reportRuntimeError3(
+ "msg.nonjava.method", getFunctionName(),
+ ScriptRuntime.toString(thisObj), c.getName());
+ }
+ if (o instanceof Wrapper) {
+ javaObject = ((Wrapper)o).unwrap();
+ if (c.isInstance(javaObject)) {
+ break;
+ }
+ }
+ o = o.getPrototype();
+ }
+ }
+ if (debug) {
+ printDebug("Calling ", meth, args);
+ }
+
+ Object retval = meth.invoke(javaObject, args);
+ Class staticType = meth.method().getReturnType();
+
+ if (debug) {
+ Class actualType = (retval == null) ? null
+ : retval.getClass();
+ System.err.println(" ----- Returned " + retval +
+ " actual = " + actualType +
+ " expect = " + staticType);
+ }
+
+ Object wrapped = cx.getWrapFactory().wrap(cx, scope,
+ retval, staticType);
+ if (debug) {
+ Class actualType = (wrapped == null) ? null
+ : wrapped.getClass();
+ System.err.println(" ----- Wrapped as " + wrapped +
+ " class = " + actualType);
+ }
+
+ if (wrapped == null && staticType == Void.TYPE) {
+ wrapped = Undefined.instance;
+ }
+ return wrapped;
+ }
+
+ /**
+ * Find the index of the correct function to call given the set of methods
+ * or constructors and the arguments.
+ * If no function can be found to call, return -1.
+ */
+ static int findFunction(Context cx,
+ MemberBox[] methodsOrCtors, Object[] args)
+ {
+ if (methodsOrCtors.length == 0) {
+ return -1;
+ } else if (methodsOrCtors.length == 1) {
+ MemberBox member = methodsOrCtors[0];
+ Class[] argTypes = member.argTypes;
+ int alength = argTypes.length;
+
+ if (member.vararg) {
+ alength--;
+ if ( alength > args.length) {
+ return -1;
+ }
+ } else {
+ if (alength != args.length) {
+ return -1;
+ }
+ }
+ for (int j = 0; j != alength; ++j) {
+ if (!NativeJavaObject.canConvert(args[j], argTypes[j])) {
+ if (debug) printDebug("Rejecting (args can't convert) ",
+ member, args);
+ return -1;
+ }
+ }
+ if (debug) printDebug("Found ", member, args);
+ return 0;
+ }
+
+ int firstBestFit = -1;
+ int[] extraBestFits = null;
+ int extraBestFitsCount = 0;
+
+ search:
+ for (int i = 0; i < methodsOrCtors.length; i++) {
+ MemberBox member = methodsOrCtors[i];
+ Class[] argTypes = member.argTypes;
+ int alength = argTypes.length;
+ if (member.vararg) {
+ alength--;
+ if ( alength > args.length) {
+ continue search;
+ }
+ } else {
+ if (alength != args.length) {
+ continue search;
+ }
+ }
+ for (int j = 0; j < alength; j++) {
+ if (!NativeJavaObject.canConvert(args[j], argTypes[j])) {
+ if (debug) printDebug("Rejecting (args can't convert) ",
+ member, args);
+ continue search;
+ }
+ }
+ if (firstBestFit < 0) {
+ if (debug) printDebug("Found first applicable ", member, args);
+ firstBestFit = i;
+ } else {
+ // Compare with all currently fit methods.
+ // The loop starts from -1 denoting firstBestFit and proceed
+ // until extraBestFitsCount to avoid extraBestFits allocation
+ // in the most common case of no ambiguity
+ int betterCount = 0; // number of times member was prefered over
+ // best fits
+ int worseCount = 0; // number of times best fits were prefered
+ // over member
+ for (int j = -1; j != extraBestFitsCount; ++j) {
+ int bestFitIndex;
+ if (j == -1) {
+ bestFitIndex = firstBestFit;
+ } else {
+ bestFitIndex = extraBestFits[j];
+ }
+ MemberBox bestFit = methodsOrCtors[bestFitIndex];
+ if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS) &&
+ (bestFit.member().getModifiers() & Modifier.PUBLIC) !=
+ (member.member().getModifiers() & Modifier.PUBLIC))
+ {
+ // When FEATURE_ENHANCED_JAVA_ACCESS gives us access
+ // to non-public members, continue to prefer public
+ // methods in overloading
+ if ((bestFit.member().getModifiers() & Modifier.PUBLIC) == 0)
+ ++betterCount;
+ else
+ ++worseCount;
+ } else {
+ int preference = preferSignature(args, argTypes,
+ member.vararg,
+ bestFit.argTypes,
+ bestFit.vararg );
+ if (preference == PREFERENCE_AMBIGUOUS) {
+ break;
+ } else if (preference == PREFERENCE_FIRST_ARG) {
+ ++betterCount;
+ } else if (preference == PREFERENCE_SECOND_ARG) {
+ ++worseCount;
+ } else {
+ if (preference != PREFERENCE_EQUAL) Kit.codeBug();
+ // This should not happen in theory
+ // but on some JVMs, Class.getMethods will return all
+ // static methods of the class heirarchy, even if
+ // a derived class's parameters match exactly.
+ // We want to call the dervied class's method.
+ if (bestFit.isStatic()
+ && bestFit.getDeclaringClass().isAssignableFrom(
+ member.getDeclaringClass()))
+ {
+ // On some JVMs, Class.getMethods will return all
+ // static methods of the class heirarchy, even if
+ // a derived class's parameters match exactly.
+ // We want to call the dervied class's method.
+ if (debug) printDebug(
+ "Substituting (overridden static)",
+ member, args);
+ if (j == -1) {
+ firstBestFit = i;
+ } else {
+ extraBestFits[j] = i;
+ }
+ } else {
+ if (debug) printDebug(
+ "Ignoring same signature member ",
+ member, args);
+ }
+ continue search;
+ }
+ }
+ }
+ if (betterCount == 1 + extraBestFitsCount) {
+ // member was prefered over all best fits
+ if (debug) printDebug(
+ "New first applicable ", member, args);
+ firstBestFit = i;
+ extraBestFitsCount = 0;
+ } else if (worseCount == 1 + extraBestFitsCount) {
+ // all best fits were prefered over member, ignore it
+ if (debug) printDebug(
+ "Rejecting (all current bests better) ", member, args);
+ } else {
+ // some ambiguity was present, add member to best fit set
+ if (debug) printDebug(
+ "Added to best fit set ", member, args);
+ if (extraBestFits == null) {
+ // Allocate maximum possible array
+ extraBestFits = new int[methodsOrCtors.length - 1];
+ }
+ extraBestFits[extraBestFitsCount] = i;
+ ++extraBestFitsCount;
+ }
+ }
+ }
+
+ if (firstBestFit < 0) {
+ // Nothing was found
+ return -1;
+ } else if (extraBestFitsCount == 0) {
+ // single best fit
+ return firstBestFit;
+ }
+
+ // report remaining ambiguity
+ StringBuffer buf = new StringBuffer();
+ for (int j = -1; j != extraBestFitsCount; ++j) {
+ int bestFitIndex;
+ if (j == -1) {
+ bestFitIndex = firstBestFit;
+ } else {
+ bestFitIndex = extraBestFits[j];
+ }
+ buf.append("\n ");
+ buf.append(methodsOrCtors[bestFitIndex].toJavaDeclaration());
+ }
+
+ MemberBox firstFitMember = methodsOrCtors[firstBestFit];
+ String memberName = firstFitMember.getName();
+ String memberClass = firstFitMember.getDeclaringClass().getName();
+
+ if (methodsOrCtors[0].isMethod()) {
+ throw Context.reportRuntimeError3(
+ "msg.constructor.ambiguous",
+ memberName, scriptSignature(args), buf.toString());
+ } else {
+ throw Context.reportRuntimeError4(
+ "msg.method.ambiguous", memberClass,
+ memberName, scriptSignature(args), buf.toString());
+ }
+ }
+
+ /** Types are equal */
+ private static final int PREFERENCE_EQUAL = 0;
+ private static final int PREFERENCE_FIRST_ARG = 1;
+ private static final int PREFERENCE_SECOND_ARG = 2;
+ /** No clear "easy" conversion */
+ private static final int PREFERENCE_AMBIGUOUS = 3;
+
+ /**
+ * Determine which of two signatures is the closer fit.
+ * Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG,
+ * PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS.
+ */
+ private static int preferSignature(Object[] args,
+ Class[] sig1,
+ boolean vararg1,
+ Class[] sig2,
+ boolean vararg2 )
+ {
+ // TODO: This test is pretty primitive. It bascially prefers
+ // a matching no vararg method over a vararg method independent
+ // of the type conversion cost. This can lead to unexpected results.
+ int alength = args.length;
+ if (!vararg1 && vararg2) {
+ // prefer the no vararg signature
+ return PREFERENCE_FIRST_ARG;
+ } else if (vararg1 && !vararg2) {
+ // prefer the no vararg signature
+ return PREFERENCE_SECOND_ARG;
+ } else if (vararg1 && vararg2) {
+ if (sig1.length < sig2.length) {
+ // prefer the signature with more explicit types
+ return PREFERENCE_SECOND_ARG;
+ } else if (sig1.length > sig2.length) {
+ // prefer the signature with more explicit types
+ return PREFERENCE_FIRST_ARG;
+ } else {
+ // Both are varargs and have the same length, so make the
+ // decision with the explicit args.
+ alength = Math.min(args.length, sig1.length-1);
+ }
+ }
+
+ int totalPreference = 0;
+ for (int j = 0; j < alength; j++) {
+ Class type1 = sig1[j];
+ Class type2 = sig2[j];
+ if (type1 == type2) {
+ continue;
+ }
+ Object arg = args[j];
+
+ // Determine which of type1, type2 is easier to convert from arg.
+
+ int rank1 = NativeJavaObject.getConversionWeight(arg, type1);
+ int rank2 = NativeJavaObject.getConversionWeight(arg, type2);
+
+ int preference;
+ if (rank1 < rank2) {
+ preference = PREFERENCE_FIRST_ARG;
+ } else if (rank1 > rank2) {
+ preference = PREFERENCE_SECOND_ARG;
+ } else {
+ // Equal ranks
+ if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) {
+ if (type1.isAssignableFrom(type2)) {
+ preference = PREFERENCE_SECOND_ARG;
+ } else if (type2.isAssignableFrom(type1)) {
+ preference = PREFERENCE_FIRST_ARG;
+ } else {
+ preference = PREFERENCE_AMBIGUOUS;
+ }
+ } else {
+ preference = PREFERENCE_AMBIGUOUS;
+ }
+ }
+
+ totalPreference |= preference;
+
+ if (totalPreference == PREFERENCE_AMBIGUOUS) {
+ break;
+ }
+ }
+ return totalPreference;
+ }
+
+
+ private static final boolean debug = false;
+
+ private static void printDebug(String msg, MemberBox member,
+ Object[] args)
+ {
+ if (debug) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(" ----- ");
+ sb.append(msg);
+ sb.append(member.getDeclaringClass().getName());
+ sb.append('.');
+ if (member.isMethod()) {
+ sb.append(member.getName());
+ }
+ sb.append(JavaMembers.liveConnectSignature(member.argTypes));
+ sb.append(" for arguments (");
+ sb.append(scriptSignature(args));
+ sb.append(')');
+ System.out.println(sb);
+ }
+ }
+
+ MemberBox[] methods;
+ private String functionName;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
new file mode 100644
index 0000000..3d27852
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaObject.java
@@ -0,0 +1,1002 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Frank Mitchell
+ * Mike Shaver
+ * Kemal Bayram
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.Hashtable;
+import java.util.Date;
+
+/**
+ * This class reflects non-Array Java objects into the JavaScript environment. It
+ * reflect fields directly, and uses NativeJavaMethod objects to reflect (possibly
+ * overloaded) methods.<p>
+ *
+ * @author Mike Shaver
+ * @see NativeJavaArray
+ * @see NativeJavaPackage
+ * @see NativeJavaClass
+ */
+
+public class NativeJavaObject implements Scriptable, Wrapper, Serializable
+{
+ static final long serialVersionUID = -6948590651130498591L;
+
+ public NativeJavaObject() { }
+
+ public NativeJavaObject(Scriptable scope, Object javaObject,
+ Class staticType)
+ {
+ this(scope, javaObject, staticType, false);
+ }
+
+ public NativeJavaObject(Scriptable scope, Object javaObject,
+ Class staticType, boolean isAdapter)
+ {
+ this.parent = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
+ this.javaObject = javaObject;
+ this.staticType = staticType;
+ this.isAdapter = isAdapter;
+ initMembers();
+ }
+
+ protected void initMembers() {
+ Class dynamicType;
+ if (javaObject != null) {
+ dynamicType = javaObject.getClass();
+ } else {
+ dynamicType = staticType;
+ }
+ members = JavaMembers.lookupClass(parent, dynamicType, staticType,
+ isAdapter);
+ fieldAndMethods
+ = members.getFieldAndMethodsObjects(this, javaObject, false);
+ }
+
+ public boolean has(String name, Scriptable start) {
+ return members.has(name, false);
+ }
+
+ public boolean has(int index, Scriptable start) {
+ return false;
+ }
+
+ public Object get(String name, Scriptable start) {
+ if (fieldAndMethods != null) {
+ Object result = fieldAndMethods.get(name);
+ if (result != null) {
+ return result;
+ }
+ }
+ // TODO: passing 'this' as the scope is bogus since it has
+ // no parent scope
+ return members.get(this, name, javaObject, false);
+ }
+
+ public Object get(int index, Scriptable start) {
+ throw members.reportMemberNotFound(Integer.toString(index));
+ }
+
+ public void put(String name, Scriptable start, Object value) {
+ // We could be asked to modify the value of a property in the
+ // prototype. Since we can't add a property to a Java object,
+ // we modify it in the prototype rather than copy it down.
+ if (prototype == null || members.has(name, false))
+ members.put(this, name, javaObject, value, false);
+ else
+ prototype.put(name, prototype, value);
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ throw members.reportMemberNotFound(Integer.toString(index));
+ }
+
+ public boolean hasInstance(Scriptable value) {
+ // This is an instance of a Java class, so always return false
+ return false;
+ }
+
+ public void delete(String name) {
+ }
+
+ public void delete(int index) {
+ }
+
+ public Scriptable getPrototype() {
+ if (prototype == null && javaObject instanceof String) {
+ return ScriptableObject.getClassPrototype(parent, "String");
+ }
+ return prototype;
+ }
+
+ /**
+ * Sets the prototype of the object.
+ */
+ public void setPrototype(Scriptable m) {
+ prototype = m;
+ }
+
+ /**
+ * Returns the parent (enclosing) scope of the object.
+ */
+ public Scriptable getParentScope() {
+ return parent;
+ }
+
+ /**
+ * Sets the parent (enclosing) scope of the object.
+ */
+ public void setParentScope(Scriptable m) {
+ parent = m;
+ }
+
+ public Object[] getIds() {
+ return members.getIds(false);
+ }
+
+/**
+@deprecated Use {@link Context#getWrapFactory()} together with calling {@link
+WrapFactory#wrap(Context, Scriptable, Object, Class)}
+*/
+ public static Object wrap(Scriptable scope, Object obj, Class staticType) {
+
+ Context cx = Context.getContext();
+ return cx.getWrapFactory().wrap(cx, scope, obj, staticType);
+ }
+
+ public Object unwrap() {
+ return javaObject;
+ }
+
+ public String getClassName() {
+ return "JavaObject";
+ }
+
+ public Object getDefaultValue(Class hint)
+ {
+ Object value;
+ if (hint == null) {
+ if (javaObject instanceof Boolean) {
+ hint = ScriptRuntime.BooleanClass;
+ }
+ }
+ if (hint == null || hint == ScriptRuntime.StringClass) {
+ value = javaObject.toString();
+ } else {
+ String converterName;
+ if (hint == ScriptRuntime.BooleanClass) {
+ converterName = "booleanValue";
+ } else if (hint == ScriptRuntime.NumberClass) {
+ converterName = "doubleValue";
+ } else {
+ throw Context.reportRuntimeError0("msg.default.value");
+ }
+ Object converterObject = get(converterName, this);
+ if (converterObject instanceof Function) {
+ Function f = (Function)converterObject;
+ value = f.call(Context.getContext(), f.getParentScope(),
+ this, ScriptRuntime.emptyArgs);
+ } else {
+ if (hint == ScriptRuntime.NumberClass
+ && javaObject instanceof Boolean)
+ {
+ boolean b = ((Boolean)javaObject).booleanValue();
+ value = ScriptRuntime.wrapNumber(b ? 1.0 : 0.0);
+ } else {
+ value = javaObject.toString();
+ }
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Determine whether we can/should convert between the given type and the
+ * desired one. This should be superceded by a conversion-cost calculation
+ * function, but for now I'll hide behind precedent.
+ */
+ public static boolean canConvert(Object fromObj, Class to) {
+ int weight = getConversionWeight(fromObj, to);
+
+ return (weight < CONVERSION_NONE);
+ }
+
+ private static final int JSTYPE_UNDEFINED = 0; // undefined type
+ private static final int JSTYPE_NULL = 1; // null
+ private static final int JSTYPE_BOOLEAN = 2; // boolean
+ private static final int JSTYPE_NUMBER = 3; // number
+ private static final int JSTYPE_STRING = 4; // string
+ private static final int JSTYPE_JAVA_CLASS = 5; // JavaClass
+ private static final int JSTYPE_JAVA_OBJECT = 6; // JavaObject
+ private static final int JSTYPE_JAVA_ARRAY = 7; // JavaArray
+ private static final int JSTYPE_OBJECT = 8; // Scriptable
+
+ static final byte CONVERSION_TRIVIAL = 1;
+ static final byte CONVERSION_NONTRIVIAL = 0;
+ static final byte CONVERSION_NONE = 99;
+
+ /**
+ * Derive a ranking based on how "natural" the conversion is.
+ * The special value CONVERSION_NONE means no conversion is possible,
+ * and CONVERSION_NONTRIVIAL signals that more type conformance testing
+ * is required.
+ * Based on
+ * <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">
+ * "preferred method conversions" from Live Connect 3</a>
+ */
+ static int getConversionWeight(Object fromObj, Class to) {
+ int fromCode = getJSTypeCode(fromObj);
+
+ switch (fromCode) {
+
+ case JSTYPE_UNDEFINED:
+ if (to == ScriptRuntime.StringClass ||
+ to == ScriptRuntime.ObjectClass) {
+ return 1;
+ }
+ break;
+
+ case JSTYPE_NULL:
+ if (!to.isPrimitive()) {
+ return 1;
+ }
+ break;
+
+ case JSTYPE_BOOLEAN:
+ // "boolean" is #1
+ if (to == Boolean.TYPE) {
+ return 1;
+ }
+ else if (to == ScriptRuntime.BooleanClass) {
+ return 2;
+ }
+ else if (to == ScriptRuntime.ObjectClass) {
+ return 3;
+ }
+ else if (to == ScriptRuntime.StringClass) {
+ return 4;
+ }
+ break;
+
+ case JSTYPE_NUMBER:
+ if (to.isPrimitive()) {
+ if (to == Double.TYPE) {
+ return 1;
+ }
+ else if (to != Boolean.TYPE) {
+ return 1 + getSizeRank(to);
+ }
+ }
+ else {
+ if (to == ScriptRuntime.StringClass) {
+ // native numbers are #1-8
+ return 9;
+ }
+ else if (to == ScriptRuntime.ObjectClass) {
+ return 10;
+ }
+ else if (ScriptRuntime.NumberClass.isAssignableFrom(to)) {
+ // "double" is #1
+ return 2;
+ }
+ }
+ break;
+
+ case JSTYPE_STRING:
+ if (to == ScriptRuntime.StringClass) {
+ return 1;
+ }
+ else if (to.isInstance(fromObj)) {
+ return 2;
+ }
+ else if (to.isPrimitive()) {
+ if (to == Character.TYPE) {
+ return 3;
+ } else if (to != Boolean.TYPE) {
+ return 4;
+ }
+ }
+ break;
+
+ case JSTYPE_JAVA_CLASS:
+ if (to == ScriptRuntime.ClassClass) {
+ return 1;
+ }
+ else if (to == ScriptRuntime.ObjectClass) {
+ return 3;
+ }
+ else if (to == ScriptRuntime.StringClass) {
+ return 4;
+ }
+ break;
+
+ case JSTYPE_JAVA_OBJECT:
+ case JSTYPE_JAVA_ARRAY:
+ Object javaObj = fromObj;
+ if (javaObj instanceof Wrapper) {
+ javaObj = ((Wrapper)javaObj).unwrap();
+ }
+ if (to.isInstance(javaObj)) {
+ return CONVERSION_NONTRIVIAL;
+ }
+ if (to == ScriptRuntime.StringClass) {
+ return 2;
+ }
+ else if (to.isPrimitive() && to != Boolean.TYPE) {
+ return (fromCode == JSTYPE_JAVA_ARRAY)
+ ? CONVERSION_NONE : 2 + getSizeRank(to);
+ }
+ break;
+
+ case JSTYPE_OBJECT:
+ // Other objects takes #1-#3 spots
+ if (to == fromObj.getClass()) {
+ // No conversion required
+ return 1;
+ }
+ if (to.isArray()) {
+ if (fromObj instanceof NativeArray) {
+ // This is a native array conversion to a java array
+ // Array conversions are all equal, and preferable to object
+ // and string conversion, per LC3.
+ return 1;
+ }
+ }
+ else if (to == ScriptRuntime.ObjectClass) {
+ return 2;
+ }
+ else if (to == ScriptRuntime.StringClass) {
+ return 3;
+ }
+ else if (to == ScriptRuntime.DateClass) {
+ if (fromObj instanceof NativeDate) {
+ // This is a native date to java date conversion
+ return 1;
+ }
+ }
+ else if (to.isInterface()) {
+ if (fromObj instanceof Function) {
+ // See comments in coerceType
+ if (to.getMethods().length == 1) {
+ return 1;
+ }
+ }
+ return 11;
+ }
+ else if (to.isPrimitive() && to != Boolean.TYPE) {
+ return 3 + getSizeRank(to);
+ }
+ break;
+ }
+
+ return CONVERSION_NONE;
+ }
+
+ static int getSizeRank(Class aType) {
+ if (aType == Double.TYPE) {
+ return 1;
+ }
+ else if (aType == Float.TYPE) {
+ return 2;
+ }
+ else if (aType == Long.TYPE) {
+ return 3;
+ }
+ else if (aType == Integer.TYPE) {
+ return 4;
+ }
+ else if (aType == Short.TYPE) {
+ return 5;
+ }
+ else if (aType == Character.TYPE) {
+ return 6;
+ }
+ else if (aType == Byte.TYPE) {
+ return 7;
+ }
+ else if (aType == Boolean.TYPE) {
+ return CONVERSION_NONE;
+ }
+ else {
+ return 8;
+ }
+ }
+
+ private static int getJSTypeCode(Object value) {
+ if (value == null) {
+ return JSTYPE_NULL;
+ }
+ else if (value == Undefined.instance) {
+ return JSTYPE_UNDEFINED;
+ }
+ else if (value instanceof String) {
+ return JSTYPE_STRING;
+ }
+ else if (value instanceof Number) {
+ return JSTYPE_NUMBER;
+ }
+ else if (value instanceof Boolean) {
+ return JSTYPE_BOOLEAN;
+ }
+ else if (value instanceof Scriptable) {
+ if (value instanceof NativeJavaClass) {
+ return JSTYPE_JAVA_CLASS;
+ }
+ else if (value instanceof NativeJavaArray) {
+ return JSTYPE_JAVA_ARRAY;
+ }
+ else if (value instanceof Wrapper) {
+ return JSTYPE_JAVA_OBJECT;
+ }
+ else {
+ return JSTYPE_OBJECT;
+ }
+ }
+ else if (value instanceof Class) {
+ return JSTYPE_JAVA_CLASS;
+ }
+ else {
+ Class valueClass = value.getClass();
+ if (valueClass.isArray()) {
+ return JSTYPE_JAVA_ARRAY;
+ }
+ else {
+ return JSTYPE_JAVA_OBJECT;
+ }
+ }
+ }
+
+ /**
+ * Not intended for public use. Callers should use the
+ * public API Context.toType.
+ * @deprecated as of 1.5 Release 4
+ * @see org.mozilla.javascript.Context#jsToJava(Object, Class)
+ */
+ public static Object coerceType(Class type, Object value)
+ {
+ return coerceTypeImpl(type, value);
+ }
+
+ /**
+ * Type-munging for field setting and method invocation.
+ * Conforms to LC3 specification
+ */
+ static Object coerceTypeImpl(Class type, Object value)
+ {
+ if (value != null && value.getClass() == type) {
+ return value;
+ }
+
+ switch (getJSTypeCode(value)) {
+
+ case JSTYPE_NULL:
+ // raise error if type.isPrimitive()
+ if (type.isPrimitive()) {
+ reportConversionError(value, type);
+ }
+ return null;
+
+ case JSTYPE_UNDEFINED:
+ if (type == ScriptRuntime.StringClass ||
+ type == ScriptRuntime.ObjectClass) {
+ return "undefined";
+ }
+ else {
+ reportConversionError("undefined", type);
+ }
+ break;
+
+ case JSTYPE_BOOLEAN:
+ // Under LC3, only JS Booleans can be coerced into a Boolean value
+ if (type == Boolean.TYPE ||
+ type == ScriptRuntime.BooleanClass ||
+ type == ScriptRuntime.ObjectClass) {
+ return value;
+ }
+ else if (type == ScriptRuntime.StringClass) {
+ return value.toString();
+ }
+ else {
+ reportConversionError(value, type);
+ }
+ break;
+
+ case JSTYPE_NUMBER:
+ if (type == ScriptRuntime.StringClass) {
+ return ScriptRuntime.toString(value);
+ }
+ else if (type == ScriptRuntime.ObjectClass) {
+ return coerceToNumber(Double.TYPE, value);
+ }
+ else if ((type.isPrimitive() && type != Boolean.TYPE) ||
+ ScriptRuntime.NumberClass.isAssignableFrom(type)) {
+ return coerceToNumber(type, value);
+ }
+ else {
+ reportConversionError(value, type);
+ }
+ break;
+
+ case JSTYPE_STRING:
+ if (type == ScriptRuntime.StringClass || type.isInstance(value)) {
+ return value;
+ }
+ else if (type == Character.TYPE
+ || type == ScriptRuntime.CharacterClass)
+ {
+ // Special case for converting a single char string to a
+ // character
+ // Placed here because it applies *only* to JS strings,
+ // not other JS objects converted to strings
+ if (((String)value).length() == 1) {
+ return new Character(((String)value).charAt(0));
+ }
+ else {
+ return coerceToNumber(type, value);
+ }
+ }
+ else if ((type.isPrimitive() && type != Boolean.TYPE)
+ || ScriptRuntime.NumberClass.isAssignableFrom(type))
+ {
+ return coerceToNumber(type, value);
+ }
+ else {
+ reportConversionError(value, type);
+ }
+ break;
+
+ case JSTYPE_JAVA_CLASS:
+ if (value instanceof Wrapper) {
+ value = ((Wrapper)value).unwrap();
+ }
+
+ if (type == ScriptRuntime.ClassClass ||
+ type == ScriptRuntime.ObjectClass) {
+ return value;
+ }
+ else if (type == ScriptRuntime.StringClass) {
+ return value.toString();
+ }
+ else {
+ reportConversionError(value, type);
+ }
+ break;
+
+ case JSTYPE_JAVA_OBJECT:
+ case JSTYPE_JAVA_ARRAY:
+ if (value instanceof Wrapper) {
+ value = ((Wrapper)value).unwrap();
+ }
+ if (type.isPrimitive()) {
+ if (type == Boolean.TYPE) {
+ reportConversionError(value, type);
+ }
+ return coerceToNumber(type, value);
+ }
+ else {
+ if (type == ScriptRuntime.StringClass) {
+ return value.toString();
+ }
+ else {
+ if (type.isInstance(value)) {
+ return value;
+ }
+ else {
+ reportConversionError(value, type);
+ }
+ }
+ }
+ break;
+
+ case JSTYPE_OBJECT:
+ if (type == ScriptRuntime.StringClass) {
+ return ScriptRuntime.toString(value);
+ }
+ else if (type.isPrimitive()) {
+ if (type == Boolean.TYPE) {
+ reportConversionError(value, type);
+ }
+ return coerceToNumber(type, value);
+ }
+ else if (type.isInstance(value)) {
+ return value;
+ }
+ else if (type == ScriptRuntime.DateClass
+ && value instanceof NativeDate)
+ {
+ double time = ((NativeDate)value).getJSTimeValue();
+ // XXX: This will replace NaN by 0
+ return new Date((long)time);
+ }
+ else if (type.isArray() && value instanceof NativeArray) {
+ // Make a new java array, and coerce the JS array components
+ // to the target (component) type.
+ NativeArray array = (NativeArray) value;
+ long length = array.getLength();
+ Class arrayType = type.getComponentType();
+ Object Result = Array.newInstance(arrayType, (int)length);
+ for (int i = 0 ; i < length ; ++i) {
+ try {
+ Array.set(Result, i, coerceType(arrayType,
+ array.get(i, array)));
+ }
+ catch (EvaluatorException ee) {
+ reportConversionError(value, type);
+ }
+ }
+
+ return Result;
+ }
+ else if (value instanceof Wrapper) {
+ value = ((Wrapper)value).unwrap();
+ if (type.isInstance(value))
+ return value;
+ reportConversionError(value, type);
+ }
+ else if (type.isInterface() && value instanceof Callable) {
+ // Try to use function as implementation of Java interface.
+ //
+ // XXX: Curently only instances of ScriptableObject are
+ // supported since the resulting interface proxies should
+ // be reused next time conversion is made and generic
+ // Callable has no storage for it. Weak references can
+ // address it but for now use this restriction.
+ if (value instanceof ScriptableObject) {
+ ScriptableObject so = (ScriptableObject)value;
+ Object key = Kit.makeHashKeyFromPair(
+ COERCED_INTERFACE_KEY, type);
+ Object old = so.getAssociatedValue(key);
+ if (old != null) {
+ // Function was already wrapped
+ return old;
+ }
+ Context cx = Context.getContext();
+ Object glue
+ = InterfaceAdapter.create(cx, type, (Callable)value);
+ // Store for later retrival
+ glue = so.associateValue(key, glue);
+ return glue;
+ }
+ reportConversionError(value, type);
+ } else {
+ reportConversionError(value, type);
+ }
+ break;
+ }
+
+ return value;
+ }
+
+ private static Object coerceToNumber(Class type, Object value)
+ {
+ Class valueClass = value.getClass();
+
+ // Character
+ if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) {
+ if (valueClass == ScriptRuntime.CharacterClass) {
+ return value;
+ }
+ return new Character((char)toInteger(value,
+ ScriptRuntime.CharacterClass,
+ Character.MIN_VALUE,
+ Character.MAX_VALUE));
+ }
+
+ // Double, Float
+ if (type == ScriptRuntime.ObjectClass ||
+ type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
+ return valueClass == ScriptRuntime.DoubleClass
+ ? value
+ : new Double(toDouble(value));
+ }
+
+ if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
+ if (valueClass == ScriptRuntime.FloatClass) {
+ return value;
+ }
+ else {
+ double number = toDouble(value);
+ if (Double.isInfinite(number) || Double.isNaN(number)
+ || number == 0.0) {
+ return new Float((float)number);
+ }
+ else {
+ double absNumber = Math.abs(number);
+ if (absNumber < Float.MIN_VALUE) {
+ return new Float((number > 0.0) ? +0.0 : -0.0);
+ }
+ else if (absNumber > Float.MAX_VALUE) {
+ return new Float((number > 0.0) ?
+ Float.POSITIVE_INFINITY :
+ Float.NEGATIVE_INFINITY);
+ }
+ else {
+ return new Float((float)number);
+ }
+ }
+ }
+ }
+
+ // Integer, Long, Short, Byte
+ if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) {
+ if (valueClass == ScriptRuntime.IntegerClass) {
+ return value;
+ }
+ else {
+ return new Integer((int)toInteger(value,
+ ScriptRuntime.IntegerClass,
+ Integer.MIN_VALUE,
+ Integer.MAX_VALUE));
+ }
+ }
+
+ if (type == ScriptRuntime.LongClass || type == Long.TYPE) {
+ if (valueClass == ScriptRuntime.LongClass) {
+ return value;
+ } else {
+ /* Long values cannot be expressed exactly in doubles.
+ * We thus use the largest and smallest double value that
+ * has a value expressible as a long value. We build these
+ * numerical values from their hexidecimal representations
+ * to avoid any problems caused by attempting to parse a
+ * decimal representation.
+ */
+ final double max = Double.longBitsToDouble(0x43dfffffffffffffL);
+ final double min = Double.longBitsToDouble(0xc3e0000000000000L);
+ return new Long(toInteger(value,
+ ScriptRuntime.LongClass,
+ min,
+ max));
+ }
+ }
+
+ if (type == ScriptRuntime.ShortClass || type == Short.TYPE) {
+ if (valueClass == ScriptRuntime.ShortClass) {
+ return value;
+ }
+ else {
+ return new Short((short)toInteger(value,
+ ScriptRuntime.ShortClass,
+ Short.MIN_VALUE,
+ Short.MAX_VALUE));
+ }
+ }
+
+ if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) {
+ if (valueClass == ScriptRuntime.ByteClass) {
+ return value;
+ }
+ else {
+ return new Byte((byte)toInteger(value,
+ ScriptRuntime.ByteClass,
+ Byte.MIN_VALUE,
+ Byte.MAX_VALUE));
+ }
+ }
+
+ return new Double(toDouble(value));
+ }
+
+
+ private static double toDouble(Object value)
+ {
+ if (value instanceof Number) {
+ return ((Number)value).doubleValue();
+ }
+ else if (value instanceof String) {
+ return ScriptRuntime.toNumber((String)value);
+ }
+ else if (value instanceof Scriptable) {
+ if (value instanceof Wrapper) {
+ // XXX: optimize tail-recursion?
+ return toDouble(((Wrapper)value).unwrap());
+ }
+ else {
+ return ScriptRuntime.toNumber(value);
+ }
+ }
+ else {
+ Method meth;
+ try {
+ meth = value.getClass().getMethod("doubleValue",
+ (Class [])null);
+ }
+ catch (NoSuchMethodException e) {
+ meth = null;
+ }
+ catch (SecurityException e) {
+ meth = null;
+ }
+ if (meth != null) {
+ try {
+ return ((Number)meth.invoke(value,
+ (Object [])null)).doubleValue();
+ }
+ catch (IllegalAccessException e) {
+ // XXX: ignore, or error message?
+ reportConversionError(value, Double.TYPE);
+ }
+ catch (InvocationTargetException e) {
+ // XXX: ignore, or error message?
+ reportConversionError(value, Double.TYPE);
+ }
+ }
+ return ScriptRuntime.toNumber(value.toString());
+ }
+ }
+
+ private static long toInteger(Object value, Class type,
+ double min, double max)
+ {
+ double d = toDouble(value);
+
+ if (Double.isInfinite(d) || Double.isNaN(d)) {
+ // Convert to string first, for more readable message
+ reportConversionError(ScriptRuntime.toString(value), type);
+ }
+
+ if (d > 0.0) {
+ d = Math.floor(d);
+ }
+ else {
+ d = Math.ceil(d);
+ }
+
+ if (d < min || d > max) {
+ // Convert to string first, for more readable message
+ reportConversionError(ScriptRuntime.toString(value), type);
+ }
+ return (long)d;
+ }
+
+ static void reportConversionError(Object value, Class type)
+ {
+ // It uses String.valueOf(value), not value.toString() since
+ // value can be null, bug 282447.
+ throw Context.reportRuntimeError2(
+ "msg.conversion.not.allowed",
+ String.valueOf(value),
+ JavaMembers.javaSignature(type));
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ out.writeBoolean(isAdapter);
+ if (isAdapter) {
+ if (adapter_writeAdapterObject == null) {
+ throw new IOException();
+ }
+ Object[] args = { javaObject, out };
+ try {
+ adapter_writeAdapterObject.invoke(null, args);
+ } catch (Exception ex) {
+ throw new IOException();
+ }
+ } else {
+ out.writeObject(javaObject);
+ }
+
+ if (staticType != null) {
+ out.writeObject(staticType.getClass().getName());
+ } else {
+ out.writeObject(null);
+ }
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ isAdapter = in.readBoolean();
+ if (isAdapter) {
+ if (adapter_readAdapterObject == null)
+ throw new ClassNotFoundException();
+ Object[] args = { this, in };
+ try {
+ javaObject = adapter_readAdapterObject.invoke(null, args);
+ } catch (Exception ex) {
+ throw new IOException();
+ }
+ } else {
+ javaObject = in.readObject();
+ }
+
+ String className = (String)in.readObject();
+ if (className != null) {
+ staticType = Class.forName(className);
+ } else {
+ staticType = null;
+ }
+
+ initMembers();
+ }
+
+ /**
+ * The prototype of this object.
+ */
+ protected Scriptable prototype;
+
+ /**
+ * The parent scope of this object.
+ */
+ protected Scriptable parent;
+
+ protected transient Object javaObject;
+
+ protected transient Class staticType;
+ protected transient JavaMembers members;
+ private transient Hashtable fieldAndMethods;
+ private transient boolean isAdapter;
+
+ private static final Object COERCED_INTERFACE_KEY = new Object();
+ private static Method adapter_writeAdapterObject;
+ private static Method adapter_readAdapterObject;
+
+ static {
+ // Reflection in java is verbose
+ Class[] sig2 = new Class[2];
+ Class cl = Kit.classOrNull("org.mozilla.javascript.JavaAdapter");
+ if (cl != null) {
+ try {
+ sig2[0] = ScriptRuntime.ObjectClass;
+ sig2[1] = Kit.classOrNull("java.io.ObjectOutputStream");
+ adapter_writeAdapterObject = cl.getMethod("writeAdapterObject",
+ sig2);
+
+ sig2[0] = ScriptRuntime.ScriptableClass;
+ sig2[1] = Kit.classOrNull("java.io.ObjectInputStream");
+ adapter_readAdapterObject = cl.getMethod("readAdapterObject",
+ sig2);
+
+ } catch (Exception ex) {
+ adapter_writeAdapterObject = null;
+ adapter_readAdapterObject = null;
+ }
+ }
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java
new file mode 100644
index 0000000..71f09f7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaPackage.java
@@ -0,0 +1,199 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Frank Mitchell
+ * Mike Shaver
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class reflects Java packages into the JavaScript environment. We
+ * lazily reflect classes and subpackages, and use a caching/sharing
+ * system to ensure that members reflected into one JavaPackage appear
+ * in all other references to the same package (as with Packages.java.lang
+ * and java.lang).
+ *
+ * @author Mike Shaver
+ * @see NativeJavaArray
+ * @see NativeJavaObject
+ * @see NativeJavaClass
+ */
+
+public class NativeJavaPackage extends ScriptableObject
+{
+ static final long serialVersionUID = 7445054382212031523L;
+
+ NativeJavaPackage(boolean internalUsage,
+ String packageName, ClassLoader classLoader)
+ {
+ this.packageName = packageName;
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * @deprecated NativeJavaPackage is an internal class, do not use
+ * it directly.
+ */
+ public NativeJavaPackage(String packageName, ClassLoader classLoader) {
+ this(false, packageName, classLoader);
+ }
+
+ /**
+ * @deprecated NativeJavaPackage is an internal class, do not use
+ * it directly.
+ */
+ public NativeJavaPackage(String packageName) {
+ this(false, packageName,
+ Context.getCurrentContext().getApplicationClassLoader());
+ }
+
+ public String getClassName() {
+ return "JavaPackage";
+ }
+
+ public boolean has(String id, Scriptable start) {
+ return true;
+ }
+
+ public boolean has(int index, Scriptable start) {
+ return false;
+ }
+
+ public void put(String id, Scriptable start, Object value) {
+ // Can't add properties to Java packages. Sorry.
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ throw Context.reportRuntimeError0("msg.pkg.int");
+ }
+
+ public Object get(String id, Scriptable start) {
+ return getPkgProperty(id, start, true);
+ }
+
+ public Object get(int index, Scriptable start) {
+ return NOT_FOUND;
+ }
+
+ // set up a name which is known to be a package so we don't
+ // need to look for a class by that name
+ void forcePackage(String name, Scriptable scope)
+ {
+ NativeJavaPackage pkg;
+ int end = name.indexOf('.');
+ if (end == -1) {
+ end = name.length();
+ }
+
+ String id = name.substring(0, end);
+ Object cached = super.get(id, this);
+ if (cached != null && cached instanceof NativeJavaPackage) {
+ pkg = (NativeJavaPackage) cached;
+ } else {
+ String newPackage = packageName.length() == 0
+ ? id
+ : packageName + "." + id;
+ pkg = new NativeJavaPackage(true, newPackage, classLoader);
+ ScriptRuntime.setObjectProtoAndParent(pkg, scope);
+ super.put(id, this, pkg);
+ }
+ if (end < name.length()) {
+ pkg.forcePackage(name.substring(end+1), scope);
+ }
+ }
+
+ synchronized Object getPkgProperty(String name, Scriptable start,
+ boolean createPkg)
+ {
+ Object cached = super.get(name, start);
+ if (cached != NOT_FOUND)
+ return cached;
+
+ String className = (packageName.length() == 0)
+ ? name : packageName + '.' + name;
+ Context cx = Context.getContext();
+ ClassShutter shutter = cx.getClassShutter();
+ Scriptable newValue = null;
+ if (shutter == null || shutter.visibleToScripts(className)) {
+ Class cl = null;
+ if (classLoader != null) {
+ cl = Kit.classOrNull(classLoader, className);
+ } else {
+ cl = Kit.classOrNull(className);
+ }
+ if (cl != null) {
+ newValue = new NativeJavaClass(getTopLevelScope(this), cl);
+ newValue.setPrototype(getPrototype());
+ }
+ }
+ if (newValue == null && createPkg) {
+ NativeJavaPackage pkg;
+ pkg = new NativeJavaPackage(true, className, classLoader);
+ ScriptRuntime.setObjectProtoAndParent(pkg, getParentScope());
+ newValue = pkg;
+ }
+ if (newValue != null) {
+ // Make it available for fast lookup and sharing of
+ // lazily-reflected constructors and static members.
+ super.put(name, start, newValue);
+ }
+ return newValue;
+ }
+
+ public Object getDefaultValue(Class ignored) {
+ return toString();
+ }
+
+ public String toString() {
+ return "[JavaPackage " + packageName + "]";
+ }
+
+ public boolean equals(Object obj) {
+ if(obj instanceof NativeJavaPackage) {
+ NativeJavaPackage njp = (NativeJavaPackage)obj;
+ return packageName.equals(njp.packageName) && classLoader == njp.classLoader;
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return packageName.hashCode() ^ (classLoader == null ? 0 : classLoader.hashCode());
+ }
+
+ private String packageName;
+ private ClassLoader classLoader;
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java
new file mode 100644
index 0000000..b5c9b49
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeJavaTopPackage.java
@@ -0,0 +1,187 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Frank Mitchell
+ * Mike Shaver
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class reflects Java packages into the JavaScript environment. We
+ * lazily reflect classes and subpackages, and use a caching/sharing
+ * system to ensure that members reflected into one JavaPackage appear
+ * in all other references to the same package (as with Packages.java.lang
+ * and java.lang).
+ *
+ * @author Mike Shaver
+ * @see NativeJavaArray
+ * @see NativeJavaObject
+ * @see NativeJavaClass
+ */
+
+public class NativeJavaTopPackage
+ extends NativeJavaPackage implements Function, IdFunctionCall
+{
+ static final long serialVersionUID = -1455787259477709999L;
+
+ // we know these are packages so we can skip the class check
+ // note that this is ok even if the package isn't present.
+ private static final String commonPackages = ""
+ +"java.lang;"
+ +"java.lang.reflect;"
+ +"java.io;"
+ +"java.math;"
+ +"java.net;"
+ +"java.util;"
+ +"java.util.zip;"
+ +"java.text;"
+ +"java.text.resources;"
+ +"java.applet;"
+ +"javax.swing;"
+ ;
+
+ NativeJavaTopPackage(ClassLoader loader)
+ {
+ super(true, "", loader);
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return construct(cx, scope, args);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ ClassLoader loader = null;
+ if (args.length != 0) {
+ Object arg = args[0];
+ if (arg instanceof Wrapper) {
+ arg = ((Wrapper)arg).unwrap();
+ }
+ if (arg instanceof ClassLoader) {
+ loader = (ClassLoader)arg;
+ }
+ }
+ if (loader == null) {
+ Context.reportRuntimeError0("msg.not.classloader");
+ return null;
+ }
+ return new NativeJavaPackage(true, "", loader);
+ }
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+ ClassLoader loader = cx.getApplicationClassLoader();
+ final NativeJavaTopPackage top = new NativeJavaTopPackage(loader);
+ top.setPrototype(getObjectPrototype(scope));
+ top.setParentScope(scope);
+
+ String[] names = Kit.semicolonSplit(commonPackages);
+ for (int i = 0; i != names.length; ++i) {
+ top.forcePackage(names[i], scope);
+ }
+
+ // getClass implementation
+ IdFunctionObject getClass = new IdFunctionObject(top, FTAG, Id_getClass,
+ "getClass", 1, scope);
+
+ // We want to get a real alias, and not a distinct JavaPackage
+ // with the same packageName, so that we share classes and top
+ // that are underneath.
+ String[] topNames = { "java", "javax", "org", "com", "edu", "net" };
+ NativeJavaPackage[] topPackages = new NativeJavaPackage[topNames.length];
+ for (int i=0; i < topNames.length; i++) {
+ topPackages[i] = (NativeJavaPackage)top.get(topNames[i], top);
+ }
+
+ // It's safe to downcast here since initStandardObjects takes
+ // a ScriptableObject.
+ ScriptableObject global = (ScriptableObject) scope;
+
+ if (sealed) {
+ getClass.sealObject();
+ }
+ getClass.exportAsScopeProperty();
+ global.defineProperty("Packages", top, ScriptableObject.DONTENUM);
+ for (int i=0; i < topNames.length; i++) {
+ global.defineProperty(topNames[i], topPackages[i],
+ ScriptableObject.DONTENUM);
+ }
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (f.hasTag(FTAG)) {
+ if (f.methodId() == Id_getClass) {
+ return js_getClass(cx, scope, args);
+ }
+ }
+ throw f.unknown();
+ }
+
+ private Scriptable js_getClass(Context cx, Scriptable scope, Object[] args)
+ {
+ if (args.length > 0 && args[0] instanceof Wrapper) {
+ Scriptable result = this;
+ Class cl = ((Wrapper) args[0]).unwrap().getClass();
+ // Evaluate the class name by getting successive properties of
+ // the string to find the appropriate NativeJavaClass object
+ String name = cl.getName();
+ int offset = 0;
+ for (;;) {
+ int index = name.indexOf('.', offset);
+ String propName = index == -1
+ ? name.substring(offset)
+ : name.substring(offset, index);
+ Object prop = result.get(propName, result);
+ if (!(prop instanceof Scriptable))
+ break; // fall through to error
+ result = (Scriptable) prop;
+ if (index == -1)
+ return result;
+ offset = index+1;
+ }
+ }
+ throw Context.reportRuntimeError0("msg.not.java.obj");
+ }
+
+ private static final Object FTAG = new Object();
+ private static final int Id_getClass = 1;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java
new file mode 100644
index 0000000..36b66b4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeMath.java
@@ -0,0 +1,399 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the Math native object.
+ * See ECMA 15.8.
+ * @author Norris Boyd
+ */
+
+final class NativeMath extends IdScriptableObject
+{
+ static final long serialVersionUID = -8838847185801131569L;
+
+ private static final Object MATH_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeMath obj = new NativeMath();
+ obj.activatePrototypeMap(MAX_ID);
+ obj.setPrototype(getObjectPrototype(scope));
+ obj.setParentScope(scope);
+ if (sealed) { obj.sealObject(); }
+ ScriptableObject.defineProperty(scope, "Math", obj,
+ ScriptableObject.DONTENUM);
+ }
+
+ private NativeMath()
+ {
+ }
+
+ public String getClassName() { return "Math"; }
+
+ protected void initPrototypeId(int id)
+ {
+ if (id <= LAST_METHOD_ID) {
+ String name;
+ int arity;
+ switch (id) {
+ case Id_toSource: arity = 0; name = "toSource"; break;
+ case Id_abs: arity = 1; name = "abs"; break;
+ case Id_acos: arity = 1; name = "acos"; break;
+ case Id_asin: arity = 1; name = "asin"; break;
+ case Id_atan: arity = 1; name = "atan"; break;
+ case Id_atan2: arity = 2; name = "atan2"; break;
+ case Id_ceil: arity = 1; name = "ceil"; break;
+ case Id_cos: arity = 1; name = "cos"; break;
+ case Id_exp: arity = 1; name = "exp"; break;
+ case Id_floor: arity = 1; name = "floor"; break;
+ case Id_log: arity = 1; name = "log"; break;
+ case Id_max: arity = 2; name = "max"; break;
+ case Id_min: arity = 2; name = "min"; break;
+ case Id_pow: arity = 2; name = "pow"; break;
+ case Id_random: arity = 0; name = "random"; break;
+ case Id_round: arity = 1; name = "round"; break;
+ case Id_sin: arity = 1; name = "sin"; break;
+ case Id_sqrt: arity = 1; name = "sqrt"; break;
+ case Id_tan: arity = 1; name = "tan"; break;
+ default: throw new IllegalStateException(String.valueOf(id));
+ }
+ initPrototypeMethod(MATH_TAG, id, name, arity);
+ } else {
+ String name;
+ double x;
+ switch (id) {
+ case Id_E: x = Math.E; name = "E"; break;
+ case Id_PI: x = Math.PI; name = "PI"; break;
+ case Id_LN10: x = 2.302585092994046; name = "LN10"; break;
+ case Id_LN2: x = 0.6931471805599453; name = "LN2"; break;
+ case Id_LOG2E: x = 1.4426950408889634; name = "LOG2E"; break;
+ case Id_LOG10E: x = 0.4342944819032518; name = "LOG10E"; break;
+ case Id_SQRT1_2: x = 0.7071067811865476; name = "SQRT1_2"; break;
+ case Id_SQRT2: x = 1.4142135623730951; name = "SQRT2"; break;
+ default: throw new IllegalStateException(String.valueOf(id));
+ }
+ initPrototypeValue(id, name, ScriptRuntime.wrapNumber(x),
+ DONTENUM | READONLY | PERMANENT);
+ }
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(MATH_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ double x;
+ int methodId = f.methodId();
+ switch (methodId) {
+ case Id_toSource:
+ return "Math";
+
+ case Id_abs:
+ x = ScriptRuntime.toNumber(args, 0);
+ // abs(-0.0) should be 0.0, but -0.0 < 0.0 == false
+ x = (x == 0.0) ? 0.0 : (x < 0.0) ? -x : x;
+ break;
+
+ case Id_acos:
+ case Id_asin:
+ x = ScriptRuntime.toNumber(args, 0);
+ if (x == x && -1.0 <= x && x <= 1.0) {
+ x = (methodId == Id_acos) ? Math.acos(x) : Math.asin(x);
+ } else {
+ x = Double.NaN;
+ }
+ break;
+
+ case Id_atan:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.atan(x);
+ break;
+
+ case Id_atan2:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.atan2(x, ScriptRuntime.toNumber(args, 1));
+ break;
+
+ case Id_ceil:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.ceil(x);
+ break;
+
+ case Id_cos:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = (x == Double.POSITIVE_INFINITY
+ || x == Double.NEGATIVE_INFINITY)
+ ? Double.NaN : Math.cos(x);
+ break;
+
+ case Id_exp:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = (x == Double.POSITIVE_INFINITY) ? x
+ : (x == Double.NEGATIVE_INFINITY) ? 0.0
+ : Math.exp(x);
+ break;
+
+ case Id_floor:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.floor(x);
+ break;
+
+ case Id_log:
+ x = ScriptRuntime.toNumber(args, 0);
+ // Java's log(<0) = -Infinity; we need NaN
+ x = (x < 0) ? Double.NaN : Math.log(x);
+ break;
+
+ case Id_max:
+ case Id_min:
+ x = (methodId == Id_max)
+ ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+ for (int i = 0; i != args.length; ++i) {
+ double d = ScriptRuntime.toNumber(args[i]);
+ if (d != d) {
+ x = d; // NaN
+ break;
+ }
+ if (methodId == Id_max) {
+ // if (x < d) x = d; does not work due to -0.0 >= +0.0
+ x = Math.max(x, d);
+ } else {
+ x = Math.min(x, d);
+ }
+ }
+ break;
+
+ case Id_pow:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = js_pow(x, ScriptRuntime.toNumber(args, 1));
+ break;
+
+ case Id_random:
+ x = Math.random();
+ break;
+
+ case Id_round:
+ x = ScriptRuntime.toNumber(args, 0);
+ if (x == x && x != Double.POSITIVE_INFINITY
+ && x != Double.NEGATIVE_INFINITY)
+ {
+ // Round only finite x
+ long l = Math.round(x);
+ if (l != 0) {
+ x = l;
+ } else {
+ // We must propagate the sign of d into the result
+ if (x < 0.0) {
+ x = ScriptRuntime.negativeZero;
+ } else if (x != 0.0) {
+ x = 0.0;
+ }
+ }
+ }
+ break;
+
+ case Id_sin:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = (x == Double.POSITIVE_INFINITY
+ || x == Double.NEGATIVE_INFINITY)
+ ? Double.NaN : Math.sin(x);
+ break;
+
+ case Id_sqrt:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.sqrt(x);
+ break;
+
+ case Id_tan:
+ x = ScriptRuntime.toNumber(args, 0);
+ x = Math.tan(x);
+ break;
+
+ default: throw new IllegalStateException(String.valueOf(methodId));
+ }
+ return ScriptRuntime.wrapNumber(x);
+ }
+
+ // See Ecma 15.8.2.13
+ private double js_pow(double x, double y) {
+ double result;
+ if (y != y) {
+ // y is NaN, result is always NaN
+ result = y;
+ } else if (y == 0) {
+ // Java's pow(NaN, 0) = NaN; we need 1
+ result = 1.0;
+ } else if (x == 0) {
+ // Many dirrerences from Java's Math.pow
+ if (1 / x > 0) {
+ result = (y > 0) ? 0 : Double.POSITIVE_INFINITY;
+ } else {
+ // x is -0, need to check if y is an odd integer
+ long y_long = (long)y;
+ if (y_long == y && (y_long & 0x1) != 0) {
+ result = (y > 0) ? -0.0 : Double.NEGATIVE_INFINITY;
+ } else {
+ result = (y > 0) ? 0.0 : Double.POSITIVE_INFINITY;
+ }
+ }
+ } else {
+ result = Math.pow(x, y);
+ if (result != result) {
+ // Check for broken Java implementations that gives NaN
+ // when they should return something else
+ if (y == Double.POSITIVE_INFINITY) {
+ if (x < -1.0 || 1.0 < x) {
+ result = Double.POSITIVE_INFINITY;
+ } else if (-1.0 < x && x < 1.0) {
+ result = 0;
+ }
+ } else if (y == Double.NEGATIVE_INFINITY) {
+ if (x < -1.0 || 1.0 < x) {
+ result = 0;
+ } else if (-1.0 < x && x < 1.0) {
+ result = Double.POSITIVE_INFINITY;
+ }
+ } else if (x == Double.POSITIVE_INFINITY) {
+ result = (y > 0) ? Double.POSITIVE_INFINITY : 0.0;
+ } else if (x == Double.NEGATIVE_INFINITY) {
+ long y_long = (long)y;
+ if (y_long == y && (y_long & 0x1) != 0) {
+ // y is odd integer
+ result = (y > 0) ? Double.NEGATIVE_INFINITY : -0.0;
+ } else {
+ result = (y > 0) ? Double.POSITIVE_INFINITY : 0.0;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2004-03-17 13:51:32 CET
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 1: if (s.charAt(0)=='E') {id=Id_E; break L0;} break L;
+ case 2: if (s.charAt(0)=='P' && s.charAt(1)=='I') {id=Id_PI; break L0;} break L;
+ case 3: switch (s.charAt(0)) {
+ case 'L': if (s.charAt(2)=='2' && s.charAt(1)=='N') {id=Id_LN2; break L0;} break L;
+ case 'a': if (s.charAt(2)=='s' && s.charAt(1)=='b') {id=Id_abs; break L0;} break L;
+ case 'c': if (s.charAt(2)=='s' && s.charAt(1)=='o') {id=Id_cos; break L0;} break L;
+ case 'e': if (s.charAt(2)=='p' && s.charAt(1)=='x') {id=Id_exp; break L0;} break L;
+ case 'l': if (s.charAt(2)=='g' && s.charAt(1)=='o') {id=Id_log; break L0;} break L;
+ case 'm': c=s.charAt(2);
+ if (c=='n') { if (s.charAt(1)=='i') {id=Id_min; break L0;} }
+ else if (c=='x') { if (s.charAt(1)=='a') {id=Id_max; break L0;} }
+ break L;
+ case 'p': if (s.charAt(2)=='w' && s.charAt(1)=='o') {id=Id_pow; break L0;} break L;
+ case 's': if (s.charAt(2)=='n' && s.charAt(1)=='i') {id=Id_sin; break L0;} break L;
+ case 't': if (s.charAt(2)=='n' && s.charAt(1)=='a') {id=Id_tan; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(1)) {
+ case 'N': X="LN10";id=Id_LN10; break L;
+ case 'c': X="acos";id=Id_acos; break L;
+ case 'e': X="ceil";id=Id_ceil; break L;
+ case 'q': X="sqrt";id=Id_sqrt; break L;
+ case 's': X="asin";id=Id_asin; break L;
+ case 't': X="atan";id=Id_atan; break L;
+ } break L;
+ case 5: switch (s.charAt(0)) {
+ case 'L': X="LOG2E";id=Id_LOG2E; break L;
+ case 'S': X="SQRT2";id=Id_SQRT2; break L;
+ case 'a': X="atan2";id=Id_atan2; break L;
+ case 'f': X="floor";id=Id_floor; break L;
+ case 'r': X="round";id=Id_round; break L;
+ } break L;
+ case 6: c=s.charAt(0);
+ if (c=='L') { X="LOG10E";id=Id_LOG10E; }
+ else if (c=='r') { X="random";id=Id_random; }
+ break L;
+ case 7: X="SQRT1_2";id=Id_SQRT1_2; break L;
+ case 8: X="toSource";id=Id_toSource; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_toSource = 1,
+ Id_abs = 2,
+ Id_acos = 3,
+ Id_asin = 4,
+ Id_atan = 5,
+ Id_atan2 = 6,
+ Id_ceil = 7,
+ Id_cos = 8,
+ Id_exp = 9,
+ Id_floor = 10,
+ Id_log = 11,
+ Id_max = 12,
+ Id_min = 13,
+ Id_pow = 14,
+ Id_random = 15,
+ Id_round = 16,
+ Id_sin = 17,
+ Id_sqrt = 18,
+ Id_tan = 19,
+
+ LAST_METHOD_ID = 19;
+
+ private static final int
+ Id_E = LAST_METHOD_ID + 1,
+ Id_PI = LAST_METHOD_ID + 2,
+ Id_LN10 = LAST_METHOD_ID + 3,
+ Id_LN2 = LAST_METHOD_ID + 4,
+ Id_LOG2E = LAST_METHOD_ID + 5,
+ Id_LOG10E = LAST_METHOD_ID + 6,
+ Id_SQRT1_2 = LAST_METHOD_ID + 7,
+ Id_SQRT2 = LAST_METHOD_ID + 8,
+
+ MAX_ID = LAST_METHOD_ID + 8;
+
+// #/string_id_map#
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java
new file mode 100644
index 0000000..8fc9fb0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeNumber.java
@@ -0,0 +1,244 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the Number native object.
+ *
+ * See ECMA 15.7.
+ *
+ * @author Norris Boyd
+ */
+final class NativeNumber extends IdScriptableObject
+{
+ static final long serialVersionUID = 3504516769741512101L;
+
+ private static final Object NUMBER_TAG = new Object();
+
+ private static final int MAX_PRECISION = 100;
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeNumber obj = new NativeNumber(0.0);
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ private NativeNumber(double number)
+ {
+ doubleValue = number;
+ }
+
+ public String getClassName()
+ {
+ return "Number";
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ final int attr = ScriptableObject.DONTENUM |
+ ScriptableObject.PERMANENT |
+ ScriptableObject.READONLY;
+
+ ctor.defineProperty("NaN", ScriptRuntime.NaNobj, attr);
+ ctor.defineProperty("POSITIVE_INFINITY",
+ ScriptRuntime.wrapNumber(Double.POSITIVE_INFINITY),
+ attr);
+ ctor.defineProperty("NEGATIVE_INFINITY",
+ ScriptRuntime.wrapNumber(Double.NEGATIVE_INFINITY),
+ attr);
+ ctor.defineProperty("MAX_VALUE",
+ ScriptRuntime.wrapNumber(Double.MAX_VALUE),
+ attr);
+ ctor.defineProperty("MIN_VALUE",
+ ScriptRuntime.wrapNumber(Double.MIN_VALUE),
+ attr);
+
+ super.fillConstructorProperties(ctor);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=1; s="toString"; break;
+ case Id_toLocaleString: arity=1; s="toLocaleString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+ case Id_toFixed: arity=1; s="toFixed"; break;
+ case Id_toExponential: arity=1; s="toExponential"; break;
+ case Id_toPrecision: arity=1; s="toPrecision"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(NUMBER_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(NUMBER_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ if (id == Id_constructor) {
+ double val = (args.length >= 1)
+ ? ScriptRuntime.toNumber(args[0]) : 0.0;
+ if (thisObj == null) {
+ // new Number(val) creates a new Number object.
+ return new NativeNumber(val);
+ }
+ // Number(val) converts val to a number value.
+ return ScriptRuntime.wrapNumber(val);
+ }
+
+ // The rest of Number.prototype methods require thisObj to be Number
+
+ if (!(thisObj instanceof NativeNumber))
+ throw incompatibleCallError(f);
+ double value = ((NativeNumber)thisObj).doubleValue;
+
+ switch (id) {
+
+ case Id_toString:
+ case Id_toLocaleString:
+ {
+ // toLocaleString is just an alias for toString for now
+ int base = (args.length == 0)
+ ? 10 : ScriptRuntime.toInt32(args[0]);
+ return ScriptRuntime.numberToString(value, base);
+ }
+
+ case Id_toSource:
+ return "(new Number("+ScriptRuntime.toString(value)+"))";
+
+ case Id_valueOf:
+ return ScriptRuntime.wrapNumber(value);
+
+ case Id_toFixed:
+ return num_to(value, args, DToA.DTOSTR_FIXED,
+ DToA.DTOSTR_FIXED, -20, 0);
+
+ case Id_toExponential:
+ return num_to(value, args, DToA.DTOSTR_STANDARD_EXPONENTIAL,
+ DToA.DTOSTR_EXPONENTIAL, 0, 1);
+
+ case Id_toPrecision:
+ return num_to(value, args, DToA.DTOSTR_STANDARD,
+ DToA.DTOSTR_PRECISION, 1, 0);
+
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+ public String toString() {
+ return ScriptRuntime.numberToString(doubleValue, 10);
+ }
+
+ private static String num_to(double val,
+ Object[] args,
+ int zeroArgMode, int oneArgMode,
+ int precisionMin, int precisionOffset)
+ {
+ int precision;
+ if (args.length == 0) {
+ precision = 0;
+ oneArgMode = zeroArgMode;
+ } else {
+ /* We allow a larger range of precision than
+ ECMA requires; this is permitted by ECMA. */
+ precision = ScriptRuntime.toInt32(args[0]);
+ if (precision < precisionMin || precision > MAX_PRECISION) {
+ String msg = ScriptRuntime.getMessage1(
+ "msg.bad.precision", ScriptRuntime.toString(args[0]));
+ throw ScriptRuntime.constructError("RangeError", msg);
+ }
+ }
+ StringBuffer sb = new StringBuffer();
+ DToA.JS_dtostr(sb, oneArgMode, precision + precisionOffset, val);
+ return sb.toString();
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:50 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 7: c=s.charAt(0);
+ if (c=='t') { X="toFixed";id=Id_toFixed; }
+ else if (c=='v') { X="valueOf";id=Id_valueOf; }
+ break L;
+ case 8: c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ break L;
+ case 11: c=s.charAt(0);
+ if (c=='c') { X="constructor";id=Id_constructor; }
+ else if (c=='t') { X="toPrecision";id=Id_toPrecision; }
+ break L;
+ case 13: X="toExponential";id=Id_toExponential; break L;
+ case 14: X="toLocaleString";id=Id_toLocaleString; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toLocaleString = 3,
+ Id_toSource = 4,
+ Id_valueOf = 5,
+ Id_toFixed = 6,
+ Id_toExponential = 7,
+ Id_toPrecision = 8,
+ MAX_PROTOTYPE_ID = 8;
+
+// #/string_id_map#
+
+ private double doubleValue;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java
new file mode 100644
index 0000000..19aff63
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeObject.java
@@ -0,0 +1,316 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the Object native object.
+ * See ECMA 15.2.
+ * @author Norris Boyd
+ */
+public class NativeObject extends IdScriptableObject
+{
+ static final long serialVersionUID = -6345305608474346996L;
+
+ private static final Object OBJECT_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeObject obj = new NativeObject();
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ public String getClassName()
+ {
+ return "Object";
+ }
+
+ public String toString()
+ {
+ return ScriptRuntime.defaultObjectToString(this);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toLocaleString: arity=0; s="toLocaleString"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+ case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
+ case Id_propertyIsEnumerable:
+ arity=1; s="propertyIsEnumerable"; break;
+ case Id_isPrototypeOf: arity=1; s="isPrototypeOf"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id___defineGetter__:
+ arity=2; s="__defineGetter__"; break;
+ case Id___defineSetter__:
+ arity=2; s="__defineSetter__"; break;
+ case Id___lookupGetter__:
+ arity=1; s="__lookupGetter__"; break;
+ case Id___lookupSetter__:
+ arity=1; s="__lookupSetter__"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(OBJECT_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(OBJECT_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor: {
+ if (thisObj != null) {
+ // BaseFunction.construct will set up parent, proto
+ return f.construct(cx, scope, args);
+ }
+ if (args.length == 0 || args[0] == null
+ || args[0] == Undefined.instance)
+ {
+ return new NativeObject();
+ }
+ return ScriptRuntime.toObject(cx, scope, args[0]);
+ }
+
+ case Id_toLocaleString: // For now just alias toString
+ case Id_toString: {
+ if (cx.hasFeature(Context.FEATURE_TO_STRING_AS_SOURCE)) {
+ String s = ScriptRuntime.defaultObjectToSource(cx, scope,
+ thisObj, args);
+ int L = s.length();
+ if (L != 0 && s.charAt(0) == '(' && s.charAt(L - 1) == ')') {
+ // Strip () that surrounds toSource
+ s = s.substring(1, L - 1);
+ }
+ return s;
+ }
+ return ScriptRuntime.defaultObjectToString(thisObj);
+ }
+
+ case Id_valueOf:
+ return thisObj;
+
+ case Id_hasOwnProperty: {
+ boolean result;
+ if (args.length == 0) {
+ result = false;
+ } else {
+ String s = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
+ if (s == null) {
+ int index = ScriptRuntime.lastIndexResult(cx);
+ result = thisObj.has(index, thisObj);
+ } else {
+ result = thisObj.has(s, thisObj);
+ }
+ }
+ return ScriptRuntime.wrapBoolean(result);
+ }
+
+ case Id_propertyIsEnumerable: {
+ boolean result;
+ if (args.length == 0) {
+ result = false;
+ } else {
+ String s = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
+ if (s == null) {
+ int index = ScriptRuntime.lastIndexResult(cx);
+ result = thisObj.has(index, thisObj);
+ if (result && thisObj instanceof ScriptableObject) {
+ ScriptableObject so = (ScriptableObject)thisObj;
+ int attrs = so.getAttributes(index);
+ result = ((attrs & ScriptableObject.DONTENUM) == 0);
+ }
+ } else {
+ result = thisObj.has(s, thisObj);
+ if (result && thisObj instanceof ScriptableObject) {
+ ScriptableObject so = (ScriptableObject)thisObj;
+ int attrs = so.getAttributes(s);
+ result = ((attrs & ScriptableObject.DONTENUM) == 0);
+ }
+ }
+ }
+ return ScriptRuntime.wrapBoolean(result);
+ }
+
+ case Id_isPrototypeOf: {
+ boolean result = false;
+ if (args.length != 0 && args[0] instanceof Scriptable) {
+ Scriptable v = (Scriptable) args[0];
+ do {
+ v = v.getPrototype();
+ if (v == thisObj) {
+ result = true;
+ break;
+ }
+ } while (v != null);
+ }
+ return ScriptRuntime.wrapBoolean(result);
+ }
+
+ case Id_toSource:
+ return ScriptRuntime.defaultObjectToSource(cx, scope, thisObj,
+ args);
+ case Id___defineGetter__:
+ case Id___defineSetter__:
+ {
+ if (args.length < 2 || !(args[1] instanceof Callable)) {
+ Object badArg = (args.length >= 2 ? args[1]
+ : Undefined.instance);
+ throw ScriptRuntime.notFunctionError(badArg);
+ }
+ if (!(thisObj instanceof ScriptableObject)) {
+ throw Context.reportRuntimeError2(
+ "msg.extend.scriptable",
+ thisObj.getClass().getName(),
+ String.valueOf(args[0]));
+ }
+ ScriptableObject so = (ScriptableObject)thisObj;
+ String name = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
+ int index = (name != null ? 0
+ : ScriptRuntime.lastIndexResult(cx));
+ Callable getterOrSetter = (Callable)args[1];
+ boolean isSetter = (id == Id___defineSetter__);
+ so.setGetterOrSetter(name, index, getterOrSetter, isSetter);
+ if (so instanceof NativeArray)
+ ((NativeArray)so).setDenseOnly(false);
+ }
+ return Undefined.instance;
+
+ case Id___lookupGetter__:
+ case Id___lookupSetter__:
+ {
+ if (args.length < 1 ||
+ !(thisObj instanceof ScriptableObject))
+ return Undefined.instance;
+
+ ScriptableObject so = (ScriptableObject)thisObj;
+ String name = ScriptRuntime.toStringIdOrIndex(cx, args[0]);
+ int index = (name != null ? 0
+ : ScriptRuntime.lastIndexResult(cx));
+ boolean isSetter = (id == Id___lookupSetter__);
+ Object gs;
+ for (;;) {
+ gs = so.getGetterOrSetter(name, index, isSetter);
+ if (gs != null)
+ break;
+ // If there is no getter or setter for the object itself,
+ // how about the prototype?
+ Scriptable v = so.getPrototype();
+ if (v == null)
+ break;
+ if (v instanceof ScriptableObject)
+ so = (ScriptableObject)v;
+ else
+ break;
+ }
+ if (gs != null)
+ return gs;
+ }
+ return Undefined.instance;
+
+ default:
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:15:55 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 7: X="valueOf";id=Id_valueOf; break L;
+ case 8: c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ break L;
+ case 11: X="constructor";id=Id_constructor; break L;
+ case 13: X="isPrototypeOf";id=Id_isPrototypeOf; break L;
+ case 14: c=s.charAt(0);
+ if (c=='h') { X="hasOwnProperty";id=Id_hasOwnProperty; }
+ else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; }
+ break L;
+ case 16: c=s.charAt(2);
+ if (c=='d') {
+ c=s.charAt(8);
+ if (c=='G') { X="__defineGetter__";id=Id___defineGetter__; }
+ else if (c=='S') { X="__defineSetter__";id=Id___defineSetter__; }
+ }
+ else if (c=='l') {
+ c=s.charAt(8);
+ if (c=='G') { X="__lookupGetter__";id=Id___lookupGetter__; }
+ else if (c=='S') { X="__lookupSetter__";id=Id___lookupSetter__; }
+ }
+ break L;
+ case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toLocaleString = 3,
+ Id_valueOf = 4,
+ Id_hasOwnProperty = 5,
+ Id_propertyIsEnumerable = 6,
+ Id_isPrototypeOf = 7,
+ Id_toSource = 8,
+ Id___defineGetter__ = 9,
+ Id___defineSetter__ = 10,
+ Id___lookupGetter__ = 11,
+ Id___lookupSetter__ = 12,
+ MAX_PROTOTYPE_ID = 12;
+
+// #/string_id_map#
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java
new file mode 100644
index 0000000..7b5191e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeScript.java
@@ -0,0 +1,221 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Roger Lawrence
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The JavaScript Script object.
+ *
+ * Note that the C version of the engine uses XDR as the format used
+ * by freeze and thaw. Since this depends on the internal format of
+ * structures in the C runtime, we cannot duplicate it.
+ *
+ * Since we cannot replace 'this' as a result of the compile method,
+ * will forward requests to execute to the nonnull 'script' field.
+ *
+ * @since 1.3
+ * @author Norris Boyd
+ */
+
+class NativeScript extends BaseFunction
+{
+ static final long serialVersionUID = -6795101161980121700L;
+
+ private static final Object SCRIPT_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeScript obj = new NativeScript(null);
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ private NativeScript(Script script)
+ {
+ this.script = script;
+ }
+
+ /**
+ * Returns the name of this JavaScript class, "Script".
+ */
+ public String getClassName()
+ {
+ return "Script";
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ if (script != null) {
+ return script.exec(cx, scope);
+ }
+ return Undefined.instance;
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ throw Context.reportRuntimeError0("msg.script.is.not.constructor");
+ }
+
+ public int getLength()
+ {
+ return 0;
+ }
+
+ public int getArity()
+ {
+ return 0;
+ }
+
+ String decompile(int indent, int flags)
+ {
+ if (script instanceof NativeFunction) {
+ return ((NativeFunction)script).decompile(indent, flags);
+ }
+ return super.decompile(indent, flags);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_exec: arity=0; s="exec"; break;
+ case Id_compile: arity=1; s="compile"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(SCRIPT_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(SCRIPT_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor: {
+ String source = (args.length == 0)
+ ? ""
+ : ScriptRuntime.toString(args[0]);
+ Script script = compile(cx, source);
+ NativeScript nscript = new NativeScript(script);
+ ScriptRuntime.setObjectProtoAndParent(nscript, scope);
+ return nscript;
+ }
+
+ case Id_toString: {
+ NativeScript real = realThis(thisObj, f);
+ Script realScript = real.script;
+ if (realScript == null) { return ""; }
+ return cx.decompileScript(realScript, 0);
+ }
+
+ case Id_exec: {
+ throw Context.reportRuntimeError1(
+ "msg.cant.call.indirect", "exec");
+ }
+
+ case Id_compile: {
+ NativeScript real = realThis(thisObj, f);
+ String source = ScriptRuntime.toString(args, 0);
+ real.script = compile(cx, source);
+ return real;
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static NativeScript realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if (!(thisObj instanceof NativeScript))
+ throw incompatibleCallError(f);
+ return (NativeScript)thisObj;
+ }
+
+ private static Script compile(Context cx, String source)
+ {
+ int[] linep = { 0 };
+ String filename = Context.getSourcePositionFromStack(linep);
+ if (filename == null) {
+ filename = "<Script object>";
+ linep[0] = 1;
+ }
+ ErrorReporter reporter;
+ reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
+ return cx.compileString(source, null, reporter, filename,
+ linep[0], null);
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:16:01 EDT
+ L0: { id = 0; String X = null;
+ L: switch (s.length()) {
+ case 4: X="exec";id=Id_exec; break L;
+ case 7: X="compile";id=Id_compile; break L;
+ case 8: X="toString";id=Id_toString; break L;
+ case 11: X="constructor";id=Id_constructor; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_compile = 3,
+ Id_exec = 4,
+ MAX_PROTOTYPE_ID = 4;
+
+// #/string_id_map#
+
+ private Script script;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java
new file mode 100644
index 0000000..972415d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeString.java
@@ -0,0 +1,983 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Tom Beauvais
+ * Norris Boyd
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.text.Collator;
+
+/**
+ * This class implements the String native object.
+ *
+ * See ECMA 15.5.
+ *
+ * String methods for dealing with regular expressions are
+ * ported directly from C. Latest port is from version 1.40.12.19
+ * in the JSFUN13_BRANCH.
+ *
+ * @author Mike McCabe
+ * @author Norris Boyd
+ */
+final class NativeString extends IdScriptableObject
+{
+ static final long serialVersionUID = 920268368584188687L;
+
+ private static final Object STRING_TAG = new Object();
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeString obj = new NativeString("");
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ private NativeString(String s) {
+ string = s;
+ }
+
+ public String getClassName() {
+ return "String";
+ }
+
+ private static final int
+ Id_length = 1,
+ MAX_INSTANCE_ID = 1;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ if (s.equals("length")) {
+ return instanceIdInfo(DONTENUM | READONLY | PERMANENT, Id_length);
+ }
+ return super.findInstanceIdInfo(s);
+ }
+
+ protected String getInstanceIdName(int id)
+ {
+ if (id == Id_length) { return "length"; }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ if (id == Id_length) {
+ return ScriptRuntime.wrapInt(string.length());
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void fillConstructorProperties(IdFunctionObject ctor)
+ {
+ addIdFunctionProperty(ctor, STRING_TAG, ConstructorId_fromCharCode,
+ "fromCharCode", 1);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_charAt, "charAt", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_charCodeAt, "charCodeAt", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_indexOf, "indexOf", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_lastIndexOf, "lastIndexOf", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_split, "split", 3);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_substring, "substring", 3);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_toLowerCase, "toLowerCase", 1);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_toUpperCase, "toUpperCase", 1);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_substr, "substr", 3);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_concat, "concat", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_slice, "slice", 3);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_equalsIgnoreCase, "equalsIgnoreCase", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_match, "match", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_search, "search", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_replace, "replace", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_localeCompare, "localeCompare", 2);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_toLocaleLowerCase, "toLocaleLowerCase", 1);
+ addIdFunctionProperty(ctor, STRING_TAG,
+ ConstructorId_fromCharCode, "fromCharCode", 1);
+ super.fillConstructorProperties(ctor);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=1; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+ case Id_charAt: arity=1; s="charAt"; break;
+ case Id_charCodeAt: arity=1; s="charCodeAt"; break;
+ case Id_indexOf: arity=1; s="indexOf"; break;
+ case Id_lastIndexOf: arity=1; s="lastIndexOf"; break;
+ case Id_split: arity=2; s="split"; break;
+ case Id_substring: arity=2; s="substring"; break;
+ case Id_toLowerCase: arity=0; s="toLowerCase"; break;
+ case Id_toUpperCase: arity=0; s="toUpperCase"; break;
+ case Id_substr: arity=2; s="substr"; break;
+ case Id_concat: arity=1; s="concat"; break;
+ case Id_slice: arity=2; s="slice"; break;
+ case Id_bold: arity=0; s="bold"; break;
+ case Id_italics: arity=0; s="italics"; break;
+ case Id_fixed: arity=0; s="fixed"; break;
+ case Id_strike: arity=0; s="strike"; break;
+ case Id_small: arity=0; s="small"; break;
+ case Id_big: arity=0; s="big"; break;
+ case Id_blink: arity=0; s="blink"; break;
+ case Id_sup: arity=0; s="sup"; break;
+ case Id_sub: arity=0; s="sub"; break;
+ case Id_fontsize: arity=0; s="fontsize"; break;
+ case Id_fontcolor: arity=0; s="fontcolor"; break;
+ case Id_link: arity=0; s="link"; break;
+ case Id_anchor: arity=0; s="anchor"; break;
+ case Id_equals: arity=1; s="equals"; break;
+ case Id_equalsIgnoreCase: arity=1; s="equalsIgnoreCase"; break;
+ case Id_match: arity=1; s="match"; break;
+ case Id_search: arity=1; s="search"; break;
+ case Id_replace: arity=1; s="replace"; break;
+ case Id_localeCompare: arity=1; s="localeCompare"; break;
+ case Id_toLocaleLowerCase: arity=0; s="toLocaleLowerCase"; break;
+ case Id_toLocaleUpperCase: arity=0; s="toLocaleUpperCase"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(STRING_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(STRING_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ again:
+ for(;;) {
+ switch (id) {
+ case ConstructorId_charAt:
+ case ConstructorId_charCodeAt:
+ case ConstructorId_indexOf:
+ case ConstructorId_lastIndexOf:
+ case ConstructorId_split:
+ case ConstructorId_substring:
+ case ConstructorId_toLowerCase:
+ case ConstructorId_toUpperCase:
+ case ConstructorId_substr:
+ case ConstructorId_concat:
+ case ConstructorId_slice:
+ case ConstructorId_equalsIgnoreCase:
+ case ConstructorId_match:
+ case ConstructorId_search:
+ case ConstructorId_replace:
+ case ConstructorId_localeCompare:
+ case ConstructorId_toLocaleLowerCase: {
+ thisObj = ScriptRuntime.toObject(scope,
+ ScriptRuntime.toString(args[0]));
+ Object[] newArgs = new Object[args.length-1];
+ for (int i=0; i < newArgs.length; i++)
+ newArgs[i] = args[i+1];
+ args = newArgs;
+ id = -id;
+ continue again;
+ }
+
+ case ConstructorId_fromCharCode: {
+ int N = args.length;
+ if (N < 1)
+ return "";
+ StringBuffer sb = new StringBuffer(N);
+ for (int i = 0; i != N; ++i) {
+ sb.append(ScriptRuntime.toUint16(args[i]));
+ }
+ return sb.toString();
+ }
+
+ case Id_constructor: {
+ String s = (args.length >= 1)
+ ? ScriptRuntime.toString(args[0]) : "";
+ if (thisObj == null) {
+ // new String(val) creates a new String object.
+ return new NativeString(s);
+ }
+ // String(val) converts val to a string value.
+ return s;
+ }
+
+ case Id_toString:
+ case Id_valueOf:
+ // ECMA 15.5.4.2: 'the toString function is not generic.
+ return realThis(thisObj, f).string;
+
+ case Id_toSource: {
+ String s = realThis(thisObj, f).string;
+ return "(new String(\""+ScriptRuntime.escapeString(s)+"\"))";
+ }
+
+ case Id_charAt:
+ case Id_charCodeAt: {
+ // See ECMA 15.5.4.[4,5]
+ String target = ScriptRuntime.toString(thisObj);
+ double pos = ScriptRuntime.toInteger(args, 0);
+ if (pos < 0 || pos >= target.length()) {
+ if (id == Id_charAt) return "";
+ else return ScriptRuntime.NaNobj;
+ }
+ char c = target.charAt((int)pos);
+ if (id == Id_charAt) return String.valueOf(c);
+ else return ScriptRuntime.wrapInt(c);
+ }
+
+ case Id_indexOf:
+ return ScriptRuntime.wrapInt(js_indexOf(
+ ScriptRuntime.toString(thisObj), args));
+
+ case Id_lastIndexOf:
+ return ScriptRuntime.wrapInt(js_lastIndexOf(
+ ScriptRuntime.toString(thisObj), args));
+
+ case Id_split:
+ return js_split(cx, scope, ScriptRuntime.toString(thisObj),
+ args);
+
+ case Id_substring:
+ return js_substring(cx, ScriptRuntime.toString(thisObj), args);
+
+ case Id_toLowerCase:
+ // See ECMA 15.5.4.11
+ return ScriptRuntime.toString(thisObj).toLowerCase();
+
+ case Id_toUpperCase:
+ // See ECMA 15.5.4.12
+ return ScriptRuntime.toString(thisObj).toUpperCase();
+
+ case Id_substr:
+ return js_substr(ScriptRuntime.toString(thisObj), args);
+
+ case Id_concat:
+ return js_concat(ScriptRuntime.toString(thisObj), args);
+
+ case Id_slice:
+ return js_slice(ScriptRuntime.toString(thisObj), args);
+
+ case Id_bold:
+ return tagify(thisObj, "b", null, null);
+
+ case Id_italics:
+ return tagify(thisObj, "i", null, null);
+
+ case Id_fixed:
+ return tagify(thisObj, "tt", null, null);
+
+ case Id_strike:
+ return tagify(thisObj, "strike", null, null);
+
+ case Id_small:
+ return tagify(thisObj, "small", null, null);
+
+ case Id_big:
+ return tagify(thisObj, "big", null, null);
+
+ case Id_blink:
+ return tagify(thisObj, "blink", null, null);
+
+ case Id_sup:
+ return tagify(thisObj, "sup", null, null);
+
+ case Id_sub:
+ return tagify(thisObj, "sub", null, null);
+
+ case Id_fontsize:
+ return tagify(thisObj, "font", "size", args);
+
+ case Id_fontcolor:
+ return tagify(thisObj, "font", "color", args);
+
+ case Id_link:
+ return tagify(thisObj, "a", "href", args);
+
+ case Id_anchor:
+ return tagify(thisObj, "a", "name", args);
+
+ case Id_equals:
+ case Id_equalsIgnoreCase: {
+ String s1 = ScriptRuntime.toString(thisObj);
+ String s2 = ScriptRuntime.toString(args, 0);
+ return ScriptRuntime.wrapBoolean(
+ (id == Id_equals) ? s1.equals(s2)
+ : s1.equalsIgnoreCase(s2));
+ }
+
+ case Id_match:
+ case Id_search:
+ case Id_replace:
+ {
+ int actionType;
+ if (id == Id_match) {
+ actionType = RegExpProxy.RA_MATCH;
+ } else if (id == Id_search) {
+ actionType = RegExpProxy.RA_SEARCH;
+ } else {
+ actionType = RegExpProxy.RA_REPLACE;
+ }
+ return ScriptRuntime.checkRegExpProxy(cx).
+ action(cx, scope, thisObj, args, actionType);
+ }
+ // ECMA-262 1 5.5.4.9
+ case Id_localeCompare:
+ {
+ // For now, create and configure a collator instance. I can't
+ // actually imagine that this'd be slower than caching them
+ // a la ClassCache, so we aren't trying to outsmart ourselves
+ // with a caching mechanism for now.
+ Collator collator = Collator.getInstance(cx.getLocale());
+ collator.setStrength(Collator.IDENTICAL);
+ collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+ return ScriptRuntime.wrapNumber(collator.compare(
+ ScriptRuntime.toString(thisObj),
+ ScriptRuntime.toString(args, 0)));
+ }
+ case Id_toLocaleLowerCase:
+ {
+ return ScriptRuntime.toString(thisObj)
+ .toLowerCase(cx.getLocale());
+ }
+ case Id_toLocaleUpperCase:
+ {
+ return ScriptRuntime.toString(thisObj)
+ .toUpperCase(cx.getLocale());
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+ }
+
+ private static NativeString realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if (!(thisObj instanceof NativeString))
+ throw incompatibleCallError(f);
+ return (NativeString)thisObj;
+ }
+
+ /*
+ * HTML composition aids.
+ */
+ private static String tagify(Object thisObj, String tag,
+ String attribute, Object[] args)
+ {
+ String str = ScriptRuntime.toString(thisObj);
+ StringBuffer result = new StringBuffer();
+ result.append('<');
+ result.append(tag);
+ if (attribute != null) {
+ result.append(' ');
+ result.append(attribute);
+ result.append("=\"");
+ result.append(ScriptRuntime.toString(args, 0));
+ result.append('"');
+ }
+ result.append('>');
+ result.append(str);
+ result.append("</");
+ result.append(tag);
+ result.append('>');
+ return result.toString();
+ }
+
+ public String toString() {
+ return string;
+ }
+
+ /* Make array-style property lookup work for strings.
+ * XXX is this ECMA? A version check is probably needed. In js too.
+ */
+ public Object get(int index, Scriptable start) {
+ if (0 <= index && index < string.length()) {
+ return string.substring(index, index + 1);
+ }
+ return super.get(index, start);
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ if (0 <= index && index < string.length()) {
+ return;
+ }
+ super.put(index, start, value);
+ }
+
+ /*
+ *
+ * See ECMA 15.5.4.6. Uses Java String.indexOf()
+ * OPT to add - BMH searching from jsstr.c.
+ */
+ private static int js_indexOf(String target, Object[] args) {
+ String search = ScriptRuntime.toString(args, 0);
+ double begin = ScriptRuntime.toInteger(args, 1);
+
+ if (begin > target.length()) {
+ return -1;
+ } else {
+ if (begin < 0)
+ begin = 0;
+ return target.indexOf(search, (int)begin);
+ }
+ }
+
+ /*
+ *
+ * See ECMA 15.5.4.7
+ *
+ */
+ private static int js_lastIndexOf(String target, Object[] args) {
+ String search = ScriptRuntime.toString(args, 0);
+ double end = ScriptRuntime.toNumber(args, 1);
+
+ if (end != end || end > target.length())
+ end = target.length();
+ else if (end < 0)
+ end = 0;
+
+ return target.lastIndexOf(search, (int)end);
+ }
+
+ /*
+ * Used by js_split to find the next split point in target,
+ * starting at offset ip and looking either for the given
+ * separator substring, or for the next re match. ip and
+ * matchlen must be reference variables (assumed to be arrays of
+ * length 1) so they can be updated in the leading whitespace or
+ * re case.
+ *
+ * Return -1 on end of string, >= 0 for a valid index of the next
+ * separator occurrence if found, or the string length if no
+ * separator is found.
+ */
+ private static int find_split(Context cx, Scriptable scope, String target,
+ String separator, int version,
+ RegExpProxy reProxy, Scriptable re,
+ int[] ip, int[] matchlen, boolean[] matched,
+ String[][] parensp)
+ {
+ int i = ip[0];
+ int length = target.length();
+
+ /*
+ * Perl4 special case for str.split(' '), only if the user has selected
+ * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s.
+ * Strange but true, apparently modeled after awk.
+ */
+ if (version == Context.VERSION_1_2 &&
+ re == null && separator.length() == 1 && separator.charAt(0) == ' ')
+ {
+ /* Skip leading whitespace if at front of str. */
+ if (i == 0) {
+ while (i < length && Character.isWhitespace(target.charAt(i)))
+ i++;
+ ip[0] = i;
+ }
+
+ /* Don't delimit whitespace at end of string. */
+ if (i == length)
+ return -1;
+
+ /* Skip over the non-whitespace chars. */
+ while (i < length
+ && !Character.isWhitespace(target.charAt(i)))
+ i++;
+
+ /* Now skip the next run of whitespace. */
+ int j = i;
+ while (j < length && Character.isWhitespace(target.charAt(j)))
+ j++;
+
+ /* Update matchlen to count delimiter chars. */
+ matchlen[0] = j - i;
+ return i;
+ }
+
+ /*
+ * Stop if past end of string. If at end of string, we will
+ * return target length, so that
+ *
+ * "ab,".split(',') => new Array("ab", "")
+ *
+ * and the resulting array converts back to the string "ab,"
+ * for symmetry. NB: This differs from perl, which drops the
+ * trailing empty substring if the LIMIT argument is omitted.
+ */
+ if (i > length)
+ return -1;
+
+ /*
+ * Match a regular expression against the separator at or
+ * above index i. Return -1 at end of string instead of
+ * trying for a match, so we don't get stuck in a loop.
+ */
+ if (re != null) {
+ return reProxy.find_split(cx, scope, target, separator, re,
+ ip, matchlen, matched, parensp);
+ }
+
+ /*
+ * Deviate from ECMA by never splitting an empty string by any separator
+ * string into a non-empty array (an array of length 1 that contains the
+ * empty string).
+ */
+ if (version != Context.VERSION_DEFAULT && version < Context.VERSION_1_3
+ && length == 0)
+ return -1;
+
+ /*
+ * Special case: if sep is the empty string, split str into
+ * one character substrings. Let our caller worry about
+ * whether to split once at end of string into an empty
+ * substring.
+ *
+ * For 1.2 compatibility, at the end of the string, we return the length as
+ * the result, and set the separator length to 1 -- this allows the caller
+ * to include an additional null string at the end of the substring list.
+ */
+ if (separator.length() == 0) {
+ if (version == Context.VERSION_1_2) {
+ if (i == length) {
+ matchlen[0] = 1;
+ return i;
+ }
+ return i + 1;
+ }
+ return (i == length) ? -1 : i + 1;
+ }
+
+ /* Punt to j.l.s.indexOf; return target length if separator is
+ * not found.
+ */
+ if (ip[0] >= length)
+ return length;
+
+ i = target.indexOf(separator, ip[0]);
+
+ return (i != -1) ? i : length;
+ }
+
+ /*
+ * See ECMA 15.5.4.8. Modified to match JS 1.2 - optionally takes
+ * a limit argument and accepts a regular expression as the split
+ * argument.
+ */
+ private static Object js_split(Context cx, Scriptable scope,
+ String target, Object[] args)
+ {
+ // create an empty Array to return;
+ Scriptable top = getTopLevelScope(scope);
+ Scriptable result = ScriptRuntime.newObject(cx, top, "Array", null);
+
+ // return an array consisting of the target if no separator given
+ // don't check against undefined, because we want
+ // 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar']
+ if (args.length < 1) {
+ result.put(0, result, target);
+ return result;
+ }
+
+ // Use the second argument as the split limit, if given.
+ boolean limited = (args.length > 1) && (args[1] != Undefined.instance);
+ long limit = 0; // Initialize to avoid warning.
+ if (limited) {
+ /* Clamp limit between 0 and 1 + string length. */
+ limit = ScriptRuntime.toUint32(args[1]);
+ if (limit > target.length())
+ limit = 1 + target.length();
+ }
+
+ String separator = null;
+ int[] matchlen = new int[1];
+ Scriptable re = null;
+ RegExpProxy reProxy = null;
+ if (args[0] instanceof Scriptable) {
+ reProxy = ScriptRuntime.getRegExpProxy(cx);
+ if (reProxy != null) {
+ Scriptable test = (Scriptable)args[0];
+ if (reProxy.isRegExp(test)) {
+ re = test;
+ }
+ }
+ }
+ if (re == null) {
+ separator = ScriptRuntime.toString(args[0]);
+ matchlen[0] = separator.length();
+ }
+
+ // split target with separator or re
+ int[] ip = { 0 };
+ int match;
+ int len = 0;
+ boolean[] matched = { false };
+ String[][] parens = { null };
+ int version = cx.getLanguageVersion();
+ while ((match = find_split(cx, scope, target, separator, version,
+ reProxy, re, ip, matchlen, matched, parens))
+ >= 0)
+ {
+ if ((limited && len >= limit) || (match > target.length()))
+ break;
+
+ String substr;
+ if (target.length() == 0)
+ substr = target;
+ else
+ substr = target.substring(ip[0], match);
+
+ result.put(len, result, substr);
+ len++;
+ /*
+ * Imitate perl's feature of including parenthesized substrings
+ * that matched part of the delimiter in the new array, after the
+ * split substring that was delimited.
+ */
+ if (re != null && matched[0] == true) {
+ int size = parens[0].length;
+ for (int num = 0; num < size; num++) {
+ if (limited && len >= limit)
+ break;
+ result.put(len, result, parens[0][num]);
+ len++;
+ }
+ matched[0] = false;
+ }
+ ip[0] = match + matchlen[0];
+
+ if (version < Context.VERSION_1_3
+ && version != Context.VERSION_DEFAULT)
+ {
+ /*
+ * Deviate from ECMA to imitate Perl, which omits a final
+ * split unless a limit argument is given and big enough.
+ */
+ if (!limited && ip[0] == target.length())
+ break;
+ }
+ }
+ return result;
+ }
+
+ /*
+ * See ECMA 15.5.4.15
+ */
+ private static String js_substring(Context cx, String target,
+ Object[] args)
+ {
+ int length = target.length();
+ double start = ScriptRuntime.toInteger(args, 0);
+ double end;
+
+ if (start < 0)
+ start = 0;
+ else if (start > length)
+ start = length;
+
+ if (args.length <= 1 || args[1] == Undefined.instance) {
+ end = length;
+ } else {
+ end = ScriptRuntime.toInteger(args[1]);
+ if (end < 0)
+ end = 0;
+ else if (end > length)
+ end = length;
+
+ // swap if end < start
+ if (end < start) {
+ if (cx.getLanguageVersion() != Context.VERSION_1_2) {
+ double temp = start;
+ start = end;
+ end = temp;
+ } else {
+ // Emulate old JDK1.0 java.lang.String.substring()
+ end = start;
+ }
+ }
+ }
+ return target.substring((int)start, (int)end);
+ }
+
+ int getLength() {
+ return string.length();
+ }
+
+ /*
+ * Non-ECMA methods.
+ */
+ private static String js_substr(String target, Object[] args) {
+ if (args.length < 1)
+ return target;
+
+ double begin = ScriptRuntime.toInteger(args[0]);
+ double end;
+ int length = target.length();
+
+ if (begin < 0) {
+ begin += length;
+ if (begin < 0)
+ begin = 0;
+ } else if (begin > length) {
+ begin = length;
+ }
+
+ if (args.length == 1) {
+ end = length;
+ } else {
+ end = ScriptRuntime.toInteger(args[1]);
+ if (end < 0)
+ end = 0;
+ end += begin;
+ if (end > length)
+ end = length;
+ }
+
+ return target.substring((int)begin, (int)end);
+ }
+
+ /*
+ * Python-esque sequence operations.
+ */
+ private static String js_concat(String target, Object[] args) {
+ int N = args.length;
+ if (N == 0) { return target; }
+ else if (N == 1) {
+ String arg = ScriptRuntime.toString(args[0]);
+ return target.concat(arg);
+ }
+
+ // Find total capacity for the final string to avoid unnecessary
+ // re-allocations in StringBuffer
+ int size = target.length();
+ String[] argsAsStrings = new String[N];
+ for (int i = 0; i != N; ++i) {
+ String s = ScriptRuntime.toString(args[i]);
+ argsAsStrings[i] = s;
+ size += s.length();
+ }
+
+ StringBuffer result = new StringBuffer(size);
+ result.append(target);
+ for (int i = 0; i != N; ++i) {
+ result.append(argsAsStrings[i]);
+ }
+ return result.toString();
+ }
+
+ private static String js_slice(String target, Object[] args) {
+ if (args.length != 0) {
+ double begin = ScriptRuntime.toInteger(args[0]);
+ double end;
+ int length = target.length();
+ if (begin < 0) {
+ begin += length;
+ if (begin < 0)
+ begin = 0;
+ } else if (begin > length) {
+ begin = length;
+ }
+
+ if (args.length == 1) {
+ end = length;
+ } else {
+ end = ScriptRuntime.toInteger(args[1]);
+ if (end < 0) {
+ end += length;
+ if (end < 0)
+ end = 0;
+ } else if (end > length) {
+ end = length;
+ }
+ if (end < begin)
+ end = begin;
+ }
+ return target.substring((int)begin, (int)end);
+ }
+ return target;
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-01 22:11:49 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 3: c=s.charAt(2);
+ if (c=='b') { if (s.charAt(0)=='s' && s.charAt(1)=='u') {id=Id_sub; break L0;} }
+ else if (c=='g') { if (s.charAt(0)=='b' && s.charAt(1)=='i') {id=Id_big; break L0;} }
+ else if (c=='p') { if (s.charAt(0)=='s' && s.charAt(1)=='u') {id=Id_sup; break L0;} }
+ break L;
+ case 4: c=s.charAt(0);
+ if (c=='b') { X="bold";id=Id_bold; }
+ else if (c=='l') { X="link";id=Id_link; }
+ break L;
+ case 5: switch (s.charAt(4)) {
+ case 'd': X="fixed";id=Id_fixed; break L;
+ case 'e': X="slice";id=Id_slice; break L;
+ case 'h': X="match";id=Id_match; break L;
+ case 'k': X="blink";id=Id_blink; break L;
+ case 'l': X="small";id=Id_small; break L;
+ case 't': X="split";id=Id_split; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'e': X="search";id=Id_search; break L;
+ case 'h': X="charAt";id=Id_charAt; break L;
+ case 'n': X="anchor";id=Id_anchor; break L;
+ case 'o': X="concat";id=Id_concat; break L;
+ case 'q': X="equals";id=Id_equals; break L;
+ case 't': X="strike";id=Id_strike; break L;
+ case 'u': X="substr";id=Id_substr; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="valueOf";id=Id_valueOf; break L;
+ case 'e': X="replace";id=Id_replace; break L;
+ case 'n': X="indexOf";id=Id_indexOf; break L;
+ case 't': X="italics";id=Id_italics; break L;
+ } break L;
+ case 8: c=s.charAt(4);
+ if (c=='r') { X="toString";id=Id_toString; }
+ else if (c=='s') { X="fontsize";id=Id_fontsize; }
+ else if (c=='u') { X="toSource";id=Id_toSource; }
+ break L;
+ case 9: c=s.charAt(0);
+ if (c=='f') { X="fontcolor";id=Id_fontcolor; }
+ else if (c=='s') { X="substring";id=Id_substring; }
+ break L;
+ case 10: X="charCodeAt";id=Id_charCodeAt; break L;
+ case 11: switch (s.charAt(2)) {
+ case 'L': X="toLowerCase";id=Id_toLowerCase; break L;
+ case 'U': X="toUpperCase";id=Id_toUpperCase; break L;
+ case 'n': X="constructor";id=Id_constructor; break L;
+ case 's': X="lastIndexOf";id=Id_lastIndexOf; break L;
+ } break L;
+ case 13: X="localeCompare";id=Id_localeCompare; break L;
+ case 16: X="equalsIgnoreCase";id=Id_equalsIgnoreCase; break L;
+ case 17: c=s.charAt(8);
+ if (c=='L') { X="toLocaleLowerCase";id=Id_toLocaleLowerCase; }
+ else if (c=='U') { X="toLocaleUpperCase";id=Id_toLocaleUpperCase; }
+ break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ ConstructorId_fromCharCode = -1,
+
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ Id_valueOf = 4,
+ Id_charAt = 5,
+ Id_charCodeAt = 6,
+ Id_indexOf = 7,
+ Id_lastIndexOf = 8,
+ Id_split = 9,
+ Id_substring = 10,
+ Id_toLowerCase = 11,
+ Id_toUpperCase = 12,
+ Id_substr = 13,
+ Id_concat = 14,
+ Id_slice = 15,
+ Id_bold = 16,
+ Id_italics = 17,
+ Id_fixed = 18,
+ Id_strike = 19,
+ Id_small = 20,
+ Id_big = 21,
+ Id_blink = 22,
+ Id_sup = 23,
+ Id_sub = 24,
+ Id_fontsize = 25,
+ Id_fontcolor = 26,
+ Id_link = 27,
+ Id_anchor = 28,
+ Id_equals = 29,
+ Id_equalsIgnoreCase = 30,
+ Id_match = 31,
+ Id_search = 32,
+ Id_replace = 33,
+ Id_localeCompare = 34,
+ Id_toLocaleLowerCase = 35,
+ Id_toLocaleUpperCase = 36,
+ MAX_PROTOTYPE_ID = 36;
+
+// #/string_id_map#
+
+ private static final int
+ ConstructorId_charAt = -Id_charAt,
+ ConstructorId_charCodeAt = -Id_charCodeAt,
+ ConstructorId_indexOf = -Id_indexOf,
+ ConstructorId_lastIndexOf = -Id_lastIndexOf,
+ ConstructorId_split = -Id_split,
+ ConstructorId_substring = -Id_substring,
+ ConstructorId_toLowerCase = -Id_toLowerCase,
+ ConstructorId_toUpperCase = -Id_toUpperCase,
+ ConstructorId_substr = -Id_substr,
+ ConstructorId_concat = -Id_concat,
+ ConstructorId_slice = -Id_slice,
+ ConstructorId_equalsIgnoreCase = -Id_equalsIgnoreCase,
+ ConstructorId_match = -Id_match,
+ ConstructorId_search = -Id_search,
+ ConstructorId_replace = -Id_replace,
+ ConstructorId_localeCompare = -Id_localeCompare,
+ ConstructorId_toLocaleLowerCase = -Id_toLocaleLowerCase;
+
+ private String string;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java
new file mode 100644
index 0000000..83683b2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NativeWith.java
@@ -0,0 +1,207 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+/**
+ * This class implements the object lookup required for the
+ * <code>with</code> statement.
+ * It simply delegates every action to its prototype except
+ * for operations on its parent.
+ */
+public class NativeWith implements Scriptable, IdFunctionCall, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ static void init(Scriptable scope, boolean sealed)
+ {
+ NativeWith obj = new NativeWith();
+
+ obj.setParentScope(scope);
+ obj.setPrototype(ScriptableObject.getObjectPrototype(scope));
+
+ IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_constructor,
+ "With", 0, scope);
+ ctor.markAsConstructor(obj);
+ if (sealed) {
+ ctor.sealObject();
+ }
+ ctor.exportAsScopeProperty();
+ }
+
+ private NativeWith() {
+ }
+
+ protected NativeWith(Scriptable parent, Scriptable prototype) {
+ this.parent = parent;
+ this.prototype = prototype;
+ }
+
+ public String getClassName() {
+ return "With";
+ }
+
+ public boolean has(String id, Scriptable start)
+ {
+ return prototype.has(id, prototype);
+ }
+
+ public boolean has(int index, Scriptable start)
+ {
+ return prototype.has(index, prototype);
+ }
+
+ public Object get(String id, Scriptable start)
+ {
+ if (start == this)
+ start = prototype;
+ return prototype.get(id, start);
+ }
+
+ public Object get(int index, Scriptable start)
+ {
+ if (start == this)
+ start = prototype;
+ return prototype.get(index, start);
+ }
+
+ public void put(String id, Scriptable start, Object value)
+ {
+ if (start == this)
+ start = prototype;
+ prototype.put(id, start, value);
+ }
+
+ public void put(int index, Scriptable start, Object value)
+ {
+ if (start == this)
+ start = prototype;
+ prototype.put(index, start, value);
+ }
+
+ public void delete(String id)
+ {
+ prototype.delete(id);
+ }
+
+ public void delete(int index)
+ {
+ prototype.delete(index);
+ }
+
+ public Scriptable getPrototype() {
+ return prototype;
+ }
+
+ public void setPrototype(Scriptable prototype) {
+ this.prototype = prototype;
+ }
+
+ public Scriptable getParentScope() {
+ return parent;
+ }
+
+ public void setParentScope(Scriptable parent) {
+ this.parent = parent;
+ }
+
+ public Object[] getIds() {
+ return prototype.getIds();
+ }
+
+ public Object getDefaultValue(Class typeHint) {
+ return prototype.getDefaultValue(typeHint);
+ }
+
+ public boolean hasInstance(Scriptable value) {
+ return prototype.hasInstance(value);
+ }
+
+ /**
+ * Must return null to continue looping or the final collection result.
+ */
+ protected Object updateDotQuery(boolean value)
+ {
+ // NativeWith itself does not support it
+ throw new IllegalStateException();
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (f.hasTag(FTAG)) {
+ if (f.methodId() == Id_constructor) {
+ throw Context.reportRuntimeError1("msg.cant.call.indirect", "With");
+ }
+ }
+ throw f.unknown();
+ }
+
+ static boolean isWithFunction(Object functionObj)
+ {
+ if (functionObj instanceof IdFunctionObject) {
+ IdFunctionObject f = (IdFunctionObject)functionObj;
+ return f.hasTag(FTAG) && f.methodId() == Id_constructor;
+ }
+ return false;
+ }
+
+ static Object newWithSpecial(Context cx, Scriptable scope, Object[] args)
+ {
+ ScriptRuntime.checkDeprecated(cx, "With");
+ scope = ScriptableObject.getTopLevelScope(scope);
+ NativeWith thisObj = new NativeWith();
+ thisObj.setPrototype(args.length == 0
+ ? ScriptableObject.getClassPrototype(scope,
+ "Object")
+ : ScriptRuntime.toObject(cx, scope, args[0]));
+ thisObj.setParentScope(scope);
+ return thisObj;
+ }
+
+ private static final Object FTAG = new Object();
+
+ private static final int
+ Id_constructor = 1;
+
+ protected Scriptable prototype;
+ protected Scriptable parent;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java
new file mode 100644
index 0000000..4298388
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Node.java
@@ -0,0 +1,1394 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roshan James
+ * Roger Lawrence
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.util.Collections;
+
+/**
+ * This class implements the root of the intermediate representation.
+ *
+ * @author Norris Boyd
+ * @author Mike McCabe
+ */
+
+public class Node
+{
+ public static final int
+ FUNCTION_PROP = 1,
+ LOCAL_PROP = 2,
+ LOCAL_BLOCK_PROP = 3,
+ REGEXP_PROP = 4,
+ CASEARRAY_PROP = 5,
+ /*
+ the following properties are defined and manipulated by the
+ optimizer -
+ TARGETBLOCK_PROP - the block referenced by a branch node
+ VARIABLE_PROP - the variable referenced by a BIND or NAME node
+ ISNUMBER_PROP - this node generates code on Number children and
+ delivers a Number result (as opposed to Objects)
+ DIRECTCALL_PROP - this call node should emit code to test the function
+ object against the known class and call diret if it
+ matches.
+ */
+
+ TARGETBLOCK_PROP = 6,
+ VARIABLE_PROP = 7,
+ ISNUMBER_PROP = 8,
+ DIRECTCALL_PROP = 9,
+ SPECIALCALL_PROP = 10,
+ SKIP_INDEXES_PROP = 11, // array of skipped indexes of array literal
+ OBJECT_IDS_PROP = 12, // array of properties for object literal
+ INCRDECR_PROP = 13, // pre or post type of increment/decerement
+ CATCH_SCOPE_PROP = 14, // index of catch scope block in catch
+ LABEL_ID_PROP = 15, // label id: code generation uses it
+ MEMBER_TYPE_PROP = 16, // type of element access operation
+ NAME_PROP = 17, // property name
+ CONTROL_BLOCK_PROP = 18, // flags a control block that can drop off
+ PARENTHESIZED_PROP = 19, // expression is parenthesized
+ GENERATOR_END_PROP = 20,
+ DESTRUCTURING_ARRAY_LENGTH = 21,
+ DESTRUCTURING_NAMES= 22,
+ LAST_PROP = 22;
+
+ // values of ISNUMBER_PROP to specify
+ // which of the children are Number types
+ public static final int
+ BOTH = 0,
+ LEFT = 1,
+ RIGHT = 2;
+
+ public static final int // values for SPECIALCALL_PROP
+ NON_SPECIALCALL = 0,
+ SPECIALCALL_EVAL = 1,
+ SPECIALCALL_WITH = 2;
+
+ public static final int // flags for INCRDECR_PROP
+ DECR_FLAG = 0x1,
+ POST_FLAG = 0x2;
+
+ public static final int // flags for MEMBER_TYPE_PROP
+ PROPERTY_FLAG = 0x1, // property access: element is valid name
+ ATTRIBUTE_FLAG = 0x2, // x.@y or x..@y
+ DESCENDANTS_FLAG = 0x4; // x..y or x..@i
+
+ private static class NumberNode extends Node
+ {
+ NumberNode(double number)
+ {
+ super(Token.NUMBER);
+ this.number = number;
+ }
+
+ double number;
+ }
+
+ private static class StringNode extends Node
+ {
+ StringNode(int type, String str) {
+ super(type);
+ this.str = str;
+ }
+
+ String str;
+ Node.Scope scope;
+ }
+
+ public static class Jump extends Node
+ {
+ public Jump(int type)
+ {
+ super(type);
+ }
+
+ Jump(int type, int lineno)
+ {
+ super(type, lineno);
+ }
+
+ Jump(int type, Node child)
+ {
+ super(type, child);
+ }
+
+ Jump(int type, Node child, int lineno)
+ {
+ super(type, child, lineno);
+ }
+
+ public final Jump getJumpStatement()
+ {
+ if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug();
+ return jumpNode;
+ }
+
+ public final void setJumpStatement(Jump jumpStatement)
+ {
+ if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug();
+ if (jumpStatement == null) Kit.codeBug();
+ if (this.jumpNode != null) Kit.codeBug(); //only once
+ this.jumpNode = jumpStatement;
+ }
+
+ public final Node getDefault()
+ {
+ if (!(type == Token.SWITCH)) Kit.codeBug();
+ return target2;
+ }
+
+ public final void setDefault(Node defaultTarget)
+ {
+ if (!(type == Token.SWITCH)) Kit.codeBug();
+ if (defaultTarget.type != Token.TARGET) Kit.codeBug();
+ if (target2 != null) Kit.codeBug(); //only once
+ target2 = defaultTarget;
+ }
+
+ public final Node getFinally()
+ {
+ if (!(type == Token.TRY)) Kit.codeBug();
+ return target2;
+ }
+
+ public final void setFinally(Node finallyTarget)
+ {
+ if (!(type == Token.TRY)) Kit.codeBug();
+ if (finallyTarget.type != Token.TARGET) Kit.codeBug();
+ if (target2 != null) Kit.codeBug(); //only once
+ target2 = finallyTarget;
+ }
+
+ public final Jump getLoop()
+ {
+ if (!(type == Token.LABEL)) Kit.codeBug();
+ return jumpNode;
+ }
+
+ public final void setLoop(Jump loop)
+ {
+ if (!(type == Token.LABEL)) Kit.codeBug();
+ if (loop == null) Kit.codeBug();
+ if (jumpNode != null) Kit.codeBug(); //only once
+ jumpNode = loop;
+ }
+
+ public final Node getContinue()
+ {
+ if (type != Token.LOOP) Kit.codeBug();
+ return target2;
+ }
+
+ public final void setContinue(Node continueTarget)
+ {
+ if (type != Token.LOOP) Kit.codeBug();
+ if (continueTarget.type != Token.TARGET) Kit.codeBug();
+ if (target2 != null) Kit.codeBug(); //only once
+ target2 = continueTarget;
+ }
+
+ public Node target;
+ private Node target2;
+ private Jump jumpNode;
+ }
+
+ static class Symbol {
+ Symbol(int declType, String name) {
+ this.declType = declType;
+ this.name = name;
+ this.index = -1;
+ }
+ /**
+ * One of Token.FUNCTION, Token.LP (for parameters), Token.VAR,
+ * Token.LET, or Token.CONST
+ */
+ int declType;
+ int index;
+ String name;
+ Node.Scope containingTable;
+ }
+
+ static class Scope extends Jump {
+ public Scope(int nodeType) {
+ super(nodeType);
+ }
+
+ public Scope(int nodeType, int lineno) {
+ super(nodeType, lineno);
+ }
+
+ public Scope(int nodeType, Node n, int lineno) {
+ super(nodeType, n, lineno);
+ }
+
+ /*
+ * Creates a new scope node, moving symbol table information
+ * from "scope" to the new node, and making "scope" a nested
+ * scope contained by the new node.
+ * Useful for injecting a new scope in a scope chain.
+ */
+ public static Scope splitScope(Scope scope) {
+ Scope result = new Scope(scope.getType());
+ result.symbolTable = scope.symbolTable;
+ scope.symbolTable = null;
+ result.parent = scope.parent;
+ scope.parent = result;
+ result.top = scope.top;
+ return result;
+ }
+
+ public static void joinScopes(Scope source, Scope dest) {
+ source.ensureSymbolTable();
+ dest.ensureSymbolTable();
+ if (!Collections.disjoint(source.symbolTable.keySet(),
+ dest.symbolTable.keySet()))
+ {
+ throw Kit.codeBug();
+ }
+ dest.symbolTable.putAll(source.symbolTable);
+ }
+
+ public void setParent(Scope parent) {
+ this.parent = parent;
+ this.top = parent == null ? (ScriptOrFnNode)this : parent.top;
+ }
+
+ public Scope getParentScope() {
+ return parent;
+ }
+
+ public Scope getDefiningScope(String name) {
+ for (Scope sn=this; sn != null; sn = sn.parent) {
+ if (sn.symbolTable == null)
+ continue;
+ if (sn.symbolTable.containsKey(name))
+ return sn;
+ }
+ return null;
+ }
+
+ public Symbol getSymbol(String name) {
+ return symbolTable == null ? null : symbolTable.get(name);
+ }
+
+ public void putSymbol(String name, Symbol symbol) {
+ ensureSymbolTable();
+ symbolTable.put(name, symbol);
+ symbol.containingTable = this;
+ top.addSymbol(symbol);
+ }
+
+ public Map<String,Symbol> getSymbolTable() {
+ return symbolTable;
+ }
+
+ private void ensureSymbolTable() {
+ if (symbolTable == null) {
+ symbolTable = new LinkedHashMap<String,Symbol>(5);
+ }
+ }
+
+ // Use LinkedHashMap so that the iteration order is the insertion order
+ protected LinkedHashMap<String,Symbol> symbolTable;
+ private Scope parent;
+ private ScriptOrFnNode top;
+ }
+
+ private static class PropListItem
+ {
+ PropListItem next;
+ int type;
+ int intValue;
+ Object objectValue;
+ }
+
+
+ public Node(int nodeType) {
+ type = nodeType;
+ }
+
+ public Node(int nodeType, Node child) {
+ type = nodeType;
+ first = last = child;
+ child.next = null;
+ }
+
+ public Node(int nodeType, Node left, Node right) {
+ type = nodeType;
+ first = left;
+ last = right;
+ left.next = right;
+ right.next = null;
+ }
+
+ public Node(int nodeType, Node left, Node mid, Node right) {
+ type = nodeType;
+ first = left;
+ last = right;
+ left.next = mid;
+ mid.next = right;
+ right.next = null;
+ }
+
+ public Node(int nodeType, int line) {
+ type = nodeType;
+ lineno = line;
+ }
+
+ public Node(int nodeType, Node child, int line) {
+ this(nodeType, child);
+ lineno = line;
+ }
+
+ public Node(int nodeType, Node left, Node right, int line) {
+ this(nodeType, left, right);
+ lineno = line;
+ }
+
+ public Node(int nodeType, Node left, Node mid, Node right, int line) {
+ this(nodeType, left, mid, right);
+ lineno = line;
+ }
+
+ public static Node newNumber(double number) {
+ return new NumberNode(number);
+ }
+
+ public static Node newString(String str) {
+ return new StringNode(Token.STRING, str);
+ }
+
+ public static Node newString(int type, String str) {
+ return new StringNode(type, str);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public boolean hasChildren() {
+ return first != null;
+ }
+
+ public Node getFirstChild() {
+ return first;
+ }
+
+ public Node getLastChild() {
+ return last;
+ }
+
+ public Node getNext() {
+ return next;
+ }
+
+ public Node getChildBefore(Node child) {
+ if (child == first)
+ return null;
+ Node n = first;
+ while (n.next != child) {
+ n = n.next;
+ if (n == null)
+ throw new RuntimeException("node is not a child");
+ }
+ return n;
+ }
+
+ public Node getLastSibling() {
+ Node n = this;
+ while (n.next != null) {
+ n = n.next;
+ }
+ return n;
+ }
+
+ public void addChildToFront(Node child) {
+ child.next = first;
+ first = child;
+ if (last == null) {
+ last = child;
+ }
+ }
+
+ public void addChildToBack(Node child) {
+ child.next = null;
+ if (last == null) {
+ first = last = child;
+ return;
+ }
+ last.next = child;
+ last = child;
+ }
+
+ public void addChildrenToFront(Node children) {
+ Node lastSib = children.getLastSibling();
+ lastSib.next = first;
+ first = children;
+ if (last == null) {
+ last = lastSib;
+ }
+ }
+
+ public void addChildrenToBack(Node children) {
+ if (last != null) {
+ last.next = children;
+ }
+ last = children.getLastSibling();
+ if (first == null) {
+ first = children;
+ }
+ }
+
+ /**
+ * Add 'child' before 'node'.
+ */
+ public void addChildBefore(Node newChild, Node node) {
+ if (newChild.next != null)
+ throw new RuntimeException(
+ "newChild had siblings in addChildBefore");
+ if (first == node) {
+ newChild.next = first;
+ first = newChild;
+ return;
+ }
+ Node prev = getChildBefore(node);
+ addChildAfter(newChild, prev);
+ }
+
+ /**
+ * Add 'child' after 'node'.
+ */
+ public void addChildAfter(Node newChild, Node node) {
+ if (newChild.next != null)
+ throw new RuntimeException(
+ "newChild had siblings in addChildAfter");
+ newChild.next = node.next;
+ node.next = newChild;
+ if (last == node)
+ last = newChild;
+ }
+
+ public void removeChild(Node child) {
+ Node prev = getChildBefore(child);
+ if (prev == null)
+ first = first.next;
+ else
+ prev.next = child.next;
+ if (child == last) last = prev;
+ child.next = null;
+ }
+
+ public void replaceChild(Node child, Node newChild) {
+ newChild.next = child.next;
+ if (child == first) {
+ first = newChild;
+ } else {
+ Node prev = getChildBefore(child);
+ prev.next = newChild;
+ }
+ if (child == last)
+ last = newChild;
+ child.next = null;
+ }
+
+ public void replaceChildAfter(Node prevChild, Node newChild) {
+ Node child = prevChild.next;
+ newChild.next = child.next;
+ prevChild.next = newChild;
+ if (child == last)
+ last = newChild;
+ child.next = null;
+ }
+
+ private static final String propToString(int propType)
+ {
+ if (Token.printTrees) {
+ // If Context.printTrees is false, the compiler
+ // can remove all these strings.
+ switch (propType) {
+ case FUNCTION_PROP: return "function";
+ case LOCAL_PROP: return "local";
+ case LOCAL_BLOCK_PROP: return "local_block";
+ case REGEXP_PROP: return "regexp";
+ case CASEARRAY_PROP: return "casearray";
+
+ case TARGETBLOCK_PROP: return "targetblock";
+ case VARIABLE_PROP: return "variable";
+ case ISNUMBER_PROP: return "isnumber";
+ case DIRECTCALL_PROP: return "directcall";
+
+ case SPECIALCALL_PROP: return "specialcall";
+ case SKIP_INDEXES_PROP: return "skip_indexes";
+ case OBJECT_IDS_PROP: return "object_ids_prop";
+ case INCRDECR_PROP: return "incrdecr_prop";
+ case CATCH_SCOPE_PROP: return "catch_scope_prop";
+ case LABEL_ID_PROP: return "label_id_prop";
+ case MEMBER_TYPE_PROP: return "member_type_prop";
+ case NAME_PROP: return "name_prop";
+ case CONTROL_BLOCK_PROP: return "control_block_prop";
+ case PARENTHESIZED_PROP: return "parenthesized_prop";
+ case GENERATOR_END_PROP: return "generator_end";
+ case DESTRUCTURING_ARRAY_LENGTH:
+ return "destructuring_array_length";
+ case DESTRUCTURING_NAMES:return "destructuring_names";
+
+ default: Kit.codeBug();
+ }
+ }
+ return null;
+ }
+
+ private PropListItem lookupProperty(int propType)
+ {
+ PropListItem x = propListHead;
+ while (x != null && propType != x.type) {
+ x = x.next;
+ }
+ return x;
+ }
+
+ private PropListItem ensureProperty(int propType)
+ {
+ PropListItem item = lookupProperty(propType);
+ if (item == null) {
+ item = new PropListItem();
+ item.type = propType;
+ item.next = propListHead;
+ propListHead = item;
+ }
+ return item;
+ }
+
+ public void removeProp(int propType)
+ {
+ PropListItem x = propListHead;
+ if (x != null) {
+ PropListItem prev = null;
+ while (x.type != propType) {
+ prev = x;
+ x = x.next;
+ if (x == null) { return; }
+ }
+ if (prev == null) {
+ propListHead = x.next;
+ } else {
+ prev.next = x.next;
+ }
+ }
+ }
+
+ public Object getProp(int propType)
+ {
+ PropListItem item = lookupProperty(propType);
+ if (item == null) { return null; }
+ return item.objectValue;
+ }
+
+ public int getIntProp(int propType, int defaultValue)
+ {
+ PropListItem item = lookupProperty(propType);
+ if (item == null) { return defaultValue; }
+ return item.intValue;
+ }
+
+ public int getExistingIntProp(int propType)
+ {
+ PropListItem item = lookupProperty(propType);
+ if (item == null) { Kit.codeBug(); }
+ return item.intValue;
+ }
+
+ public void putProp(int propType, Object prop)
+ {
+ if (prop == null) {
+ removeProp(propType);
+ } else {
+ PropListItem item = ensureProperty(propType);
+ item.objectValue = prop;
+ }
+ }
+
+ public void putIntProp(int propType, int prop)
+ {
+ PropListItem item = ensureProperty(propType);
+ item.intValue = prop;
+ }
+
+ public int getLineno() {
+ return lineno;
+ }
+
+ /** Can only be called when <tt>getType() == Token.NUMBER</tt> */
+ public final double getDouble() {
+ return ((NumberNode)this).number;
+ }
+
+ public final void setDouble(double number) {
+ ((NumberNode)this).number = number;
+ }
+
+ /** Can only be called when node has String context. */
+ public final String getString() {
+ return ((StringNode)this).str;
+ }
+
+ /** Can only be called when node has String context. */
+ public final void setString(String s) {
+ if (s == null) Kit.codeBug();
+ ((StringNode)this).str = s;
+ }
+
+ /** Can only be called when node has String context. */
+ public final Scope getScope() {
+ return ((StringNode)this).scope;
+ }
+
+ /** Can only be called when node has String context. */
+ public final void setScope(Scope s) {
+ if (s == null) Kit.codeBug();
+ if (!(this instanceof StringNode)) {
+ throw Kit.codeBug();
+ }
+ ((StringNode)this).scope = s;
+ }
+
+ public static Node newTarget()
+ {
+ return new Node(Token.TARGET);
+ }
+
+ public final int labelId()
+ {
+ if (type != Token.TARGET && type != Token.YIELD) Kit.codeBug();
+ return getIntProp(LABEL_ID_PROP, -1);
+ }
+
+ public void labelId(int labelId)
+ {
+ if (type != Token.TARGET && type != Token.YIELD) Kit.codeBug();
+ putIntProp(LABEL_ID_PROP, labelId);
+ }
+
+
+ /**
+ * Does consistent-return analysis on the function body when strict mode is
+ * enabled.
+ *
+ * function (x) { return (x+1) }
+ * is ok, but
+ * function (x) { if (x < 0) return (x+1); }
+ * is not becuase the function can potentially return a value when the
+ * condition is satisfied and if not, the function does not explicitly
+ * return value.
+ *
+ * This extends to checking mismatches such as "return" and "return <value>"
+ * used in the same function. Warnings are not emitted if inconsistent
+ * returns exist in code that can be statically shown to be unreachable.
+ * Ex.
+ * function (x) { while (true) { ... if (..) { return value } ... } }
+ * emits no warning. However if the loop had a break statement, then a
+ * warning would be emitted.
+ *
+ * The consistency analysis looks at control structures such as loops, ifs,
+ * switch, try-catch-finally blocks, examines the reachable code paths and
+ * warns the user about an inconsistent set of termination possibilities.
+ *
+ * Caveat: Since the parser flattens many control structures into almost
+ * straight-line code with gotos, it makes such analysis hard. Hence this
+ * analyser is written to taken advantage of patterns of code generated by
+ * the parser (for loops, try blocks and such) and does not do a full
+ * control flow analysis of the gotos and break/continue statements.
+ * Future changes to the parser will affect this analysis.
+ */
+
+ /**
+ * These flags enumerate the possible ways a statement/function can
+ * terminate. These flags are used by endCheck() and by the Parser to
+ * detect inconsistent return usage.
+ *
+ * END_UNREACHED is reserved for code paths that are assumed to always be
+ * able to execute (example: throw, continue)
+ *
+ * END_DROPS_OFF indicates if the statement can transfer control to the
+ * next one. Statement such as return dont. A compound statement may have
+ * some branch that drops off control to the next statement.
+ *
+ * END_RETURNS indicates that the statement can return (without arguments)
+ * END_RETURNS_VALUE indicates that the statement can return a value.
+ *
+ * A compound statement such as
+ * if (condition) {
+ * return value;
+ * }
+ * Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
+ */
+ static final int END_UNREACHED = 0;
+ static final int END_DROPS_OFF = 1;
+ static final int END_RETURNS = 2;
+ static final int END_RETURNS_VALUE = 4;
+ static final int END_YIELDS = 8;
+
+ /**
+ * Checks that every return usage in a function body is consistent with the
+ * requirements of strict-mode.
+ * @return true if the function satisfies strict mode requirement.
+ */
+ public boolean hasConsistentReturnUsage()
+ {
+ int n = endCheck();
+ return (n & END_RETURNS_VALUE) == 0 ||
+ (n & (END_DROPS_OFF|END_RETURNS|END_YIELDS)) == 0;
+ }
+
+ /**
+ * Returns in the then and else blocks must be consistent with each other.
+ * If there is no else block, then the return statement can fall through.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckIf()
+ {
+ Node th, el;
+ int rv = END_UNREACHED;
+
+ th = next;
+ el = ((Jump)this).target;
+
+ rv = th.endCheck();
+
+ if (el != null)
+ rv |= el.endCheck();
+ else
+ rv |= END_DROPS_OFF;
+
+ return rv;
+ }
+
+ /**
+ * Consistency of return statements is checked between the case statements.
+ * If there is no default, then the switch can fall through. If there is a
+ * default,we check to see if all code paths in the default return or if
+ * there is a code path that can fall through.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckSwitch()
+ {
+ Node n;
+ int rv = END_UNREACHED;
+
+ // examine the cases
+ for (n = first.next; n != null; n = n.next)
+ {
+ if (n.type == Token.CASE) {
+ rv |= ((Jump)n).target.endCheck();
+ } else
+ break;
+ }
+
+ // we don't care how the cases drop into each other
+ rv &= ~END_DROPS_OFF;
+
+ // examine the default
+ n = ((Jump)this).getDefault();
+ if (n != null)
+ rv |= n.endCheck();
+ else
+ rv |= END_DROPS_OFF;
+
+ // remove the switch block
+ rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
+
+ return rv;
+ }
+
+ /**
+ * If the block has a finally, return consistency is checked in the
+ * finally block. If all code paths in the finally returns, then the
+ * returns in the try-catch blocks don't matter. If there is a code path
+ * that does not return or if there is no finally block, the returns
+ * of the try and catch blocks are checked for mismatch.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckTry()
+ {
+ Node n;
+ int rv = END_UNREACHED;
+
+ // check the finally if it exists
+ n = ((Jump)this).getFinally();
+ if(n != null) {
+ rv = n.next.first.endCheck();
+ } else {
+ rv = END_DROPS_OFF;
+ }
+
+ // if the finally block always returns, then none of the returns
+ // in the try or catch blocks matter
+ if ((rv & END_DROPS_OFF) != 0) {
+ rv &= ~END_DROPS_OFF;
+
+ // examine the try block
+ rv |= first.endCheck();
+
+ // check each catch block
+ n = ((Jump)this).target;
+ if (n != null)
+ {
+ // point to the first catch_scope
+ for (n = n.next.first; n != null; n = n.next.next)
+ {
+ // check the block of user code in the catch_scope
+ rv |= n.next.first.next.first.endCheck();
+ }
+ }
+ }
+
+ return rv;
+ }
+
+ /**
+ * Return statement in the loop body must be consistent. The default
+ * assumption for any kind of a loop is that it will eventually terminate.
+ * The only exception is a loop with a constant true condition. Code that
+ * follows such a loop is examined only if one can statically determine
+ * that there is a break out of the loop.
+ * for(<> ; <>; <>) {}
+ * for(<> in <> ) {}
+ * while(<>) { }
+ * do { } while(<>)
+ * @return logical OR of END_* flags
+ */
+ private int endCheckLoop()
+ {
+ Node n;
+ int rv = END_UNREACHED;
+
+ // To find the loop body, we look at the second to last node of the
+ // loop node, which should be the predicate that the loop should
+ // satisfy.
+ // The target of the predicate is the loop-body for all 4 kinds of
+ // loops.
+ for (n = first; n.next != last; n = n.next) {
+ /* skip */
+ }
+ if (n.type != Token.IFEQ)
+ return END_DROPS_OFF;
+
+ // The target's next is the loop body block
+ rv = ((Jump)n).target.next.endCheck();
+
+ // check to see if the loop condition is true
+ if (n.first.type == Token.TRUE)
+ rv &= ~END_DROPS_OFF;
+
+ // look for effect of breaks
+ rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
+
+ return rv;
+ }
+
+
+ /**
+ * A general block of code is examined statement by statement. If any
+ * statement (even compound ones) returns in all branches, then subsequent
+ * statements are not examined.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckBlock()
+ {
+ Node n;
+ int rv = END_DROPS_OFF;
+
+ // check each statment and if the statement can continue onto the next
+ // one, then check the next statement
+ for (n=first; ((rv & END_DROPS_OFF) != 0) && n != null; n = n.next)
+ {
+ rv &= ~END_DROPS_OFF;
+ rv |= n.endCheck();
+ }
+ return rv;
+ }
+
+ /**
+ * A labelled statement implies that there maybe a break to the label. The
+ * function processes the labelled statement and then checks the
+ * CONTROL_BLOCK_PROP property to see if there is ever a break to the
+ * particular label.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckLabel()
+ {
+ int rv = END_UNREACHED;
+
+ rv = next.endCheck();
+ rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);
+
+ return rv;
+ }
+
+ /**
+ * When a break is encountered annotate the statement being broken
+ * out of by setting its CONTROL_BLOCK_PROP property.
+ * @return logical OR of END_* flags
+ */
+ private int endCheckBreak()
+ {
+ Node n = ((Jump) this).jumpNode;
+ n.putIntProp(CONTROL_BLOCK_PROP, END_DROPS_OFF);
+ return END_UNREACHED;
+ }
+
+ /**
+ * endCheck() examines the body of a function, doing a basic reachability
+ * analysis and returns a combination of flags END_* flags that indicate
+ * how the function execution can terminate. These constitute only the
+ * pessimistic set of termination conditions. It is possible that at
+ * runtime certain code paths will never be actually taken. Hence this
+ * analysis will flag errors in cases where there may not be errors.
+ * @return logical OR of END_* flags
+ */
+ private int endCheck()
+ {
+ switch(type)
+ {
+ case Token.BREAK:
+ return endCheckBreak();
+
+ case Token.EXPR_VOID:
+ if (this.first != null)
+ return first.endCheck();
+ return END_DROPS_OFF;
+
+ case Token.YIELD:
+ return END_YIELDS;
+
+ case Token.CONTINUE:
+ case Token.THROW:
+ return END_UNREACHED;
+
+ case Token.RETURN:
+ if (this.first != null)
+ return END_RETURNS_VALUE;
+ else
+ return END_RETURNS;
+
+ case Token.TARGET:
+ if (next != null)
+ return next.endCheck();
+ else
+ return END_DROPS_OFF;
+
+ case Token.LOOP:
+ return endCheckLoop();
+
+ case Token.LOCAL_BLOCK:
+ case Token.BLOCK:
+ // there are several special kinds of blocks
+ if (first == null)
+ return END_DROPS_OFF;
+
+ switch(first.type) {
+ case Token.LABEL:
+ return first.endCheckLabel();
+
+ case Token.IFNE:
+ return first.endCheckIf();
+
+ case Token.SWITCH:
+ return first.endCheckSwitch();
+
+ case Token.TRY:
+ return first.endCheckTry();
+
+ default:
+ return endCheckBlock();
+ }
+
+ default:
+ return END_DROPS_OFF;
+ }
+ }
+
+ public boolean hasSideEffects()
+ {
+ switch (type) {
+ case Token.EXPR_VOID:
+ case Token.COMMA:
+ if (last != null)
+ return last.hasSideEffects();
+ else
+ return true;
+
+ case Token.HOOK:
+ if (first == null ||
+ first.next == null ||
+ first.next.next == null)
+ Kit.codeBug();
+ return first.next.hasSideEffects() &&
+ first.next.next.hasSideEffects();
+
+ case Token.ERROR: // Avoid cascaded error messages
+ case Token.EXPR_RESULT:
+ case Token.ASSIGN:
+ case Token.ASSIGN_ADD:
+ case Token.ASSIGN_SUB:
+ case Token.ASSIGN_MUL:
+ case Token.ASSIGN_DIV:
+ case Token.ASSIGN_MOD:
+ case Token.ASSIGN_BITOR:
+ case Token.ASSIGN_BITXOR:
+ case Token.ASSIGN_BITAND:
+ case Token.ASSIGN_LSH:
+ case Token.ASSIGN_RSH:
+ case Token.ASSIGN_URSH:
+ case Token.ENTERWITH:
+ case Token.LEAVEWITH:
+ case Token.RETURN:
+ case Token.GOTO:
+ case Token.IFEQ:
+ case Token.IFNE:
+ case Token.NEW:
+ case Token.DELPROP:
+ case Token.SETNAME:
+ case Token.SETPROP:
+ case Token.SETELEM:
+ case Token.CALL:
+ case Token.THROW:
+ case Token.RETHROW:
+ case Token.SETVAR:
+ case Token.CATCH_SCOPE:
+ case Token.RETURN_RESULT:
+ case Token.SET_REF:
+ case Token.DEL_REF:
+ case Token.REF_CALL:
+ case Token.TRY:
+ case Token.SEMI:
+ case Token.INC:
+ case Token.DEC:
+ case Token.EXPORT:
+ case Token.IMPORT:
+ case Token.IF:
+ case Token.ELSE:
+ case Token.SWITCH:
+ case Token.WHILE:
+ case Token.DO:
+ case Token.FOR:
+ case Token.BREAK:
+ case Token.CONTINUE:
+ case Token.VAR:
+ case Token.CONST:
+ case Token.LET:
+ case Token.LETEXPR:
+ case Token.WITH:
+ case Token.WITHEXPR:
+ case Token.CATCH:
+ case Token.FINALLY:
+ case Token.BLOCK:
+ case Token.LABEL:
+ case Token.TARGET:
+ case Token.LOOP:
+ case Token.JSR:
+ case Token.SETPROP_OP:
+ case Token.SETELEM_OP:
+ case Token.LOCAL_BLOCK:
+ case Token.SET_REF_OP:
+ case Token.YIELD:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ public String toString()
+ {
+ if (Token.printTrees) {
+ StringBuffer sb = new StringBuffer();
+ toString(new ObjToIntMap(), sb);
+ return sb.toString();
+ }
+ return String.valueOf(type);
+ }
+
+ private void toString(ObjToIntMap printIds, StringBuffer sb)
+ {
+ if (Token.printTrees) {
+ sb.append(Token.name(type));
+ if (this instanceof StringNode) {
+ sb.append(' ');
+ sb.append(getString());
+ Scope scope = getScope();
+ if (scope != null) {
+ sb.append("[scope: ");
+ appendPrintId(scope, printIds, sb);
+ sb.append("]");
+ }
+ } else if (this instanceof Node.Scope) {
+ if (this instanceof ScriptOrFnNode) {
+ ScriptOrFnNode sof = (ScriptOrFnNode)this;
+ if (this instanceof FunctionNode) {
+ FunctionNode fn = (FunctionNode)this;
+ sb.append(' ');
+ sb.append(fn.getFunctionName());
+ }
+ sb.append(" [source name: ");
+ sb.append(sof.getSourceName());
+ sb.append("] [encoded source length: ");
+ sb.append(sof.getEncodedSourceEnd()
+ - sof.getEncodedSourceStart());
+ sb.append("] [base line: ");
+ sb.append(sof.getBaseLineno());
+ sb.append("] [end line: ");
+ sb.append(sof.getEndLineno());
+ sb.append(']');
+ }
+ if (((Node.Scope)this).symbolTable != null) {
+ sb.append(" [scope ");
+ appendPrintId(this, printIds, sb);
+ sb.append(": ");
+ Iterator iter = ((Node.Scope) this).symbolTable.keySet()
+ .iterator();
+ while (iter.hasNext()) {
+ sb.append(iter.next());
+ sb.append(" ");
+ }
+ sb.append("]");
+ }
+ } else if (this instanceof Jump) {
+ Jump jump = (Jump)this;
+ if (type == Token.BREAK || type == Token.CONTINUE) {
+ sb.append(" [label: ");
+ appendPrintId(jump.getJumpStatement(), printIds, sb);
+ sb.append(']');
+ } else if (type == Token.TRY) {
+ Node catchNode = jump.target;
+ Node finallyTarget = jump.getFinally();
+ if (catchNode != null) {
+ sb.append(" [catch: ");
+ appendPrintId(catchNode, printIds, sb);
+ sb.append(']');
+ }
+ if (finallyTarget != null) {
+ sb.append(" [finally: ");
+ appendPrintId(finallyTarget, printIds, sb);
+ sb.append(']');
+ }
+ } else if (type == Token.LABEL || type == Token.LOOP
+ || type == Token.SWITCH)
+ {
+ sb.append(" [break: ");
+ appendPrintId(jump.target, printIds, sb);
+ sb.append(']');
+ if (type == Token.LOOP) {
+ sb.append(" [continue: ");
+ appendPrintId(jump.getContinue(), printIds, sb);
+ sb.append(']');
+ }
+ } else {
+ sb.append(" [target: ");
+ appendPrintId(jump.target, printIds, sb);
+ sb.append(']');
+ }
+ } else if (type == Token.NUMBER) {
+ sb.append(' ');
+ sb.append(getDouble());
+ } else if (type == Token.TARGET) {
+ sb.append(' ');
+ appendPrintId(this, printIds, sb);
+ }
+ if (lineno != -1) {
+ sb.append(' ');
+ sb.append(lineno);
+ }
+
+ for (PropListItem x = propListHead; x != null; x = x.next) {
+ int type = x.type;
+ sb.append(" [");
+ sb.append(propToString(type));
+ sb.append(": ");
+ String value;
+ switch (type) {
+ case TARGETBLOCK_PROP : // can't add this as it recurses
+ value = "target block property";
+ break;
+ case LOCAL_BLOCK_PROP : // can't add this as it is dull
+ value = "last local block";
+ break;
+ case ISNUMBER_PROP:
+ switch (x.intValue) {
+ case BOTH:
+ value = "both";
+ break;
+ case RIGHT:
+ value = "right";
+ break;
+ case LEFT:
+ value = "left";
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ break;
+ case SPECIALCALL_PROP:
+ switch (x.intValue) {
+ case SPECIALCALL_EVAL:
+ value = "eval";
+ break;
+ case SPECIALCALL_WITH:
+ value = "with";
+ break;
+ default:
+ // NON_SPECIALCALL should not be stored
+ throw Kit.codeBug();
+ }
+ break;
+ case OBJECT_IDS_PROP: {
+ Object[] a = (Object[]) x.objectValue;
+ value = "[";
+ for (int i=0; i < a.length; i++) {
+ value += a[i].toString();
+ if (i+1 < a.length)
+ value += ", ";
+ }
+ value += "]";
+ break;
+ }
+ default :
+ Object obj = x.objectValue;
+ if (obj != null) {
+ value = obj.toString();
+ } else {
+ value = String.valueOf(x.intValue);
+ }
+ break;
+ }
+ sb.append(value);
+ sb.append(']');
+ }
+ }
+ }
+
+ public String toStringTree(ScriptOrFnNode treeTop) {
+ if (Token.printTrees) {
+ StringBuffer sb = new StringBuffer();
+ toStringTreeHelper(treeTop, this, null, 0, sb);
+ return sb.toString();
+ }
+ return null;
+ }
+
+ private static void toStringTreeHelper(ScriptOrFnNode treeTop, Node n,
+ ObjToIntMap printIds,
+ int level, StringBuffer sb)
+ {
+ if (Token.printTrees) {
+ if (printIds == null) {
+ printIds = new ObjToIntMap();
+ generatePrintIds(treeTop, printIds);
+ }
+ for (int i = 0; i != level; ++i) {
+ sb.append(" ");
+ }
+ n.toString(printIds, sb);
+ sb.append('\n');
+ for (Node cursor = n.getFirstChild(); cursor != null;
+ cursor = cursor.getNext())
+ {
+ if (cursor.getType() == Token.FUNCTION) {
+ int fnIndex = cursor.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = treeTop.getFunctionNode(fnIndex);
+ toStringTreeHelper(fn, fn, null, level + 1, sb);
+ } else {
+ toStringTreeHelper(treeTop, cursor, printIds, level + 1, sb);
+ }
+ }
+ }
+ }
+
+ private static void generatePrintIds(Node n, ObjToIntMap map)
+ {
+ if (Token.printTrees) {
+ map.put(n, map.size());
+ for (Node cursor = n.getFirstChild(); cursor != null;
+ cursor = cursor.getNext())
+ {
+ generatePrintIds(cursor, map);
+ }
+ }
+ }
+
+ private static void appendPrintId(Node n, ObjToIntMap printIds,
+ StringBuffer sb)
+ {
+ if (Token.printTrees) {
+ if (n != null) {
+ int id = printIds.get(n, -1);
+ sb.append('#');
+ if (id != -1) {
+ sb.append(id + 1);
+ } else {
+ sb.append("<not_available>");
+ }
+ }
+ }
+ }
+
+ int type; // type of the node; Token.NAME for example
+ Node next; // next sibling
+ private Node first; // first element of a linked list of children
+ private Node last; // last element of a linked list of children
+ protected int lineno = -1;
+
+ /*APPJET*/public int statementEndLineNum = -1;
+
+ /**
+ * Linked list of properties. Since vast majority of nodes would have
+ * no more then 2 properties, linked list saves memory and provides
+ * fast lookup. If this does not holds, propListHead can be replaced
+ * by UintMap.
+ */
+ private PropListItem propListHead;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java
new file mode 100644
index 0000000..201c6f2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/NodeTransformer.java
@@ -0,0 +1,565 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Bob Jervis
+ * Roger Lawrence
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class transforms a tree to a lower-level representation for codegen.
+ *
+ * @see Node
+ * @author Norris Boyd
+ */
+
+public class NodeTransformer
+{
+
+ public NodeTransformer()
+ {
+ }
+
+ public final void transform(ScriptOrFnNode tree)
+ {
+ transformCompilationUnit(tree);
+ for (int i = 0; i != tree.getFunctionCount(); ++i) {
+ FunctionNode fn = tree.getFunctionNode(i);
+ transform(fn);
+ }
+ }
+
+ private void transformCompilationUnit(ScriptOrFnNode tree)
+ {
+ loops = new ObjArray();
+ loopEnds = new ObjArray();
+
+ // to save against upchecks if no finally blocks are used.
+ hasFinally = false;
+
+ // Flatten all only if we are not using scope objects for block scope
+ boolean createScopeObjects = tree.getType() != Token.FUNCTION ||
+ ((FunctionNode)tree).requiresActivation();
+ tree.flattenSymbolTable(!createScopeObjects);
+
+ //uncomment to print tree before transformation
+ //if (Token.printTrees) System.out.println(tree.toStringTree(tree));
+ transformCompilationUnit_r(tree, tree, tree, createScopeObjects);
+ }
+
+ private void transformCompilationUnit_r(final ScriptOrFnNode tree,
+ final Node parent,
+ Node.Scope scope,
+ boolean createScopeObjects)
+ {
+ Node node = null;
+ siblingLoop:
+ for (;;) {
+ Node previous = null;
+ if (node == null) {
+ node = parent.getFirstChild();
+ } else {
+ previous = node;
+ node = node.getNext();
+ }
+ if (node == null) {
+ break;
+ }
+
+ int type = node.getType();
+ if (createScopeObjects &&
+ (type == Token.BLOCK || type == Token.LOOP ||
+ type == Token.ARRAYCOMP) &&
+ (node instanceof Node.Scope))
+ {
+ Node.Scope newScope = (Node.Scope) node;
+ if (newScope.symbolTable != null) {
+ // transform to let statement so we get a with statement
+ // created to contain scoped let variables
+ Node let = new Node(type == Token.ARRAYCOMP ? Token.LETEXPR
+ : Token.LET);
+ Node innerLet = new Node(Token.LET);
+ let.addChildToBack(innerLet);
+ for (String name: newScope.symbolTable.keySet()) {
+ innerLet.addChildToBack(Node.newString(Token.NAME, name));
+ }
+ newScope.symbolTable = null; // so we don't transform again
+ Node oldNode = node;
+ node = replaceCurrent(parent, previous, node, let);
+ type = node.getType();
+ let.addChildToBack(oldNode);
+ }
+ }
+
+ switch (type) {
+
+ case Token.LABEL:
+ case Token.SWITCH:
+ case Token.LOOP:
+ loops.push(node);
+ loopEnds.push(((Node.Jump)node).target);
+ break;
+
+ case Token.WITH:
+ {
+ loops.push(node);
+ Node leave = node.getNext();
+ if (leave.getType() != Token.LEAVEWITH) {
+ Kit.codeBug();
+ }
+ loopEnds.push(leave);
+ break;
+ }
+
+ case Token.TRY:
+ {
+ Node.Jump jump = (Node.Jump)node;
+ Node finallytarget = jump.getFinally();
+ if (finallytarget != null) {
+ hasFinally = true;
+ loops.push(node);
+ loopEnds.push(finallytarget);
+ }
+ break;
+ }
+
+ case Token.TARGET:
+ case Token.LEAVEWITH:
+ if (!loopEnds.isEmpty() && loopEnds.peek() == node) {
+ loopEnds.pop();
+ loops.pop();
+ }
+ break;
+
+ case Token.YIELD:
+ ((FunctionNode)tree).addResumptionPoint(node);
+ break;
+
+ case Token.RETURN:
+ {
+ boolean isGenerator = tree.getType() == Token.FUNCTION
+ && ((FunctionNode)tree).isGenerator();
+ if (isGenerator) {
+ node.putIntProp(Node.GENERATOR_END_PROP, 1);
+ }
+ /* If we didn't support try/finally, it wouldn't be
+ * necessary to put LEAVEWITH nodes here... but as
+ * we do need a series of JSR FINALLY nodes before
+ * each RETURN, we need to ensure that each finally
+ * block gets the correct scope... which could mean
+ * that some LEAVEWITH nodes are necessary.
+ */
+ if (!hasFinally)
+ break; // skip the whole mess.
+ Node unwindBlock = null;
+ for (int i=loops.size()-1; i >= 0; i--) {
+ Node n = (Node) loops.get(i);
+ int elemtype = n.getType();
+ if (elemtype == Token.TRY || elemtype == Token.WITH) {
+ Node unwind;
+ if (elemtype == Token.TRY) {
+ Node.Jump jsrnode = new Node.Jump(Token.JSR);
+ Node jsrtarget = ((Node.Jump)n).getFinally();
+ jsrnode.target = jsrtarget;
+ unwind = jsrnode;
+ } else {
+ unwind = new Node(Token.LEAVEWITH);
+ }
+ if (unwindBlock == null) {
+ unwindBlock = new Node(Token.BLOCK,
+ node.getLineno());
+ }
+ unwindBlock.addChildToBack(unwind);
+ }
+ }
+ if (unwindBlock != null) {
+ Node returnNode = node;
+ Node returnExpr = returnNode.getFirstChild();
+ node = replaceCurrent(parent, previous, node, unwindBlock);
+ if (returnExpr == null || isGenerator) {
+ unwindBlock.addChildToBack(returnNode);
+ } else {
+ Node store = new Node(Token.EXPR_RESULT, returnExpr);
+ unwindBlock.addChildToFront(store);
+ returnNode = new Node(Token.RETURN_RESULT);
+ unwindBlock.addChildToBack(returnNode);
+ // transform return expression
+ transformCompilationUnit_r(tree, store, scope,
+ createScopeObjects);
+ }
+ // skip transformCompilationUnit_r to avoid infinite loop
+ continue siblingLoop;
+ }
+ break;
+ }
+
+ case Token.BREAK:
+ case Token.CONTINUE:
+ {
+ Node.Jump jump = (Node.Jump)node;
+ Node.Jump jumpStatement = jump.getJumpStatement();
+ if (jumpStatement == null) Kit.codeBug();
+
+ for (int i = loops.size(); ;) {
+ if (i == 0) {
+ // Parser/IRFactory ensure that break/continue
+ // always has a jump statement associated with it
+ // which should be found
+ throw Kit.codeBug();
+ }
+ --i;
+ Node n = (Node) loops.get(i);
+ if (n == jumpStatement) {
+ break;
+ }
+
+ int elemtype = n.getType();
+ if (elemtype == Token.WITH) {
+ Node leave = new Node(Token.LEAVEWITH);
+ previous = addBeforeCurrent(parent, previous, node,
+ leave);
+ } else if (elemtype == Token.TRY) {
+ Node.Jump tryNode = (Node.Jump)n;
+ Node.Jump jsrFinally = new Node.Jump(Token.JSR);
+ jsrFinally.target = tryNode.getFinally();
+ previous = addBeforeCurrent(parent, previous, node,
+ jsrFinally);
+ }
+ }
+
+ if (type == Token.BREAK) {
+ jump.target = jumpStatement.target;
+ } else {
+ jump.target = jumpStatement.getContinue();
+ }
+ jump.setType(Token.GOTO);
+
+ break;
+ }
+
+ case Token.CALL:
+ visitCall(node, tree);
+ break;
+
+ case Token.NEW:
+ visitNew(node, tree);
+ break;
+
+ case Token.LETEXPR:
+ case Token.LET: {
+ Node child = node.getFirstChild();
+ if (child.getType() == Token.LET) {
+ // We have a let statement or expression rather than a
+ // let declaration
+ boolean createWith = tree.getType() != Token.FUNCTION
+ || ((FunctionNode)tree).requiresActivation();
+ node = visitLet(createWith, parent, previous, node);
+ break;
+ } else {
+ // fall through to process let declaration...
+ }
+ }
+ /* fall through */
+ case Token.CONST:
+ case Token.VAR:
+ {
+ Node result = new Node(Token.BLOCK);
+ for (Node cursor = node.getFirstChild(); cursor != null;) {
+ // Move cursor to next before createAssignment gets chance
+ // to change n.next
+ Node n = cursor;
+ cursor = cursor.getNext();
+ if (n.getType() == Token.NAME) {
+ if (!n.hasChildren())
+ continue;
+ Node init = n.getFirstChild();
+ n.removeChild(init);
+ n.setType(Token.BINDNAME);
+ n = new Node(type == Token.CONST ?
+ Token.SETCONST :
+ Token.SETNAME,
+ n, init);
+ } else {
+ // May be a destructuring assignment already transformed
+ // to a LETEXPR
+ if (n.getType() != Token.LETEXPR)
+ throw Kit.codeBug();
+ }
+ Node pop = new Node(Token.EXPR_VOID, n, node.getLineno());
+ result.addChildToBack(pop);
+ }
+ node = replaceCurrent(parent, previous, node, result);
+ break;
+ }
+
+ case Token.TYPEOFNAME: {
+ Node.Scope defining = scope.getDefiningScope(node.getString());
+ if (defining != null) {
+ node.setScope(defining);
+ }
+ }
+ break;
+
+ case Token.TYPEOF:
+ case Token.IFNE: {
+ /* We want to suppress warnings for undefined property o.p
+ * for the following constructs: typeof o.p, if (o.p),
+ * if (!o.p), if (o.p == undefined), if (undefined == o.p)
+ */
+ Node child = node.getFirstChild();
+ if (type == Token.IFNE) {
+ while (child.getType() == Token.NOT) {
+ child = child.getFirstChild();
+ }
+ if (child.getType() == Token.EQ ||
+ child.getType() == Token.NE)
+ {
+ Node first = child.getFirstChild();
+ Node last = child.getLastChild();
+ if (first.getType() == Token.NAME &&
+ first.getString().equals("undefined"))
+ child = last;
+ else if (last.getType() == Token.NAME &&
+ last.getString().equals("undefined"))
+ child = first;
+ }
+ }
+ if (child.getType() == Token.GETPROP)
+ child.setType(Token.GETPROPNOWARN);
+ break;
+ }
+
+ case Token.NAME:
+ case Token.SETNAME:
+ case Token.SETCONST:
+ case Token.DELPROP:
+ {
+ // Turn name to var for faster access if possible
+ if (createScopeObjects) {
+ break;
+ }
+ Node nameSource;
+ if (type == Token.NAME) {
+ nameSource = node;
+ } else {
+ nameSource = node.getFirstChild();
+ if (nameSource.getType() != Token.BINDNAME) {
+ if (type == Token.DELPROP) {
+ break;
+ }
+ throw Kit.codeBug();
+ }
+ }
+ if (nameSource.getScope() != null) {
+ break; // already have a scope set
+ }
+ String name = nameSource.getString();
+ Node.Scope defining = scope.getDefiningScope(name);
+ if (defining != null) {
+ nameSource.setScope(defining);
+ if (type == Token.NAME) {
+ node.setType(Token.GETVAR);
+ } else if (type == Token.SETNAME) {
+ node.setType(Token.SETVAR);
+ nameSource.setType(Token.STRING);
+ } else if (type == Token.SETCONST) {
+ node.setType(Token.SETCONSTVAR);
+ nameSource.setType(Token.STRING);
+ } else if (type == Token.DELPROP) {
+ // Local variables are by definition permanent
+ Node n = new Node(Token.FALSE);
+ node = replaceCurrent(parent, previous, node, n);
+ } else {
+ throw Kit.codeBug();
+ }
+ }
+ break;
+ }
+ }
+
+ transformCompilationUnit_r(tree, node,
+ node instanceof Node.Scope ? (Node.Scope)node : scope,
+ createScopeObjects);
+ }
+ }
+
+ protected void visitNew(Node node, ScriptOrFnNode tree) {
+ }
+
+ protected void visitCall(Node node, ScriptOrFnNode tree) {
+ }
+
+ protected Node visitLet(boolean createWith, Node parent, Node previous,
+ Node scopeNode)
+ {
+ Node vars = scopeNode.getFirstChild();
+ Node body = vars.getNext();
+ scopeNode.removeChild(vars);
+ scopeNode.removeChild(body);
+ boolean isExpression = scopeNode.getType() == Token.LETEXPR;
+ Node result;
+ Node newVars;
+ if (createWith) {
+ result = new Node(isExpression ? Token.WITHEXPR : Token.BLOCK);
+ result = replaceCurrent(parent, previous, scopeNode, result);
+ ArrayList<Object> list = new ArrayList<Object>();
+ Node objectLiteral = new Node(Token.OBJECTLIT);
+ for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {
+ Node current = v;
+ if (current.getType() == Token.LETEXPR) {
+ // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}
+ List<?> destructuringNames = (List<?>)
+ current.getProp(Node.DESTRUCTURING_NAMES);
+ Node c = current.getFirstChild();
+ if (c.getType() != Token.LET) throw Kit.codeBug();
+ // Add initialization code to front of body
+ if (isExpression) {
+ body = new Node(Token.COMMA, c.getNext(), body);
+ } else {
+ body = new Node(Token.BLOCK,
+ new Node(Token.EXPR_VOID, c.getNext()),
+ body);
+ }
+ // Update "list" and "objectLiteral" for the variables
+ // defined in the destructuring assignment
+ if (destructuringNames != null) {
+ list.addAll(destructuringNames);
+ for (int i=0; i < destructuringNames.size(); i++) {
+ objectLiteral.addChildToBack(
+ new Node(Token.VOID, Node.newNumber(0.0)));
+ }
+ }
+ current = c.getFirstChild(); // should be a NAME, checked below
+ }
+ if (current.getType() != Token.NAME) throw Kit.codeBug();
+ list.add(ScriptRuntime.getIndexObject(current.getString()));
+ Node init = current.getFirstChild();
+ if (init == null) {
+ init = new Node(Token.VOID, Node.newNumber(0.0));
+ }
+ objectLiteral.addChildToBack(init);
+ }
+ objectLiteral.putProp(Node.OBJECT_IDS_PROP, list.toArray());
+ newVars = new Node(Token.ENTERWITH, objectLiteral);
+ result.addChildToBack(newVars);
+ result.addChildToBack(new Node(Token.WITH, body));
+ result.addChildToBack(new Node(Token.LEAVEWITH));
+ } else {
+ result = new Node(isExpression ? Token.COMMA : Token.BLOCK);
+ result = replaceCurrent(parent, previous, scopeNode, result);
+ newVars = new Node(Token.COMMA);
+ for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {
+ Node current = v;
+ if (current.getType() == Token.LETEXPR) {
+ // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}
+ Node c = current.getFirstChild();
+ if (c.getType() != Token.LET) throw Kit.codeBug();
+ // Add initialization code to front of body
+ if (isExpression) {
+ body = new Node(Token.COMMA, c.getNext(), body);
+ } else {
+ body = new Node(Token.BLOCK,
+ new Node(Token.EXPR_VOID, c.getNext()),
+ body);
+ }
+ // We're removing the LETEXPR, so move the symbols
+ Node.Scope.joinScopes((Node.Scope)current,
+ (Node.Scope)scopeNode);
+ current = c.getFirstChild(); // should be a NAME, checked below
+ }
+ if (current.getType() != Token.NAME) throw Kit.codeBug();
+ Node stringNode = Node.newString(current.getString());
+ stringNode.setScope((Node.Scope)scopeNode);
+ Node init = current.getFirstChild();
+ if (init == null) {
+ init = new Node(Token.VOID, Node.newNumber(0.0));
+ }
+ newVars.addChildToBack(new Node(Token.SETVAR, stringNode, init));
+ }
+ if (isExpression) {
+ result.addChildToBack(newVars);
+ scopeNode.setType(Token.COMMA);
+ result.addChildToBack(scopeNode);
+ scopeNode.addChildToBack(body);
+ } else {
+ result.addChildToBack(new Node(Token.EXPR_VOID, newVars));
+ scopeNode.setType(Token.BLOCK);
+ result.addChildToBack(scopeNode);
+ scopeNode.addChildrenToBack(body);
+ }
+ }
+ return result;
+ }
+
+ private static Node addBeforeCurrent(Node parent, Node previous,
+ Node current, Node toAdd)
+ {
+ if (previous == null) {
+ if (!(current == parent.getFirstChild())) Kit.codeBug();
+ parent.addChildToFront(toAdd);
+ } else {
+ if (!(current == previous.getNext())) Kit.codeBug();
+ parent.addChildAfter(toAdd, previous);
+ }
+ return toAdd;
+ }
+
+ private static Node replaceCurrent(Node parent, Node previous,
+ Node current, Node replacement)
+ {
+ if (previous == null) {
+ if (!(current == parent.getFirstChild())) Kit.codeBug();
+ parent.replaceChild(current, replacement);
+ } else if (previous.next == current) {
+ // Check cachedPrev.next == current is necessary due to possible
+ // tree mutations
+ parent.replaceChildAfter(previous, replacement);
+ } else {
+ parent.replaceChild(current, replacement);
+ }
+ return replacement;
+ }
+
+ private ObjArray loops;
+ private ObjArray loopEnds;
+ private boolean hasFinally;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java
new file mode 100644
index 0000000..a9636a3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjArray.java
@@ -0,0 +1,388 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+Implementation of resizable array with focus on minimizing memory usage by storing few initial array elements in object fields. Can also be used as a stack.
+*/
+
+public class ObjArray implements Serializable
+{
+ static final long serialVersionUID = 4174889037736658296L;
+
+ public ObjArray() { }
+
+ public final boolean isSealed()
+ {
+ return sealed;
+ }
+
+ public final void seal()
+ {
+ sealed = true;
+ }
+
+ public final boolean isEmpty()
+ {
+ return size == 0;
+ }
+
+ public final int size()
+ {
+ return size;
+ }
+
+ public final void setSize(int newSize)
+ {
+ if (newSize < 0) throw new IllegalArgumentException();
+ if (sealed) throw onSeledMutation();
+ int N = size;
+ if (newSize < N) {
+ for (int i = newSize; i != N; ++i) {
+ setImpl(i, null);
+ }
+ } else if (newSize > N) {
+ if (newSize > FIELDS_STORE_SIZE) {
+ ensureCapacity(newSize);
+ }
+ }
+ size = newSize;
+ }
+
+ public final Object get(int index)
+ {
+ if (!(0 <= index && index < size)) throw onInvalidIndex(index, size);
+ return getImpl(index);
+ }
+
+ public final void set(int index, Object value)
+ {
+ if (!(0 <= index && index < size)) throw onInvalidIndex(index, size);
+ if (sealed) throw onSeledMutation();
+ setImpl(index, value);
+ }
+
+ private Object getImpl(int index)
+ {
+ switch (index) {
+ case 0: return f0;
+ case 1: return f1;
+ case 2: return f2;
+ case 3: return f3;
+ case 4: return f4;
+ }
+ return data[index - FIELDS_STORE_SIZE];
+ }
+
+ private void setImpl(int index, Object value)
+ {
+ switch (index) {
+ case 0: f0 = value; break;
+ case 1: f1 = value; break;
+ case 2: f2 = value; break;
+ case 3: f3 = value; break;
+ case 4: f4 = value; break;
+ default: data[index - FIELDS_STORE_SIZE] = value;
+ }
+
+ }
+
+ public int indexOf(Object obj)
+ {
+ int N = size;
+ for (int i = 0; i != N; ++i) {
+ Object current = getImpl(i);
+ if (current == obj || (current != null && current.equals(obj))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int lastIndexOf(Object obj)
+ {
+ for (int i = size; i != 0;) {
+ --i;
+ Object current = getImpl(i);
+ if (current == obj || (current != null && current.equals(obj))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public final Object peek()
+ {
+ int N = size;
+ if (N == 0) throw onEmptyStackTopRead();
+ return getImpl(N - 1);
+ }
+
+ public final Object pop()
+ {
+ if (sealed) throw onSeledMutation();
+ int N = size;
+ --N;
+ Object top;
+ switch (N) {
+ case -1: throw onEmptyStackTopRead();
+ case 0: top = f0; f0 = null; break;
+ case 1: top = f1; f1 = null; break;
+ case 2: top = f2; f2 = null; break;
+ case 3: top = f3; f3 = null; break;
+ case 4: top = f4; f4 = null; break;
+ default:
+ top = data[N - FIELDS_STORE_SIZE];
+ data[N - FIELDS_STORE_SIZE] = null;
+ }
+ size = N;
+ return top;
+ }
+
+ public final void push(Object value)
+ {
+ add(value);
+ }
+
+ public final void add(Object value)
+ {
+ if (sealed) throw onSeledMutation();
+ int N = size;
+ if (N >= FIELDS_STORE_SIZE) {
+ ensureCapacity(N + 1);
+ }
+ size = N + 1;
+ setImpl(N, value);
+ }
+
+ public final void add(int index, Object value)
+ {
+ int N = size;
+ if (!(0 <= index && index <= N)) throw onInvalidIndex(index, N + 1);
+ if (sealed) throw onSeledMutation();
+ Object tmp;
+ switch (index) {
+ case 0:
+ if (N == 0) { f0 = value; break; }
+ tmp = f0; f0 = value; value = tmp;
+ case 1:
+ if (N == 1) { f1 = value; break; }
+ tmp = f1; f1 = value; value = tmp;
+ case 2:
+ if (N == 2) { f2 = value; break; }
+ tmp = f2; f2 = value; value = tmp;
+ case 3:
+ if (N == 3) { f3 = value; break; }
+ tmp = f3; f3 = value; value = tmp;
+ case 4:
+ if (N == 4) { f4 = value; break; }
+ tmp = f4; f4 = value; value = tmp;
+
+ index = FIELDS_STORE_SIZE;
+ default:
+ ensureCapacity(N + 1);
+ if (index != N) {
+ System.arraycopy(data, index - FIELDS_STORE_SIZE,
+ data, index - FIELDS_STORE_SIZE + 1,
+ N - index);
+ }
+ data[index - FIELDS_STORE_SIZE] = value;
+ }
+ size = N + 1;
+ }
+
+ public final void remove(int index)
+ {
+ int N = size;
+ if (!(0 <= index && index < N)) throw onInvalidIndex(index, N);
+ if (sealed) throw onSeledMutation();
+ --N;
+ switch (index) {
+ case 0:
+ if (N == 0) { f0 = null; break; }
+ f0 = f1;
+ case 1:
+ if (N == 1) { f1 = null; break; }
+ f1 = f2;
+ case 2:
+ if (N == 2) { f2 = null; break; }
+ f2 = f3;
+ case 3:
+ if (N == 3) { f3 = null; break; }
+ f3 = f4;
+ case 4:
+ if (N == 4) { f4 = null; break; }
+ f4 = data[0];
+
+ index = FIELDS_STORE_SIZE;
+ default:
+ if (index != N) {
+ System.arraycopy(data, index - FIELDS_STORE_SIZE + 1,
+ data, index - FIELDS_STORE_SIZE,
+ N - index);
+ }
+ data[N - FIELDS_STORE_SIZE] = null;
+ }
+ size = N;
+ }
+
+ public final void clear()
+ {
+ if (sealed) throw onSeledMutation();
+ int N = size;
+ for (int i = 0; i != N; ++i) {
+ setImpl(i, null);
+ }
+ size = 0;
+ }
+
+ public final Object[] toArray()
+ {
+ Object[] array = new Object[size];
+ toArray(array, 0);
+ return array;
+ }
+
+ public final void toArray(Object[] array)
+ {
+ toArray(array, 0);
+ }
+
+ public final void toArray(Object[] array, int offset)
+ {
+ int N = size;
+ switch (N) {
+ default:
+ System.arraycopy(data, 0, array, offset + FIELDS_STORE_SIZE,
+ N - FIELDS_STORE_SIZE);
+ case 5: array[offset + 4] = f4;
+ case 4: array[offset + 3] = f3;
+ case 3: array[offset + 2] = f2;
+ case 2: array[offset + 1] = f1;
+ case 1: array[offset + 0] = f0;
+ case 0: break;
+ }
+ }
+
+ private void ensureCapacity(int minimalCapacity)
+ {
+ int required = minimalCapacity - FIELDS_STORE_SIZE;
+ if (required <= 0) throw new IllegalArgumentException();
+ if (data == null) {
+ int alloc = FIELDS_STORE_SIZE * 2;
+ if (alloc < required) {
+ alloc = required;
+ }
+ data = new Object[alloc];
+ } else {
+ int alloc = data.length;
+ if (alloc < required) {
+ if (alloc <= FIELDS_STORE_SIZE) {
+ alloc = FIELDS_STORE_SIZE * 2;
+ } else {
+ alloc *= 2;
+ }
+ if (alloc < required) {
+ alloc = required;
+ }
+ Object[] tmp = new Object[alloc];
+ if (size > FIELDS_STORE_SIZE) {
+ System.arraycopy(data, 0, tmp, 0,
+ size - FIELDS_STORE_SIZE);
+ }
+ data = tmp;
+ }
+ }
+ }
+
+ private static RuntimeException onInvalidIndex(int index, int upperBound)
+ {
+ // \u2209 is "NOT ELEMENT OF"
+ String msg = index+" \u2209 [0, "+upperBound+')';
+ throw new IndexOutOfBoundsException(msg);
+ }
+
+ private static RuntimeException onEmptyStackTopRead()
+ {
+ throw new RuntimeException("Empty stack");
+ }
+
+ private static RuntimeException onSeledMutation()
+ {
+ throw new IllegalStateException("Attempt to modify sealed array");
+ }
+
+ private void writeObject(ObjectOutputStream os) throws IOException
+ {
+ os.defaultWriteObject();
+ int N = size;
+ for (int i = 0; i != N; ++i) {
+ Object obj = getImpl(i);
+ os.writeObject(obj);
+ }
+ }
+
+ private void readObject(ObjectInputStream is)
+ throws IOException, ClassNotFoundException
+ {
+ is.defaultReadObject(); // It reads size
+ int N = size;
+ if (N > FIELDS_STORE_SIZE) {
+ data = new Object[N - FIELDS_STORE_SIZE];
+ }
+ for (int i = 0; i != N; ++i) {
+ Object obj = is.readObject();
+ setImpl(i, obj);
+ }
+ }
+
+// Number of data elements
+ private int size;
+
+ private boolean sealed;
+
+ private static final int FIELDS_STORE_SIZE = 5;
+ private transient Object f0, f1, f2, f3, f4;
+ private transient Object[] data;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java
new file mode 100644
index 0000000..4aa7d23
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ObjToIntMap.java
@@ -0,0 +1,697 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Map to associate objects to integers.
+ * The map does not synchronize any of its operation, so either use
+ * it from a single thread or do own synchronization or perform all mutation
+ * operations on one thread before passing the map to others
+ *
+ * @author Igor Bukanov
+ *
+ */
+
+public class ObjToIntMap implements Serializable
+{
+ static final long serialVersionUID = -1542220580748809402L;
+
+// Map implementation via hashtable,
+// follows "The Art of Computer Programming" by Donald E. Knuth
+
+// ObjToIntMap is a copy cat of ObjToIntMap with API adjusted to object keys
+
+ public static class Iterator {
+
+ Iterator(ObjToIntMap master) {
+ this.master = master;
+ }
+
+ final void init(Object[] keys, int[] values, int keyCount) {
+ this.keys = keys;
+ this.values = values;
+ this.cursor = -1;
+ this.remaining = keyCount;
+ }
+
+ public void start() {
+ master.initIterator(this);
+ next();
+ }
+
+ public boolean done() {
+ return remaining < 0;
+ }
+
+ public void next() {
+ if (remaining == -1) Kit.codeBug();
+ if (remaining == 0) {
+ remaining = -1;
+ cursor = -1;
+ }else {
+ for (++cursor; ; ++cursor) {
+ Object key = keys[cursor];
+ if (key != null && key != DELETED) {
+ --remaining;
+ break;
+ }
+ }
+ }
+ }
+
+ public Object getKey() {
+ Object key = keys[cursor];
+ if (key == UniqueTag.NULL_VALUE) { key = null; }
+ return key;
+ }
+
+ public int getValue() {
+ return values[cursor];
+ }
+
+ public void setValue(int value) {
+ values[cursor] = value;
+ }
+
+ ObjToIntMap master;
+ private int cursor;
+ private int remaining;
+ private Object[] keys;
+ private int[] values;
+ }
+
+ public ObjToIntMap() {
+ this(4);
+ }
+
+ public ObjToIntMap(int keyCountHint) {
+ if (keyCountHint < 0) Kit.codeBug();
+ // Table grow when number of stored keys >= 3/4 of max capacity
+ int minimalCapacity = keyCountHint * 4 / 3;
+ int i;
+ for (i = 2; (1 << i) < minimalCapacity; ++i) { }
+ power = i;
+ if (check && power < 2) Kit.codeBug();
+ }
+
+ public boolean isEmpty() {
+ return keyCount == 0;
+ }
+
+ public int size() {
+ return keyCount;
+ }
+
+ public boolean has(Object key) {
+ if (key == null) { key = UniqueTag.NULL_VALUE; }
+ return 0 <= findIndex(key);
+ }
+
+ /**
+ * Get integer value assigned with key.
+ * @return key integer value or defaultValue if key is absent
+ */
+ public int get(Object key, int defaultValue) {
+ if (key == null) { key = UniqueTag.NULL_VALUE; }
+ int index = findIndex(key);
+ if (0 <= index) {
+ return values[index];
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Get integer value assigned with key.
+ * @return key integer value
+ * @throws RuntimeException if key does not exist
+ */
+ public int getExisting(Object key) {
+ if (key == null) { key = UniqueTag.NULL_VALUE; }
+ int index = findIndex(key);
+ if (0 <= index) {
+ return values[index];
+ }
+ // Key must exist
+ Kit.codeBug();
+ return 0;
+ }
+
+ public void put(Object key, int value) {
+ if (key == null) { key = UniqueTag.NULL_VALUE; }
+ int index = ensureIndex(key);
+ values[index] = value;
+ }
+
+ /**
+ * If table already contains a key that equals to keyArg, return that key
+ * while setting its value to zero, otherwise add keyArg with 0 value to
+ * the table and return it.
+ */
+ public Object intern(Object keyArg) {
+ boolean nullKey = false;
+ if (keyArg == null) {
+ nullKey = true;
+ keyArg = UniqueTag.NULL_VALUE;
+ }
+ int index = ensureIndex(keyArg);
+ values[index] = 0;
+ return (nullKey) ? null : keys[index];
+ }
+
+ public void remove(Object key) {
+ if (key == null) { key = UniqueTag.NULL_VALUE; }
+ int index = findIndex(key);
+ if (0 <= index) {
+ keys[index] = DELETED;
+ --keyCount;
+ }
+ }
+
+ public void clear() {
+ int i = keys.length;
+ while (i != 0) {
+ keys[--i] = null;
+ }
+ keyCount = 0;
+ occupiedCount = 0;
+ }
+
+ public Iterator newIterator() {
+ return new Iterator(this);
+ }
+
+ // The sole purpose of the method is to avoid accessing private fields
+ // from the Iterator inner class to workaround JDK 1.1 compiler bug which
+ // generates code triggering VerifierError on recent JVMs
+ final void initIterator(Iterator i) {
+ i.init(keys, values, keyCount);
+ }
+
+ /** Return array of present keys */
+ public Object[] getKeys() {
+ Object[] array = new Object[keyCount];
+ getKeys(array, 0);
+ return array;
+ }
+
+ public void getKeys(Object[] array, int offset) {
+ int count = keyCount;
+ for (int i = 0; count != 0; ++i) {
+ Object key = keys[i];
+ if (key != null && key != DELETED) {
+ if (key == UniqueTag.NULL_VALUE) { key = null; }
+ array[offset] = key;
+ ++offset;
+ --count;
+ }
+ }
+ }
+
+ private static int tableLookupStep(int fraction, int mask, int power) {
+ int shift = 32 - 2 * power;
+ if (shift >= 0) {
+ return ((fraction >>> shift) & mask) | 1;
+ }
+ else {
+ return (fraction & (mask >>> -shift)) | 1;
+ }
+ }
+
+ private int findIndex(Object key) {
+ if (keys != null) {
+ int hash = key.hashCode();
+ int fraction = hash * A;
+ int index = fraction >>> (32 - power);
+ Object test = keys[index];
+ if (test != null) {
+ int N = 1 << power;
+ if (test == key
+ || (values[N + index] == hash && test.equals(key)))
+ {
+ return index;
+ }
+ // Search in table after first failed attempt
+ int mask = N - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int n = 0;
+ for (;;) {
+ if (check) {
+ if (n >= occupiedCount) Kit.codeBug();
+ ++n;
+ }
+ index = (index + step) & mask;
+ test = keys[index];
+ if (test == null) {
+ break;
+ }
+ if (test == key
+ || (values[N + index] == hash && test.equals(key)))
+ {
+ return index;
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+// Insert key that is not present to table without deleted entries
+// and enough free space
+ private int insertNewKey(Object key, int hash) {
+ if (check && occupiedCount != keyCount) Kit.codeBug();
+ if (check && keyCount == 1 << power) Kit.codeBug();
+ int fraction = hash * A;
+ int index = fraction >>> (32 - power);
+ int N = 1 << power;
+ if (keys[index] != null) {
+ int mask = N - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int firstIndex = index;
+ do {
+ if (check && keys[index] == DELETED) Kit.codeBug();
+ index = (index + step) & mask;
+ if (check && firstIndex == index) Kit.codeBug();
+ } while (keys[index] != null);
+ }
+ keys[index] = key;
+ values[N + index] = hash;
+ ++occupiedCount;
+ ++keyCount;
+
+ return index;
+ }
+
+ private void rehashTable() {
+ if (keys == null) {
+ if (check && keyCount != 0) Kit.codeBug();
+ if (check && occupiedCount != 0) Kit.codeBug();
+ int N = 1 << power;
+ keys = new Object[N];
+ values = new int[2 * N];
+ }
+ else {
+ // Check if removing deleted entries would free enough space
+ if (keyCount * 2 >= occupiedCount) {
+ // Need to grow: less then half of deleted entries
+ ++power;
+ }
+ int N = 1 << power;
+ Object[] oldKeys = keys;
+ int[] oldValues = values;
+ int oldN = oldKeys.length;
+ keys = new Object[N];
+ values = new int[2 * N];
+
+ int remaining = keyCount;
+ occupiedCount = keyCount = 0;
+ for (int i = 0; remaining != 0; ++i) {
+ Object key = oldKeys[i];
+ if (key != null && key != DELETED) {
+ int keyHash = oldValues[oldN + i];
+ int index = insertNewKey(key, keyHash);
+ values[index] = oldValues[i];
+ --remaining;
+ }
+ }
+ }
+ }
+
+// Ensure key index creating one if necessary
+ private int ensureIndex(Object key) {
+ int hash = key.hashCode();
+ int index = -1;
+ int firstDeleted = -1;
+ if (keys != null) {
+ int fraction = hash * A;
+ index = fraction >>> (32 - power);
+ Object test = keys[index];
+ if (test != null) {
+ int N = 1 << power;
+ if (test == key
+ || (values[N + index] == hash && test.equals(key)))
+ {
+ return index;
+ }
+ if (test == DELETED) {
+ firstDeleted = index;
+ }
+
+ // Search in table after first failed attempt
+ int mask = N - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int n = 0;
+ for (;;) {
+ if (check) {
+ if (n >= occupiedCount) Kit.codeBug();
+ ++n;
+ }
+ index = (index + step) & mask;
+ test = keys[index];
+ if (test == null) {
+ break;
+ }
+ if (test == key
+ || (values[N + index] == hash && test.equals(key)))
+ {
+ return index;
+ }
+ if (test == DELETED && firstDeleted < 0) {
+ firstDeleted = index;
+ }
+ }
+ }
+ }
+ // Inserting of new key
+ if (check && keys != null && keys[index] != null)
+ Kit.codeBug();
+ if (firstDeleted >= 0) {
+ index = firstDeleted;
+ }
+ else {
+ // Need to consume empty entry: check occupation level
+ if (keys == null || occupiedCount * 4 >= (1 << power) * 3) {
+ // Too litle unused entries: rehash
+ rehashTable();
+ return insertNewKey(key, hash);
+ }
+ ++occupiedCount;
+ }
+ keys[index] = key;
+ values[(1 << power) + index] = hash;
+ ++keyCount;
+ return index;
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ int count = keyCount;
+ for (int i = 0; count != 0; ++i) {
+ Object key = keys[i];
+ if (key != null && key != DELETED) {
+ --count;
+ out.writeObject(key);
+ out.writeInt(values[i]);
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ int writtenKeyCount = keyCount;
+ if (writtenKeyCount != 0) {
+ keyCount = 0;
+ int N = 1 << power;
+ keys = new Object[N];
+ values = new int[2 * N];
+ for (int i = 0; i != writtenKeyCount; ++i) {
+ Object key = in.readObject();
+ int hash = key.hashCode();
+ int index = insertNewKey(key, hash);
+ values[index] = in.readInt();
+ }
+ }
+ }
+
+// A == golden_ratio * (1 << 32) = ((sqrt(5) - 1) / 2) * (1 << 32)
+// See Knuth etc.
+ private static final int A = 0x9e3779b9;
+
+ private static final Object DELETED = new Object();
+
+// Structure of kyes and values arrays (N == 1 << power):
+// keys[0 <= i < N]: key value or null or DELETED mark
+// values[0 <= i < N]: value of key at keys[i]
+// values[N <= i < 2*N]: hash code of key at keys[i-N]
+
+ private transient Object[] keys;
+ private transient int[] values;
+
+ private int power;
+ private int keyCount;
+ private transient int occupiedCount; // == keyCount + deleted_count
+
+// If true, enables consitency checks
+ private static final boolean check = false;
+
+/* TEST START
+
+ public static void main(String[] args) {
+ if (!check) {
+ System.err.println("Set check to true and re-run");
+ throw new RuntimeException("Set check to true and re-run");
+ }
+
+ ObjToIntMap map;
+ map = new ObjToIntMap(0);
+ testHash(map, 3);
+ map = new ObjToIntMap(0);
+ testHash(map, 10 * 1000);
+ map = new ObjToIntMap();
+ testHash(map, 10 * 1000);
+ map = new ObjToIntMap(30 * 1000);
+ testHash(map, 10 * 100);
+ map.clear();
+ testHash(map, 4);
+ map = new ObjToIntMap(0);
+ testHash(map, 10 * 100);
+ }
+
+ private static void testHash(ObjToIntMap map, int N) {
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ check(-1 == map.get(key, -1));
+ map.put(key, i);
+ check(i == map.get(key, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ map.put(key, i);
+ check(i == map.get(key, -1));
+ }
+
+ check(map.size() == N);
+
+ System.out.print("."); System.out.flush();
+ Object[] keys = map.getKeys();
+ check(keys.length == N);
+ for (int i = 0; i != N; ++i) {
+ Object key = keys[i];
+ check(map.has(key));
+ }
+
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ check(i == map.get(key, -1));
+ }
+
+ int Nsqrt = -1;
+ for (int i = 0; ; ++i) {
+ if (i * i >= N) {
+ Nsqrt = i;
+ break;
+ }
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i * i);
+ map.put(key, i);
+ check(i == map.get(key, -1));
+ }
+
+ check(map.size() == 2 * N - Nsqrt);
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i * i);
+ check(i == map.get(key, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(-1 - i * i);
+ map.put(key, i);
+ check(i == map.get(key, -1));
+ }
+
+ check(map.size() == 3 * N - Nsqrt);
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(-1 - i * i);
+ map.remove(key);
+ check(!map.has(key));
+ }
+
+ check(map.size() == 2 * N - Nsqrt);
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i * i);
+ check(i == map.get(key, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ int j = intSqrt(i);
+ if (j * j == i) {
+ check(j == map.get(key, -1));
+ }else {
+ check(i == map.get(key, -1));
+ }
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i * i);
+ map.remove(key);
+ check(-2 == map.get(key, -2));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ map.put(key, i);
+ check(i == map.get(key, -2));
+ }
+
+ check(map.size() == N);
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ check(i == map.get(key, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ ObjToIntMap copy = (ObjToIntMap)writeAndRead(map);
+ check(copy.size() == N);
+
+ for (int i = 0; i != N; ++i) {
+ Object key = testKey(i);
+ check(i == copy.get(key, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ checkSameMaps(copy, map);
+
+ System.out.println(); System.out.flush();
+ }
+
+ private static void checkSameMaps(ObjToIntMap map1, ObjToIntMap map2) {
+ check(map1.size() == map2.size());
+ Object[] keys = map1.getKeys();
+ check(keys.length == map1.size());
+ for (int i = 0; i != keys.length; ++i) {
+ check(map1.get(keys[i], -1) == map2.get(keys[i], -1));
+ }
+ }
+
+ private static void check(boolean condition) {
+ if (!condition) Kit.codeBug();
+ }
+
+ private static Object[] testPool;
+
+ private static Object testKey(int i) {
+ int MAX_POOL = 100;
+ if (0 <= i && i < MAX_POOL) {
+ if (testPool != null && testPool[i] != null) {
+ return testPool[i];
+ }
+ }
+ Object x = new Double(i + 0.5);
+ if (0 <= i && i < MAX_POOL) {
+ if (testPool == null) {
+ testPool = new Object[MAX_POOL];
+ }
+ testPool[i] = x;
+ }
+ return x;
+ }
+
+ private static int intSqrt(int i) {
+ int approx = (int)Math.sqrt(i) + 1;
+ while (approx * approx > i) {
+ --approx;
+ }
+ return approx;
+ }
+
+ private static Object writeAndRead(Object obj) {
+ try {
+ java.io.ByteArrayOutputStream
+ bos = new java.io.ByteArrayOutputStream();
+ java.io.ObjectOutputStream
+ out = new java.io.ObjectOutputStream(bos);
+ out.writeObject(obj);
+ out.close();
+ byte[] data = bos.toByteArray();
+ java.io.ByteArrayInputStream
+ bis = new java.io.ByteArrayInputStream(data);
+ java.io.ObjectInputStream
+ in = new java.io.ObjectInputStream(bis);
+ Object result = in.readObject();
+ in.close();
+ return result;
+ }catch (Exception ex) {
+ throw new RuntimeException("Unexpected");
+ }
+ }
+
+// TEST END */
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java
new file mode 100644
index 0000000..80cb937
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Parser.java
@@ -0,0 +1,2554 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ /*APPJET*//*no longer:private*/ String sourceURI;
+ boolean calledByCompileFunction;
+
+ /*APPJET*//*no longer:private*/ TokenStream ts;
+ private int currentFlaggedToken;
+ /*APPJET*//*no longer:private*/ int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ Node.Scope currentScope;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int endFlags;
+// end of per function variables
+
+ /*APPJET*/public int lastConsumedTokenLine = -1;
+
+ public int getCurrentLineNumber() {
+ return ts.getLineno();
+ }
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ /*APPJET*//*added method*/
+ RuntimeException reportError(String messageId, String messageArg)
+ {
+ addError(messageId, messageArg);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ /*APPJET*//*no longer: private*/int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+ tt = ts.getToken();
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+ } while (tt == Token.EOL);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ /*APPJET*//*no longer:private*/ void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ /*APPJET*/lastConsumedTokenLine = ts.getLineno();
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ /*APPJET*//*added method*/
+ private void mustMatchToken(int toMatch, String messageId, String messageArg)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId, messageArg);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ void pushScope(Node node) {
+ Node.Scope scopeNode = (Node.Scope) node;
+ if (scopeNode.getParentScope() != null) throw Kit.codeBug();
+ scopeNode.setParent(currentScope);
+ currentScope = scopeNode;
+ }
+
+ void popScope() {
+ currentScope = currentScope.getParentScope();
+ }
+
+ private Node enterLoop(Node loopLabel, boolean doPushScope)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ if (doPushScope) {
+ pushScope(loop);
+ }
+ return loop;
+ }
+
+ private void exitLoop(boolean doPopScope)
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ if (doPopScope) {
+ popScope();
+ }
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ currentScope = currentScriptOrFn;
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /*APPJET*/lastConsumedTokenLine = baseLineno;
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function <name>' does not follow
+ // by '(', assume <name> starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ if (syntheticType != FunctionNode.FUNCTION_EXPRESSION &&
+ name.length() > 0)
+ {
+ // Function statements define a symbol in the enclosing scope
+ defineSymbol(Token.FUNCTION, name);
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ Node.Scope savedCurrentScope = currentScope;
+ currentScope = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = endFlags;
+
+ Node destructuring = null;
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ int tt = peekToken();
+ if (tt == Token.LB || tt == Token.LC) {
+ // Destructuring assignment for parameters: add a
+ // dummy parameter name, and add a statement to the
+ // body to initialize variables from the destructuring
+ // assignment
+ if (destructuring == null) {
+ destructuring = new Node(Token.COMMA);
+ }
+ String parmName = currentScriptOrFn.getNextTempName();
+ defineSymbol(Token.LP, parmName);
+ destructuring.addChildToBack(
+ nf.createDestructuringAssignment(Token.VAR,
+ primaryExpr(), nf.createName(parmName)));
+ } else {
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ defineSymbol(Token.LP, s);
+ decompiler.addName(s);
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ if (destructuring != null) {
+ body.addChildToFront(
+ new Node(Token.EXPR_VOID, destructuring, ts.getLineno()));
+ }
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ if (syntheticType == FunctionNode.FUNCTION_EXPRESSION &&
+ name.length() > 0 && currentScope.getSymbol(name) == null)
+ {
+ // Function expressions define a name only in the body of the
+ // function, and only if not hidden by a parameter name
+ defineSymbol(Token.FUNCTION, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ endFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ currentScope = savedCurrentScope;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements(Node scope)
+ throws IOException
+ {
+ Node pn = scope != null ? scope : nf.createBlock(ts.getLineno());
+
+ int tt;
+ while ((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /*APPJET*/ /*begin*/
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException {
+
+ Node pn = statementHelper0(statementLabel);
+ if (pn != null && pn.getType() != Token.BLOCK && pn.getType() != Token.LOOP) {
+ pn.statementEndLineNum = lastConsumedTokenLine;
+ }
+ return pn;
+ }
+ /*end*/
+
+ private Node statementHelper0(Node statementLabel) /*APPJET*/
+ throws IOException, ParserException
+ {
+ Node pn = null;
+ int tt = peekToken();
+
+ switch (tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ /*APPJET*/cond.lineno = lineno;
+ /*APPJET*/cond.statementEndLineNum = lastConsumedTokenLine;
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ /*APPJET*/Node toSwitchOn = expr(false);
+ /*APPJET*/toSwitchOn.lineno = lineno;
+ /*APPJET*/toSwitchOn.statementEndLineNum = lastConsumedTokenLine;
+ pn = enterSwitch(toSwitchOn, lineno); /*APPJET*/
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default label
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel, true);
+ try {
+ /*APPJET*/int lineno = ts.getLineno();
+ Node cond = condition();
+ /*APPJET*/cond.lineno = lineno;
+ /*APPJET*/cond.statementEndLineNum = lastConsumedTokenLine;
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop(true);
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel, true);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop(true);
+ }
+ // Always auto-insert semicolon to follow SpiderMonkey:
+ // It is required by ECMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel, true);
+ try {
+ Node init; // Node init is also foo in 'foo in object'
+ Node cond; // Node cond is also object in 'foo in object'
+ Node incr = null;
+ Node body;
+ int declType = -1;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR || tt == Token.LET) {
+ // set init to a var list or initial
+ consumeToken(); // consume the token
+ decompiler.addToken(tt);
+ init = variables(true, tt);
+ declType = tt;
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ /*APPJET*/int parenEndLine = lastConsumedTokenLine;
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(declType, loop, init, cond, body,
+ isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ /*APPJET*/ // use the LOOP object to hold the range of the paren'd expr
+ /*APPJET*/pn.statementEndLineNum = parenEndLine;
+ } finally {
+ exitLoop(true);
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ if (peekToken() != Token.LC) {
+ reportError("msg.no.brace.try");
+ }
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(null),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ /*APPJET*/obj.lineno = lineno;
+ /*APPJET*/obj.statementEndLineNum = lastConsumedTokenLine;
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = variables(false, tt);
+ break;
+ }
+
+ case Token.LET: {
+ consumeToken();
+ decompiler.addToken(Token.LET);
+ if (peekToken() == Token.LP) {
+ pn = let(true);
+ } else {
+ pn = variables(false, tt);
+ }
+ return pn;
+ }
+
+ case Token.RETURN:
+ case Token.YIELD: {
+ pn = returnOrYield(tt, false);
+ break;
+ }
+
+ case Token.DEBUGGER:
+ consumeToken();
+ decompiler.addToken(Token.DEBUGGER);
+ pn = nf.createDebugger(ts.getLineno());
+ break;
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ Node scope = nf.createScopeNode(Token.BLOCK, ts.getLineno());
+ pushScope(scope);
+ try {
+ statements(scope);
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return scope;
+ } finally {
+ popScope();
+ }
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Returns whether or not the bits in the mask have changed to all set.
+ * @param before bits before change
+ * @param after bits after change
+ * @param mask mask for bits
+ * @return true if all the bits in the mask are set in "after" but not
+ * "before"
+ */
+ private static final boolean nowAllSet(int before, int after, int mask)
+ {
+ return ((before & mask) != mask) && ((after & mask) == mask);
+ }
+
+ private Node returnOrYield(int tt, boolean exprContext)
+ throws IOException, ParserException
+ {
+ if (!insideFunction()) {
+ reportError(tt == Token.RETURN ? "msg.bad.return"
+ : "msg.bad.yield");
+ }
+ consumeToken();
+ decompiler.addToken(tt);
+ int lineno = ts.getLineno();
+
+ Node e;
+ /* This is ugly, but we don't want to require a semicolon. */
+ switch (peekTokenOrEOL()) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ case Token.RB:
+ case Token.RP:
+ case Token.YIELD:
+ e = null;
+ break;
+ default:
+ e = expr(false);
+ break;
+ }
+
+ int before = endFlags;
+ Node ret;
+
+ if (tt == Token.RETURN) {
+ if (e == null ) {
+ endFlags |= Node.END_RETURNS;
+ } else {
+ endFlags |= Node.END_RETURNS_VALUE;
+ hasReturnValue = true;
+ }
+ ret = nf.createReturn(e, lineno);
+
+ // see if we need a strict mode warning
+ if (nowAllSet(before, endFlags,
+ Node.END_RETURNS|Node.END_RETURNS_VALUE))
+ {
+ addStrictWarning("msg.return.inconsistent", "");
+ }
+ } else {
+ endFlags |= Node.END_YIELDS;
+ ret = nf.createYield(e, lineno);
+ if (!exprContext)
+ ret = new Node(Token.EXPR_VOID, ret, lineno);
+ }
+
+ // see if we are mixing yields and value returns.
+ if (nowAllSet(before, endFlags,
+ Node.END_YIELDS|Node.END_RETURNS_VALUE))
+ {
+ String name = ((FunctionNode)currentScriptOrFn).getFunctionName();
+ if (name.length() == 0)
+ addError("msg.anon.generator.returns", "");
+ else
+ addError("msg.generator.returns", name);
+ }
+
+ return ret;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param inFor true if we are currently in the midst of the init
+ * clause of a for.
+ * @param inStatement true if called in a statement (as opposed to an
+ * expression) context
+ * @param declType A token value: either VAR, CONST, or LET depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(boolean inFor, int declType)
+ throws IOException, ParserException
+ {
+ Node result = nf.createVariables(declType, ts.getLineno());
+ boolean first = true;
+ for (;;) {
+ Node destructuring = null;
+ String s = null;
+ int tt = peekToken();
+ if (tt == Token.LB || tt == Token.LC) {
+ // Destructuring assignment, e.g., var [a,b] = ...
+ destructuring = primaryExpr();
+ } else {
+ // Simple variable name
+ mustMatchToken(Token.NAME, "msg.bad.var",
+ Token.name(declType).toLowerCase());
+ s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+ defineSymbol(declType, s);
+ }
+
+ Node init = null;
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+ init = assignExpr(inFor);
+ }
+
+ if (destructuring != null) {
+ if (init == null) {
+ if (!inFor)
+ reportError("msg.destruct.assign.no.init");
+ nf.addChildToBack(result, destructuring);
+ } else {
+ nf.addChildToBack(result,
+ nf.createDestructuringAssignment(declType,
+ destructuring, init));
+ }
+ } else {
+ Node name = nf.createName(s);
+ if (init != null)
+ nf.addChildToBack(name, init);
+ nf.addChildToBack(result, name);
+ }
+
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return result;
+ }
+
+
+ private Node let(boolean isStatement)
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.after.let");
+ decompiler.addToken(Token.LP);
+ Node result = nf.createScopeNode(Token.LET, ts.getLineno());
+ pushScope(result);
+ try {
+ Node vars = variables(false, Token.LET);
+ nf.addChildToBack(result, vars);
+ mustMatchToken(Token.RP, "msg.no.paren.let");
+ decompiler.addToken(Token.RP);
+ if (isStatement && peekToken() == Token.LC) {
+ // let statement
+ consumeToken();
+ decompiler.addEOL(Token.LC);
+ nf.addChildToBack(result, statements(null));
+ mustMatchToken(Token.RC, "msg.no.curly.let");
+ decompiler.addToken(Token.RC);
+ } else {
+ // let expression
+ result.setType(Token.LETEXPR);
+ nf.addChildToBack(result, expr(false));
+ if (isStatement) {
+ // let expression in statement context
+ result = nf.createExprStatement(result, ts.getLineno());
+ }
+ }
+ } finally {
+ popScope();
+ }
+ return result;
+ }
+
+ void defineSymbol(int declType, String name) {
+ Node.Scope definingScope = currentScope.getDefiningScope(name);
+ Node.Scope.Symbol symbol = definingScope != null
+ ? definingScope.getSymbol(name)
+ : null;
+ boolean error = false;
+ if (symbol != null && (symbol.declType == Token.CONST ||
+ declType == Token.CONST))
+ {
+ error = true;
+ } else {
+ switch (declType) {
+ case Token.LET:
+ if (symbol != null && definingScope == currentScope) {
+ error = symbol.declType == Token.LET;
+ }
+ currentScope.putSymbol(name,
+ new Node.Scope.Symbol(declType, name));
+ break;
+
+ case Token.VAR:
+ case Token.CONST:
+ case Token.FUNCTION:
+ if (symbol != null) {
+ if (symbol.declType == Token.VAR)
+ addStrictWarning("msg.var.redecl", name);
+ else if (symbol.declType == Token.LP) {
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+ } else {
+ currentScriptOrFn.putSymbol(name,
+ new Node.Scope.Symbol(declType, name));
+ }
+ break;
+
+ case Token.LP:
+ if (symbol != null) {
+ // must be duplicate parameter. Second parameter hides the
+ // first, so go ahead and add the second pararameter
+ addWarning("msg.dup.parms", name);
+ }
+ currentScriptOrFn.putSymbol(name,
+ new Node.Scope.Symbol(declType, name));
+ break;
+
+ default:
+ throw Kit.codeBug();
+ }
+ }
+ if (error) {
+ addError(symbol.declType == Token.CONST ? "msg.const.redecl" :
+ symbol.declType == Token.LET ? "msg.let.redecl" :
+ symbol.declType == Token.VAR ? "msg.var.redecl" :
+ symbol.declType == Token.FUNCTION ? "msg.fn.redecl" :
+ "msg.parm.redecl", name);
+ }
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ if (peekToken() == Token.YIELD) {
+ reportError("msg.yield.parenthesized");
+ }
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ int tt = peekToken();
+ if (tt == Token.YIELD) {
+ consumeToken();
+ return returnOrYield(tt, true);
+ }
+ Node pn = condExpr(inForInit);
+
+ tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("error"); // Only reached on error.Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ if (peekToken() == Token.YIELD) {
+ reportError("msg.yield.parenthesized");
+ }
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+
+ // needed for generator.throw();
+ case Token.THROW:
+ decompiler.addName("throw");
+ pn = propertyName(pn, "throw", memberTypeFlags);
+ break;
+
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node arrayComprehension(String arrayName, Node expr)
+ throws IOException, ParserException
+ {
+ if (nextToken() != Token.FOR)
+ throw Kit.codeBug(); // shouldn't be here if next token isn't 'for'
+ decompiler.addName(" "); // space after array literal expr
+ decompiler.addToken(Token.FOR);
+ boolean isForEach = false;
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ String name;
+ int tt = peekToken();
+ if (tt == Token.LB || tt == Token.LC) {
+ // handle destructuring assignment
+ name = currentScriptOrFn.getNextTempName();
+ defineSymbol(Token.LP, name);
+ expr = nf.createBinary(Token.COMMA,
+ nf.createAssignment(Token.ASSIGN, primaryExpr(),
+ nf.createName(name)),
+ expr);
+ } else if (tt == Token.NAME) {
+ consumeToken();
+ name = ts.getString();
+ decompiler.addName(name);
+ } else {
+ reportError("msg.bad.var");
+ return nf.createNumber(0);
+ }
+
+ Node init = nf.createName(name);
+ // Define as a let since we want the scope of the variable to
+ // be restricted to the array comprehension
+ defineSymbol(Token.LET, name);
+
+ mustMatchToken(Token.IN, "msg.in.after.for.name");
+ decompiler.addToken(Token.IN);
+ Node iterator = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+
+ Node body;
+ tt = peekToken();
+ if (tt == Token.FOR) {
+ body = arrayComprehension(arrayName, expr);
+ } else {
+ Node call = nf.createCallOrNew(Token.CALL,
+ nf.createPropertyGet(nf.createName(arrayName), null,
+ "push", 0));
+ call.addChildToBack(expr);
+ body = new Node(Token.EXPR_VOID, call, ts.getLineno());
+ if (tt == Token.IF) {
+ consumeToken();
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ body = nf.createIf(cond, body, null, lineno);
+ }
+ mustMatchToken(Token.RB, "msg.no.bracket.arg");
+ decompiler.addToken(Token.RB);
+ }
+
+ Node loop = enterLoop(null, true);
+ try {
+ return nf.createForIn(Token.LET, loop, init, iterator, body,
+ isForEach);
+ } finally {
+ exitLoop(false);
+ }
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ int destructuringLen = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ // for ([a,] in obj) is legal, but for ([a] in obj) is
+ // not since we have both key and value supplied. The
+ // trick is that [a,] and [a] are equivalent in other
+ // array literal contexts. So we calculate a special
+ // length value just for destructuring assignment.
+ destructuringLen = elems.size() +
+ (after_lb_or_comma ? 1 : 0);
+ break;
+ } else if (skipCount == 0 && elems.size() == 1 &&
+ tt == Token.FOR)
+ {
+ Node scopeNode = nf.createScopeNode(Token.ARRAYCOMP,
+ ts.getLineno());
+ String tempName = currentScriptOrFn.getNextTempName();
+ pushScope(scopeNode);
+ try {
+ defineSymbol(Token.LET, tempName);
+ Node expr = (Node) elems.get(0);
+ Node block = nf.createBlock(ts.getLineno());
+ Node init = new Node(Token.EXPR_VOID,
+ nf.createAssignment(Token.ASSIGN,
+ nf.createName(tempName),
+ nf.createCallOrNew(Token.NEW,
+ nf.createName("Array"))), ts.getLineno());
+ block.addChildToBack(init);
+ block.addChildToBack(arrayComprehension(tempName,
+ expr));
+ scopeNode.addChildToBack(block);
+ scopeNode.addChildToBack(nf.createName(tempName));
+ return scopeNode;
+ } finally {
+ popScope();
+ }
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount, destructuringLen);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LET:
+ decompiler.addToken(Token.LET);
+ return let(false);
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ /*APPJET*/
+ int index = currentScriptOrFn.addRegexp
+ (re, flags, getCurrentLineNumber());
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java
new file mode 100644
index 0000000..c4d3d7e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/PolicySecurityController.java
@@ -0,0 +1,223 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.lang.ref.SoftReference;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.mozilla.classfile.ByteCode;
+import org.mozilla.classfile.ClassFileWriter;
+
+/**
+ * A security controller relying on Java {@link Policy} in effect. When you use
+ * this security controller, your securityDomain objects must be instances of
+ * {@link CodeSource} representing the location from where you load your
+ * scripts. Any Java policy "grant" statements matching the URL and certificate
+ * in code sources will apply to the scripts. If you specify any certificates
+ * within your {@link CodeSource} objects, it is your responsibility to verify
+ * (or not) that the script source files are signed in whatever
+ * implementation-specific way you're using.
+ * @author Attila Szegedi
+ */
+public class PolicySecurityController extends SecurityController
+{
+ private static final byte[] secureCallerImplBytecode = loadBytecode();
+
+ // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we
+ // need to have one renderer per class loader. We're using weak hash maps
+ // and soft references all the way, since we don't want to interfere with
+ // cleanup of either CodeSource or ClassLoader objects.
+ private static final Map callers = new WeakHashMap();
+
+ public Class getStaticSecurityDomainClassInternal() {
+ return CodeSource.class;
+ }
+
+ private static class Loader extends SecureClassLoader
+ implements GeneratedClassLoader
+ {
+ private final CodeSource codeSource;
+
+ Loader(ClassLoader parent, CodeSource codeSource)
+ {
+ super(parent);
+ this.codeSource = codeSource;
+ }
+
+ public Class defineClass(String name, byte[] data)
+ {
+ return defineClass(name, data, 0, data.length, codeSource);
+ }
+
+ public void linkClass(Class cl)
+ {
+ resolveClass(cl);
+ }
+ }
+
+ public GeneratedClassLoader createClassLoader(final ClassLoader parent,
+ final Object securityDomain)
+ {
+ return (Loader)AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return new Loader(parent, (CodeSource)securityDomain);
+ }
+ });
+ }
+
+ public Object getDynamicSecurityDomain(Object securityDomain)
+ {
+ // No separate notion of dynamic security domain - just return what was
+ // passed in.
+ return securityDomain;
+ }
+
+ public Object callWithDomain(final Object securityDomain, final Context cx,
+ Callable callable, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ // Run in doPrivileged as we might be checked for "getClassLoader"
+ // runtime permission
+ final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return cx.getApplicationClassLoader();
+ }
+ });
+ final CodeSource codeSource = (CodeSource)securityDomain;
+ Map classLoaderMap;
+ synchronized(callers)
+ {
+ classLoaderMap = (Map)callers.get(codeSource);
+ if(classLoaderMap == null)
+ {
+ classLoaderMap = new WeakHashMap();
+ callers.put(codeSource, classLoaderMap);
+ }
+ }
+ SecureCaller caller;
+ synchronized(classLoaderMap)
+ {
+ SoftReference ref = (SoftReference)classLoaderMap.get(classLoader);
+ if(ref != null)
+ {
+ caller = (SecureCaller)ref.get();
+ }
+ else
+ {
+ caller = null;
+ }
+ if(caller == null)
+ {
+ try
+ {
+ // Run in doPrivileged as we'll be checked for
+ // "createClassLoader" runtime permission
+ caller = (SecureCaller)AccessController.doPrivileged(
+ new PrivilegedExceptionAction()
+ {
+ public Object run() throws Exception
+ {
+ Loader loader = new Loader(classLoader,
+ codeSource);
+ Class c = loader.defineClass(
+ SecureCaller.class.getName() + "Impl",
+ secureCallerImplBytecode);
+ return c.newInstance();
+ }
+ });
+ classLoaderMap.put(classLoader, new SoftReference(caller));
+ }
+ catch(PrivilegedActionException ex)
+ {
+ throw new UndeclaredThrowableException(ex.getCause());
+ }
+ }
+ }
+ return caller.call(callable, cx, scope, thisObj, args);
+ }
+
+ public abstract static class SecureCaller
+ {
+ public abstract Object call(Callable callable, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args);
+ }
+
+
+ private static byte[] loadBytecode()
+ {
+ String secureCallerClassName = SecureCaller.class.getName();
+ ClassFileWriter cfw = new ClassFileWriter(
+ secureCallerClassName + "Impl", secureCallerClassName,
+ "<generated>");
+ cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
+ cfw.addALoad(0);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, secureCallerClassName,
+ "<init>", "()V");
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)1);
+ String callableCallSig =
+ "Lorg/mozilla/javascript/Context;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "[Ljava/lang/Object;)Ljava/lang/Object;";
+
+ cfw.startMethod("call",
+ "(Lorg/mozilla/javascript/Callable;" + callableCallSig,
+ (short)(ClassFileWriter.ACC_PUBLIC
+ | ClassFileWriter.ACC_FINAL));
+ for(int i = 1; i < 6; ++i) {
+ cfw.addALoad(i);
+ }
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/Callable", "call",
+ "(" + callableCallSig);
+ cfw.add(ByteCode.ARETURN);
+ cfw.stopMethod((short)6);
+ return cfw.toByteArray();
+ }
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java
new file mode 100644
index 0000000..1e237bc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Ref.java
@@ -0,0 +1,64 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+/**
+ * Generic notion of reference object that know how to query/modify the
+ * target objects based on some property/index.
+ */
+public abstract class Ref implements Serializable
+{
+ public boolean has(Context cx)
+ {
+ return true;
+ }
+
+ public abstract Object get(Context cx);
+
+ public abstract Object set(Context cx, Object value);
+
+ public boolean delete(Context cx)
+ {
+ return false;
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java
new file mode 100644
index 0000000..6d4b61c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RefCallable.java
@@ -0,0 +1,59 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@mir2.org
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * Object that can allows assignments to the result of function calls.
+ */
+public interface RefCallable extends Callable
+{
+ /**
+ * Perform function call in reference context.
+ * The args array reference should not be stored in any object that is
+ * can be GC-reachable after this method returns. If this is necessary,
+ * for example, to implement {@link Ref} methods, then store args.clone(),
+ * not args array itself.
+ *
+ * @param cx the current Context for this thread
+ * @param thisObj the JavaScript <code>this</code> object
+ * @param args the array of arguments
+ */
+ public Ref refCall(Context cx, Scriptable thisObj, Object[] args);
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java
new file mode 100644
index 0000000..ac29c6e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RegExpProxy.java
@@ -0,0 +1,71 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * A proxy for the regexp package, so that the regexp package can be
+ * loaded optionally.
+ *
+ * @author Norris Boyd
+ */
+public interface RegExpProxy
+{
+ // Types of regexp actions
+
+ public static final int RA_MATCH = 1;
+ public static final int RA_REPLACE = 2;
+ public static final int RA_SEARCH = 3;
+
+ public boolean isRegExp(Scriptable obj);
+
+ public Object compileRegExp(Context cx, String source, String flags);
+
+ public Scriptable wrapRegExp(Context cx, Scriptable scope,
+ Object compiled);
+
+ public Object action(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args,
+ int actionType);
+
+ public int find_split(Context cx, Scriptable scope, String target,
+ String separator, Scriptable re,
+ int[] ip, int[] matchlen,
+ boolean[] matched, String[][] parensp);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java
new file mode 100644
index 0000000..b7f4a4d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/RhinoException.java
@@ -0,0 +1,306 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript;
+
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The class of exceptions thrown by the JavaScript engine.
+ */
+public abstract class RhinoException extends RuntimeException
+{
+ RhinoException()
+ {
+ Evaluator e = Context.createInterpreter();
+ if (e != null)
+ e.captureStackInfo(this);
+ }
+
+ RhinoException(String details)
+ {
+ super(details);
+ Evaluator e = Context.createInterpreter();
+ if (e != null)
+ e.captureStackInfo(this);
+ }
+
+ public final String getMessage()
+ {
+ String details = details();
+ if (sourceName == null || lineNumber <= 0) {
+ return details;
+ }
+ StringBuffer buf = new StringBuffer(details);
+ buf.append(" (");
+ if (sourceName != null) {
+ buf.append(sourceName);
+ }
+ if (lineNumber > 0) {
+ buf.append('#');
+ buf.append(lineNumber);
+ }
+ buf.append(')');
+ return buf.toString();
+ }
+
+ public String details()
+ {
+ return super.getMessage();
+ }
+
+ /**
+ * Get the uri of the script source containing the error, or null
+ * if that information is not available.
+ */
+ public final String sourceName()
+ {
+ return sourceName;
+ }
+
+ /**
+ * Initialize the uri of the script source containing the error.
+ *
+ * @param sourceName the uri of the script source responsible for the error.
+ * It should not be <tt>null</tt>.
+ *
+ * @throws IllegalStateException if the method is called more then once.
+ */
+ public final void initSourceName(String sourceName)
+ {
+ if (sourceName == null) throw new IllegalArgumentException();
+ if (this.sourceName != null) throw new IllegalStateException();
+ this.sourceName = sourceName;
+ }
+
+ /**
+ * Returns the line number of the statement causing the error,
+ * or zero if not available.
+ */
+ public final int lineNumber()
+ {
+ return lineNumber;
+ }
+
+ /**
+ * Initialize the line number of the script statement causing the error.
+ *
+ * @param lineNumber the line number in the script source.
+ * It should be positive number.
+ *
+ * @throws IllegalStateException if the method is called more then once.
+ */
+ public final void initLineNumber(int lineNumber)
+ {
+ if (lineNumber <= 0) throw new IllegalArgumentException(String.valueOf(lineNumber));
+ if (this.lineNumber > 0) throw new IllegalStateException();
+ this.lineNumber = lineNumber;
+ }
+
+ /**
+ * The column number of the location of the error, or zero if unknown.
+ */
+ public final int columnNumber()
+ {
+ return columnNumber;
+ }
+
+ /**
+ * Initialize the column number of the script statement causing the error.
+ *
+ * @param columnNumber the column number in the script source.
+ * It should be positive number.
+ *
+ * @throws IllegalStateException if the method is called more then once.
+ */
+ public final void initColumnNumber(int columnNumber)
+ {
+ if (columnNumber <= 0) throw new IllegalArgumentException(String.valueOf(columnNumber));
+ if (this.columnNumber > 0) throw new IllegalStateException();
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * The source text of the line causing the error, or null if unknown.
+ */
+ public final String lineSource()
+ {
+ return lineSource;
+ }
+
+ /**
+ * Initialize the text of the source line containing the error.
+ *
+ * @param lineSource the text of the source line responsible for the error.
+ * It should not be <tt>null</tt>.
+ *
+ * @throws IllegalStateException if the method is called more then once.
+ */
+ public final void initLineSource(String lineSource)
+ {
+ if (lineSource == null) throw new IllegalArgumentException();
+ if (this.lineSource != null) throw new IllegalStateException();
+ this.lineSource = lineSource;
+ }
+
+ final void recordErrorOrigin(String sourceName, int lineNumber,
+ String lineSource, int columnNumber)
+ {
+ // XXX: for compatibility allow for now -1 to mean 0
+ if (lineNumber == -1) {
+ lineNumber = 0;
+ }
+
+ if (sourceName != null) {
+ initSourceName(sourceName);
+ }
+ if (lineNumber != 0) {
+ initLineNumber(lineNumber);
+ }
+ if (lineSource != null) {
+ initLineSource(lineSource);
+ }
+ if (columnNumber != 0) {
+ initColumnNumber(columnNumber);
+ }
+ }
+
+ private String generateStackTrace()
+ {
+ // Get stable reference to work properly with concurrent access
+ CharArrayWriter writer = new CharArrayWriter();
+ super.printStackTrace(new PrintWriter(writer));
+ String origStackTrace = writer.toString();
+ Evaluator e = Context.createInterpreter();
+ if (e != null)
+ return e.getPatchedStack(this, origStackTrace);
+ return null;
+ }
+
+ /**
+ * Get a string representing the script stack of this exception.
+ * If optimization is enabled, this corresponds to all java stack elements
+ * with a source name ending with ".js".
+ * @return a script stack dump
+ * @since 1.6R6
+ */
+ public String getScriptStackTrace()
+ {
+ return getScriptStackTrace(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".js");
+ }
+ });
+ }
+
+ /**
+ * Get a string representing the script stack of this exception.
+ * If optimization is enabled, this corresponds to all java stack elements
+ * with a source name matching the <code>filter</code>.
+ * @param filter the file name filter to determine whether a file is a
+ * script file
+ * @return a script stack dump
+ * @since 1.6R6
+ */
+ public String getScriptStackTrace(FilenameFilter filter)
+ {
+ List interpreterStack;
+ Evaluator interpreter = Context.createInterpreter();
+ if (interpreter != null)
+ interpreterStack = interpreter.getScriptStack(this);
+ else
+ interpreterStack = new ArrayList();
+ int interpreterStackIndex = 0;
+ StringBuffer buffer = new StringBuffer();
+ String lineSeparator = SecurityUtilities.getSystemProperty("line.separator");
+ StackTraceElement[] stack = getStackTrace();
+ for (int i = 0; i < stack.length; i++) {
+ StackTraceElement e = stack[i];
+ String name = e.getFileName();
+ if (e.getLineNumber() > -1 && name != null &&
+ filter.accept(null, name))
+ {
+ buffer.append("\tat ");
+ buffer.append(e.getFileName());
+ buffer.append(':');
+ buffer.append(e.getLineNumber());
+ buffer.append(lineSeparator);
+ } else if (interpreterStack != null &&
+ "org.mozilla.javascript.Interpreter".equals(e.getClassName()) &&
+ "interpretLoop".equals(e.getMethodName()))
+ {
+ buffer.append(interpreterStack.get(interpreterStackIndex++));
+ }
+ }
+ return buffer.toString();
+ }
+
+ public void printStackTrace(PrintWriter s)
+ {
+ if (interpreterStackInfo == null) {
+ super.printStackTrace(s);
+ } else {
+ s.print(generateStackTrace());
+ }
+ }
+
+ public void printStackTrace(PrintStream s)
+ {
+ if (interpreterStackInfo == null) {
+ super.printStackTrace(s);
+ } else {
+ s.print(generateStackTrace());
+ }
+ }
+
+ private String sourceName;
+ private int lineNumber;
+ private String lineSource;
+ private int columnNumber;
+
+ Object interpreterStackInfo;
+ int[] interpreterLineData;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java
new file mode 100644
index 0000000..4721ead
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Script.java
@@ -0,0 +1,73 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * All compiled scripts implement this interface.
+ * <p>
+ * This class encapsulates script execution relative to an
+ * object scope.
+ * @since 1.3
+ * @author Norris Boyd
+ */
+
+public interface Script {
+
+ /**
+ * Execute the script.
+ * <p>
+ * The script is executed in a particular runtime Context, which
+ * must be associated with the current thread.
+ * The script is executed relative to a scope--definitions and
+ * uses of global top-level variables and functions will access
+ * properties of the scope object. For compliant ECMA
+ * programs, the scope must be an object that has been initialized
+ * as a global object using <code>Context.initStandardObjects</code>.
+ * <p>
+ *
+ * @param cx the Context associated with the current thread
+ * @param scope the scope to execute relative to
+ * @return the result of executing the script
+ * @see org.mozilla.javascript.Context#initStandardObjects()
+ */
+ public Object exec(Context cx, Scriptable scope);
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java
new file mode 100644
index 0000000..9ea6d1f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptOrFnNode.java
@@ -0,0 +1,241 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Bob Jervis
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.util.ArrayList;
+
+public class ScriptOrFnNode extends Node.Scope {
+
+ public ScriptOrFnNode(int nodeType) {
+ super(nodeType);
+ symbols = new ArrayList(4);
+ setParent(null);
+ }
+
+ public final String getSourceName() { return sourceName; }
+
+ public final void setSourceName(String sourceName) {
+ this.sourceName = sourceName;
+ }
+
+ public final int getEncodedSourceStart() { return encodedSourceStart; }
+
+ public final int getEncodedSourceEnd() { return encodedSourceEnd; }
+
+ public final void setEncodedSourceBounds(int start, int end) {
+ this.encodedSourceStart = start;
+ this.encodedSourceEnd = end;
+ }
+
+ public final int getBaseLineno() { return this.lineno; }
+
+ public final void setBaseLineno(int lineno) {
+ // One time action
+ if (lineno < 0 || this.lineno >= 0) Kit.codeBug();
+ this.lineno = lineno;
+ }
+
+ public final int getEndLineno() { return endLineno; }
+
+ public final void setEndLineno(int lineno) {
+ // One time action
+ if (lineno < 0 || endLineno >= 0) Kit.codeBug();
+ endLineno = lineno;
+ }
+
+ public final int getFunctionCount() {
+ if (functions == null) { return 0; }
+ return functions.size();
+ }
+
+ public final FunctionNode getFunctionNode(int i) {
+ return (FunctionNode)functions.get(i);
+ }
+
+ public final int addFunction(FunctionNode fnNode) {
+ if (fnNode == null) Kit.codeBug();
+ if (functions == null) { functions = new ObjArray(); }
+ functions.add(fnNode);
+ return functions.size() - 1;
+ }
+
+ public final int getRegexpCount() {
+ if (regexps == null) { return 0; }
+ return regexps.size() / 2;
+ }
+
+ public final String getRegexpString(int index) {
+ return (String)regexps.get(index * 2);
+ }
+
+ public final String getRegexpFlags(int index) {
+ return (String)regexps.get(index * 2 + 1);
+ }
+
+ /*APPJET*/public final int getRegexpLineno(int index) {
+ return (Integer)regexpLinenos.get(index);
+ }
+
+ public final int addRegexp(String string, String flags, /*APPJET*/
+ int lineno) {
+ if (string == null) Kit.codeBug();
+ if (regexps == null) {
+ /*APPJET*/
+ regexps = new ObjArray();
+ regexpLinenos = new ObjArray();
+ }
+ regexps.add(string);
+ regexps.add(flags);
+ /*APPJET*/regexpLinenos.add(lineno);
+ return regexps.size() / 2 - 1;
+ }
+
+ public int getIndexForNameNode(Node nameNode) {
+ if (variableNames == null) throw Kit.codeBug();
+ Node.Scope node = nameNode.getScope();
+ Symbol symbol = node == null ? null
+ : node.getSymbol(nameNode.getString());
+ if (symbol == null)
+ return -1;
+ return symbol.index;
+ }
+
+ public final String getParamOrVarName(int index) {
+ if (variableNames == null) throw Kit.codeBug();
+ return variableNames[index];
+ }
+
+ public final int getParamCount() {
+ return paramCount;
+ }
+
+ public final int getParamAndVarCount() {
+ if (variableNames == null) throw Kit.codeBug();
+ return symbols.size();
+ }
+
+ public final String[] getParamAndVarNames() {
+ if (variableNames == null) throw Kit.codeBug();
+ return variableNames;
+ }
+
+ public final boolean[] getParamAndVarConst() {
+ if (variableNames == null) throw Kit.codeBug();
+ return isConsts;
+ }
+
+ void addSymbol(Symbol symbol) {
+ if (variableNames != null) throw Kit.codeBug();
+ if (symbol.declType == Token.LP) {
+ paramCount++;
+ }
+ symbols.add(symbol);
+ }
+
+ /**
+ * Assign every symbol a unique integer index. Generate arrays of variable
+ * names and constness that can be indexed by those indices.
+ *
+ * @param flattenAllTables if true, flatten all symbol tables, included
+ * nested block scope symbol tables. If false, just flatten the script's
+ * or function's symbol table.
+ */
+ void flattenSymbolTable(boolean flattenAllTables) {
+ if (!flattenAllTables) {
+ ArrayList newSymbols = new ArrayList();
+ if (this.symbolTable != null) {
+ // Just replace "symbols" with the symbols in this object's
+ // symbol table. Can't just work from symbolTable map since
+ // we need to retain duplicate parameters.
+ for (int i=0; i < symbols.size(); i++) {
+ Symbol symbol = (Symbol) symbols.get(i);
+ if (symbol.containingTable == this) {
+ newSymbols.add(symbol);
+ }
+ }
+ }
+ symbols = newSymbols;
+ }
+ variableNames = new String[symbols.size()];
+ isConsts = new boolean[symbols.size()];
+ for (int i=0; i < symbols.size(); i++) {
+ Symbol symbol = (Symbol) symbols.get(i);
+ variableNames[i] = symbol.name;
+ isConsts[i] = symbol.declType == Token.CONST;
+ symbol.index = i;
+ }
+ }
+
+ public final Object getCompilerData()
+ {
+ return compilerData;
+ }
+
+ public final void setCompilerData(Object data)
+ {
+ if (data == null) throw new IllegalArgumentException();
+ // Can only call once
+ if (compilerData != null) throw new IllegalStateException();
+ compilerData = data;
+ }
+
+ public String getNextTempName()
+ {
+ return "$" + tempNumber++;
+ }
+
+ private int encodedSourceStart;
+ private int encodedSourceEnd;
+ private String sourceName;
+ private int endLineno = -1;
+
+ private ObjArray functions;
+ private ObjArray regexps;
+ /*APPJET*/ private ObjArray regexpLinenos;
+
+ private ArrayList symbols;
+ private int paramCount = 0;
+ private String[] variableNames;
+ private boolean[] isConsts;
+
+ private Object compilerData;
+ private int tempNumber = 0;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java
new file mode 100644
index 0000000..f879581
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptRuntime.java
@@ -0,0 +1,3830 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ * Norris Boyd
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Roger Lawrence
+ * Terry Lucas
+ * Frank Mitchell
+ * Milen Nankov
+ * Hannes Wallnoefer
+ * Andrew Wason
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+import java.lang.reflect.*;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.mozilla.javascript.xml.XMLObject;
+import org.mozilla.javascript.xml.XMLLib;
+
+/**
+ * This is the class that implements the runtime.
+ *
+ * @author Norris Boyd
+ */
+
+public class ScriptRuntime {
+
+ /**
+ * No instances should be created.
+ */
+ protected ScriptRuntime() {
+ }
+
+ private static class NoSuchMethodShim implements Callable {
+ String methodName;
+ Callable noSuchMethodMethod;
+
+ NoSuchMethodShim(Callable noSuchMethodMethod, String methodName)
+ {
+ this.noSuchMethodMethod = noSuchMethodMethod;
+ this.methodName = methodName;
+ }
+ /**
+ * Perform the call.
+ *
+ * @param cx the current Context for this thread
+ * @param scope the scope to use to resolve properties.
+ * @param thisObj the JavaScript <code>this</code> object
+ * @param args the array of arguments
+ * @return the result of the call
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ Object[] nestedArgs = new Object[2];
+
+ nestedArgs[0] = methodName;
+ nestedArgs[1] = newArrayLiteral(args, null, cx, scope);
+ return noSuchMethodMethod.call(cx, scope, thisObj, nestedArgs);
+ }
+
+ }
+ /*
+ * There's such a huge space (and some time) waste for the Foo.class
+ * syntax: the compiler sticks in a test of a static field in the
+ * enclosing class for null and the code for creating the class value.
+ * It has to do this since the reference has to get pushed off until
+ * execution time (i.e. can't force an early load), but for the
+ * 'standard' classes - especially those in java.lang, we can trust
+ * that they won't cause problems by being loaded early.
+ */
+
+ public final static Class
+ BooleanClass = Kit.classOrNull("java.lang.Boolean"),
+ ByteClass = Kit.classOrNull("java.lang.Byte"),
+ CharacterClass = Kit.classOrNull("java.lang.Character"),
+ ClassClass = Kit.classOrNull("java.lang.Class"),
+ DoubleClass = Kit.classOrNull("java.lang.Double"),
+ FloatClass = Kit.classOrNull("java.lang.Float"),
+ IntegerClass = Kit.classOrNull("java.lang.Integer"),
+ LongClass = Kit.classOrNull("java.lang.Long"),
+ NumberClass = Kit.classOrNull("java.lang.Number"),
+ ObjectClass = Kit.classOrNull("java.lang.Object"),
+ ShortClass = Kit.classOrNull("java.lang.Short"),
+ StringClass = Kit.classOrNull("java.lang.String"),
+ DateClass = Kit.classOrNull("java.util.Date");
+
+ public final static Class
+ ContextClass
+ = Kit.classOrNull("org.mozilla.javascript.Context"),
+ ContextFactoryClass
+ = Kit.classOrNull("org.mozilla.javascript.ContextFactory"),
+ FunctionClass
+ = Kit.classOrNull("org.mozilla.javascript.Function"),
+ ScriptableClass
+ = Kit.classOrNull("org.mozilla.javascript.Scriptable"),
+ ScriptableObjectClass
+ = Kit.classOrNull("org.mozilla.javascript.ScriptableObject");
+
+ private static final String[] lazilyNames = {
+ "RegExp", "org.mozilla.javascript.regexp.NativeRegExp",
+ "Packages", "org.mozilla.javascript.NativeJavaTopPackage",
+ "java", "org.mozilla.javascript.NativeJavaTopPackage",
+ "javax", "org.mozilla.javascript.NativeJavaTopPackage",
+ "org", "org.mozilla.javascript.NativeJavaTopPackage",
+ "com", "org.mozilla.javascript.NativeJavaTopPackage",
+ "edu", "org.mozilla.javascript.NativeJavaTopPackage",
+ "net", "org.mozilla.javascript.NativeJavaTopPackage",
+ "getClass", "org.mozilla.javascript.NativeJavaTopPackage",
+ "JavaAdapter", "org.mozilla.javascript.JavaAdapter",
+ "JavaImporter", "org.mozilla.javascript.ImporterTopLevel",
+ "Continuation", "org.mozilla.javascript.continuations.Continuation",
+ // TODO Grotesque hack using literal string (xml) just to minimize
+ // changes for now
+ "XML", "(xml)",
+ "XMLList", "(xml)",
+ "Namespace", "(xml)",
+ "QName", "(xml)",
+ };
+
+ private static final Object LIBRARY_SCOPE_KEY = new Object();
+
+ public static boolean isRhinoRuntimeType(Class cl)
+ {
+ if (cl.isPrimitive()) {
+ return (cl != Character.TYPE);
+ } else {
+ return (cl == StringClass || cl == BooleanClass
+ || NumberClass.isAssignableFrom(cl)
+ || ScriptableClass.isAssignableFrom(cl));
+ }
+ }
+
+ public static ScriptableObject initStandardObjects(Context cx,
+ ScriptableObject scope,
+ boolean sealed)
+ {
+ if (scope == null) {
+ scope = new NativeObject();
+ }
+ scope.associateValue(LIBRARY_SCOPE_KEY, scope);
+ (new ClassCache()).associate(scope);
+
+ BaseFunction.init(scope, sealed);
+ NativeObject.init(scope, sealed);
+
+ Scriptable objectProto = ScriptableObject.getObjectPrototype(scope);
+
+ // Function.prototype.__proto__ should be Object.prototype
+ Scriptable functionProto = ScriptableObject.getFunctionPrototype(scope);
+ functionProto.setPrototype(objectProto);
+
+ // Set the prototype of the object passed in if need be
+ if (scope.getPrototype() == null)
+ scope.setPrototype(objectProto);
+
+ // must precede NativeGlobal since it's needed therein
+ NativeError.init(scope, sealed);
+ NativeGlobal.init(cx, scope, sealed);
+
+ NativeArray.init(scope, sealed);
+ if (cx.getOptimizationLevel() > 0) {
+ // When optimizing, attempt to fulfill all requests for new Array(N)
+ // with a higher threshold before switching to a sparse
+ // representation
+ NativeArray.setMaximumInitialCapacity(200000);
+ }
+ NativeString.init(scope, sealed);
+ NativeBoolean.init(scope, sealed);
+ NativeNumber.init(scope, sealed);
+ NativeDate.init(scope, sealed);
+ NativeMath.init(scope, sealed);
+
+ NativeWith.init(scope, sealed);
+ NativeCall.init(scope, sealed);
+ NativeScript.init(scope, sealed);
+
+ NativeIterator.init(scope, sealed); // Also initializes NativeGenerator
+
+ boolean withXml = cx.hasFeature(Context.FEATURE_E4X) &&
+ cx.getE4xImplementationFactory() != null;
+
+ for (int i = 0; i != lazilyNames.length; i += 2) {
+ String topProperty = lazilyNames[i];
+ String className = lazilyNames[i + 1];
+ if (!withXml && className.equals("(xml)")) {
+ continue;
+ } else if (withXml && className.equals("(xml)")) {
+ className = cx.getE4xImplementationFactory().
+ getImplementationClassName();
+ }
+ new LazilyLoadedCtor(scope, topProperty, className, sealed);
+ }
+
+ return scope;
+ }
+
+ public static ScriptableObject getLibraryScopeOrNull(Scriptable scope)
+ {
+ ScriptableObject libScope;
+ libScope = (ScriptableObject)ScriptableObject.
+ getTopScopeValue(scope, LIBRARY_SCOPE_KEY);
+ return libScope;
+ }
+
+ // It is public so NativeRegExp can access it.
+ public static boolean isJSLineTerminator(int c)
+ {
+ // Optimization for faster check for eol character:
+ // they do not have 0xDFD0 bits set
+ if ((c & 0xDFD0) != 0) {
+ return false;
+ }
+ return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029;
+ }
+
+ public static Boolean wrapBoolean(boolean b)
+ {
+ return b ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public static Integer wrapInt(int i)
+ {
+ return new Integer(i);
+ }
+
+ public static Number wrapNumber(double x)
+ {
+ if (x != x) {
+ return ScriptRuntime.NaNobj;
+ }
+ return new Double(x);
+ }
+
+ /**
+ * Convert the value to a boolean.
+ *
+ * See ECMA 9.2.
+ */
+ public static boolean toBoolean(Object val)
+ {
+ for (;;) {
+ if (val instanceof Boolean)
+ return ((Boolean) val).booleanValue();
+ if (val == null || val == Undefined.instance)
+ return false;
+ if (val instanceof String)
+ return ((String) val).length() != 0;
+ if (val instanceof Number) {
+ double d = ((Number) val).doubleValue();
+ return (d == d && d != 0.0);
+ }
+ if (val instanceof Scriptable) {
+ if (val instanceof ScriptableObject &&
+ ((ScriptableObject) val).avoidObjectDetection())
+ {
+ return false;
+ }
+ if (Context.getContext().isVersionECMA1()) {
+ // pure ECMA
+ return true;
+ }
+ // ECMA extension
+ val = ((Scriptable) val).getDefaultValue(BooleanClass);
+ if (val instanceof Scriptable)
+ throw errorWithClassName("msg.primitive.expected", val);
+ continue;
+ }
+ warnAboutNonJSObject(val);
+ return true;
+ }
+ }
+
+ /**
+ * Convert the value to a number.
+ *
+ * See ECMA 9.3.
+ */
+ public static double toNumber(Object val)
+ {
+ for (;;) {
+ if (val instanceof Number)
+ return ((Number) val).doubleValue();
+ if (val == null)
+ return +0.0;
+ if (val == Undefined.instance)
+ return NaN;
+ if (val instanceof String)
+ return toNumber((String) val);
+ if (val instanceof Boolean)
+ return ((Boolean) val).booleanValue() ? 1 : +0.0;
+ if (val instanceof Scriptable) {
+ val = ((Scriptable) val).getDefaultValue(NumberClass);
+ if (val instanceof Scriptable)
+ throw errorWithClassName("msg.primitive.expected", val);
+ continue;
+ }
+ warnAboutNonJSObject(val);
+ return NaN;
+ }
+ }
+
+ public static double toNumber(Object[] args, int index) {
+ return (index < args.length) ? toNumber(args[index]) : NaN;
+ }
+
+ // Can not use Double.NaN defined as 0.0d / 0.0 as under the Microsoft VM,
+ // versions 2.01 and 3.0P1, that causes some uses (returns at least) of
+ // Double.NaN to be converted to 1.0.
+ // So we use ScriptRuntime.NaN instead of Double.NaN.
+ public static final double
+ NaN = Double.longBitsToDouble(0x7ff8000000000000L);
+
+ // A similar problem exists for negative zero.
+ public static final double
+ negativeZero = Double.longBitsToDouble(0x8000000000000000L);
+
+ public static final Double NaNobj = new Double(NaN);
+
+ /*
+ * Helper function for toNumber, parseInt, and TokenStream.getToken.
+ */
+ static double stringToNumber(String s, int start, int radix) {
+ char digitMax = '9';
+ char lowerCaseBound = 'a';
+ char upperCaseBound = 'A';
+ int len = s.length();
+ if (radix < 10) {
+ digitMax = (char) ('0' + radix - 1);
+ }
+ if (radix > 10) {
+ lowerCaseBound = (char) ('a' + radix - 10);
+ upperCaseBound = (char) ('A' + radix - 10);
+ }
+ int end;
+ double sum = 0.0;
+ for (end=start; end < len; end++) {
+ char c = s.charAt(end);
+ int newDigit;
+ if ('0' <= c && c <= digitMax)
+ newDigit = c - '0';
+ else if ('a' <= c && c < lowerCaseBound)
+ newDigit = c - 'a' + 10;
+ else if ('A' <= c && c < upperCaseBound)
+ newDigit = c - 'A' + 10;
+ else
+ break;
+ sum = sum*radix + newDigit;
+ }
+ if (start == end) {
+ return NaN;
+ }
+ if (sum >= 9007199254740992.0) {
+ if (radix == 10) {
+ /* If we're accumulating a decimal number and the number
+ * is >= 2^53, then the result from the repeated multiply-add
+ * above may be inaccurate. Call Java to get the correct
+ * answer.
+ */
+ try {
+ return Double.valueOf(s.substring(start, end)).doubleValue();
+ } catch (NumberFormatException nfe) {
+ return NaN;
+ }
+ } else if (radix == 2 || radix == 4 || radix == 8 ||
+ radix == 16 || radix == 32)
+ {
+ /* The number may also be inaccurate for one of these bases.
+ * This happens if the addition in value*radix + digit causes
+ * a round-down to an even least significant mantissa bit
+ * when the first dropped bit is a one. If any of the
+ * following digits in the number (which haven't been added
+ * in yet) are nonzero then the correct action would have
+ * been to round up instead of down. An example of this
+ * occurs when reading the number 0x1000000000000081, which
+ * rounds to 0x1000000000000000 instead of 0x1000000000000100.
+ */
+ int bitShiftInChar = 1;
+ int digit = 0;
+
+ final int SKIP_LEADING_ZEROS = 0;
+ final int FIRST_EXACT_53_BITS = 1;
+ final int AFTER_BIT_53 = 2;
+ final int ZEROS_AFTER_54 = 3;
+ final int MIXED_AFTER_54 = 4;
+
+ int state = SKIP_LEADING_ZEROS;
+ int exactBitsLimit = 53;
+ double factor = 0.0;
+ boolean bit53 = false;
+ // bit54 is the 54th bit (the first dropped from the mantissa)
+ boolean bit54 = false;
+
+ for (;;) {
+ if (bitShiftInChar == 1) {
+ if (start == end)
+ break;
+ digit = s.charAt(start++);
+ if ('0' <= digit && digit <= '9')
+ digit -= '0';
+ else if ('a' <= digit && digit <= 'z')
+ digit -= 'a' - 10;
+ else
+ digit -= 'A' - 10;
+ bitShiftInChar = radix;
+ }
+ bitShiftInChar >>= 1;
+ boolean bit = (digit & bitShiftInChar) != 0;
+
+ switch (state) {
+ case SKIP_LEADING_ZEROS:
+ if (bit) {
+ --exactBitsLimit;
+ sum = 1.0;
+ state = FIRST_EXACT_53_BITS;
+ }
+ break;
+ case FIRST_EXACT_53_BITS:
+ sum *= 2.0;
+ if (bit)
+ sum += 1.0;
+ --exactBitsLimit;
+ if (exactBitsLimit == 0) {
+ bit53 = bit;
+ state = AFTER_BIT_53;
+ }
+ break;
+ case AFTER_BIT_53:
+ bit54 = bit;
+ factor = 2.0;
+ state = ZEROS_AFTER_54;
+ break;
+ case ZEROS_AFTER_54:
+ if (bit) {
+ state = MIXED_AFTER_54;
+ }
+ // fallthrough
+ case MIXED_AFTER_54:
+ factor *= 2;
+ break;
+ }
+ }
+ switch (state) {
+ case SKIP_LEADING_ZEROS:
+ sum = 0.0;
+ break;
+ case FIRST_EXACT_53_BITS:
+ case AFTER_BIT_53:
+ // do nothing
+ break;
+ case ZEROS_AFTER_54:
+ // x1.1 -> x1 + 1 (round up)
+ // x0.1 -> x0 (round down)
+ if (bit54 & bit53)
+ sum += 1.0;
+ sum *= factor;
+ break;
+ case MIXED_AFTER_54:
+ // x.100...1.. -> x + 1 (round up)
+ // x.0anything -> x (round down)
+ if (bit54)
+ sum += 1.0;
+ sum *= factor;
+ break;
+ }
+ }
+ /* We don't worry about inaccurate numbers for any other base. */
+ }
+ return sum;
+ }
+
+
+ /**
+ * ToNumber applied to the String type
+ *
+ * See ECMA 9.3.1
+ */
+ public static double toNumber(String s) {
+ int len = s.length();
+ int start = 0;
+ char startChar;
+ for (;;) {
+ if (start == len) {
+ // Empty or contains only whitespace
+ return +0.0;
+ }
+ startChar = s.charAt(start);
+ if (!Character.isWhitespace(startChar))
+ break;
+ start++;
+ }
+
+ if (startChar == '0') {
+ if (start + 2 < len) {
+ int c1 = s.charAt(start + 1);
+ if (c1 == 'x' || c1 == 'X') {
+ // A hexadecimal number
+ return stringToNumber(s, start + 2, 16);
+ }
+ }
+ } else if (startChar == '+' || startChar == '-') {
+ if (start + 3 < len && s.charAt(start + 1) == '0') {
+ int c2 = s.charAt(start + 2);
+ if (c2 == 'x' || c2 == 'X') {
+ // A hexadecimal number with sign
+ double val = stringToNumber(s, start + 3, 16);
+ return startChar == '-' ? -val : val;
+ }
+ }
+ }
+
+ int end = len - 1;
+ char endChar;
+ while (Character.isWhitespace(endChar = s.charAt(end)))
+ end--;
+ if (endChar == 'y') {
+ // check for "Infinity"
+ if (startChar == '+' || startChar == '-')
+ start++;
+ if (start + 7 == end && s.regionMatches(start, "Infinity", 0, 8))
+ return startChar == '-'
+ ? Double.NEGATIVE_INFINITY
+ : Double.POSITIVE_INFINITY;
+ return NaN;
+ }
+ // A non-hexadecimal, non-infinity number:
+ // just try a normal floating point conversion
+ String sub = s.substring(start, end+1);
+ if (MSJVM_BUG_WORKAROUNDS) {
+ // The MS JVM will accept non-conformant strings
+ // rather than throwing a NumberFormatException
+ // as it should.
+ for (int i=sub.length()-1; i >= 0; i--) {
+ char c = sub.charAt(i);
+ if (('0' <= c && c <= '9') || c == '.' ||
+ c == 'e' || c == 'E' ||
+ c == '+' || c == '-')
+ continue;
+ return NaN;
+ }
+ }
+ try {
+ return Double.valueOf(sub).doubleValue();
+ } catch (NumberFormatException ex) {
+ return NaN;
+ }
+ }
+
+ /**
+ * Helper function for builtin objects that use the varargs form.
+ * ECMA function formal arguments are undefined if not supplied;
+ * this function pads the argument array out to the expected
+ * length, if necessary.
+ */
+ public static Object[] padArguments(Object[] args, int count) {
+ if (count < args.length)
+ return args;
+
+ int i;
+ Object[] result = new Object[count];
+ for (i = 0; i < args.length; i++) {
+ result[i] = args[i];
+ }
+
+ for (; i < count; i++) {
+ result[i] = Undefined.instance;
+ }
+
+ return result;
+ }
+
+ /* Work around Microsoft Java VM bugs. */
+ private final static boolean MSJVM_BUG_WORKAROUNDS = true;
+
+ public static String escapeString(String s)
+ {
+ return escapeString(s, '"');
+ }
+
+ /**
+ * For escaping strings printed by object and array literals; not quite
+ * the same as 'escape.'
+ */
+ public static String escapeString(String s, char escapeQuote)
+ {
+ if (!(escapeQuote == '"' || escapeQuote == '\'')) Kit.codeBug();
+ StringBuffer sb = null;
+
+ for(int i = 0, L = s.length(); i != L; ++i) {
+ int c = s.charAt(i);
+
+ if (' ' <= c && c <= '~' && c != escapeQuote && c != '\\') {
+ // an ordinary print character (like C isprint()) and not "
+ // or \ .
+ if (sb != null) {
+ sb.append((char)c);
+ }
+ continue;
+ }
+ if (sb == null) {
+ sb = new StringBuffer(L + 3);
+ sb.append(s);
+ sb.setLength(i);
+ }
+
+ int escape = -1;
+ switch (c) {
+ case '\b': escape = 'b'; break;
+ case '\f': escape = 'f'; break;
+ case '\n': escape = 'n'; break;
+ case '\r': escape = 'r'; break;
+ case '\t': escape = 't'; break;
+ case 0xb: escape = 'v'; break; // Java lacks \v.
+ case ' ': escape = ' '; break;
+ case '\\': escape = '\\'; break;
+ }
+ if (escape >= 0) {
+ // an \escaped sort of character
+ sb.append('\\');
+ sb.append((char)escape);
+ } else if (c == escapeQuote) {
+ sb.append('\\');
+ sb.append(escapeQuote);
+ } else {
+ int hexSize;
+ if (c < 256) {
+ // 2-digit hex
+ sb.append("\\x");
+ hexSize = 2;
+ } else {
+ // Unicode.
+ sb.append("\\u");
+ hexSize = 4;
+ }
+ // append hexadecimal form of c left-padded with 0
+ for (int shift = (hexSize - 1) * 4; shift >= 0; shift -= 4) {
+ int digit = 0xf & (c >> shift);
+ int hc = (digit < 10) ? '0' + digit : 'a' - 10 + digit;
+ sb.append((char)hc);
+ }
+ }
+ }
+ return (sb == null) ? s : sb.toString();
+ }
+
+ static boolean isValidIdentifierName(String s)
+ {
+ int L = s.length();
+ if (L == 0)
+ return false;
+ if (!Character.isJavaIdentifierStart(s.charAt(0)))
+ return false;
+ for (int i = 1; i != L; ++i) {
+ if (!Character.isJavaIdentifierPart(s.charAt(i)))
+ return false;
+ }
+ return !TokenStream.isKeyword(s);
+ }
+
+ /**
+ * Convert the value to a string.
+ *
+ * See ECMA 9.8.
+ */
+ public static String toString(Object val) {
+ for (;;) {
+ if (val == null) {
+ return "null";
+ }
+ if (val == Undefined.instance) {
+ return "undefined";
+ }
+ if (val instanceof String) {
+ return (String)val;
+ }
+ if (val instanceof Number) {
+ // XXX should we just teach NativeNumber.stringValue()
+ // about Numbers?
+ return numberToString(((Number)val).doubleValue(), 10);
+ }
+ if (val instanceof Scriptable) {
+ val = ((Scriptable) val).getDefaultValue(StringClass);
+ if (val instanceof Scriptable) {
+ throw errorWithClassName("msg.primitive.expected", val);
+ }
+ continue;
+ }
+ return val.toString();
+ }
+ }
+
+ static String defaultObjectToString(Scriptable obj)
+ {
+ return "[object " + obj.getClassName() + ']';
+ }
+
+ public static String toString(Object[] args, int index)
+ {
+ return (index < args.length) ? toString(args[index]) : "undefined";
+ }
+
+ /**
+ * Optimized version of toString(Object) for numbers.
+ */
+ public static String toString(double val) {
+ return numberToString(val, 10);
+ }
+
+ public static String numberToString(double d, int base) {
+ if (d != d)
+ return "NaN";
+ if (d == Double.POSITIVE_INFINITY)
+ return "Infinity";
+ if (d == Double.NEGATIVE_INFINITY)
+ return "-Infinity";
+ if (d == 0.0)
+ return "0";
+
+ if ((base < 2) || (base > 36)) {
+ throw Context.reportRuntimeError1(
+ "msg.bad.radix", Integer.toString(base));
+ }
+
+ if (base != 10) {
+ return DToA.JS_dtobasestr(base, d);
+ } else {
+ StringBuffer result = new StringBuffer();
+ DToA.JS_dtostr(result, DToA.DTOSTR_STANDARD, 0, d);
+ return result.toString();
+ }
+
+ }
+
+ static String uneval(Context cx, Scriptable scope, Object value)
+ {
+ if (value == null) {
+ return "null";
+ }
+ if (value == Undefined.instance) {
+ return "undefined";
+ }
+ if (value instanceof String) {
+ String escaped = escapeString((String)value);
+ StringBuffer sb = new StringBuffer(escaped.length() + 2);
+ sb.append('\"');
+ sb.append(escaped);
+ sb.append('\"');
+ return sb.toString();
+ }
+ if (value instanceof Number) {
+ double d = ((Number)value).doubleValue();
+ if (d == 0 && 1 / d < 0) {
+ return "-0";
+ }
+ return toString(d);
+ }
+ if (value instanceof Boolean) {
+ return toString(value);
+ }
+ if (value instanceof Scriptable) {
+ Scriptable obj = (Scriptable)value;
+ // Wrapped Java objects won't have "toSource" and will report
+ // errors for get()s of nonexistent name, so use has() first
+ if (ScriptableObject.hasProperty(obj, "toSource")) {
+ Object v = ScriptableObject.getProperty(obj, "toSource");
+ if (v instanceof Function) {
+ Function f = (Function)v;
+ return toString(f.call(cx, scope, obj, emptyArgs));
+ }
+ }
+ return toString(value);
+ }
+ warnAboutNonJSObject(value);
+ return value.toString();
+ }
+
+ static String defaultObjectToSource(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ boolean toplevel, iterating;
+ if (cx.iterating == null) {
+ toplevel = true;
+ iterating = false;
+ cx.iterating = new ObjToIntMap(31);
+ } else {
+ toplevel = false;
+ iterating = cx.iterating.has(thisObj);
+ }
+
+ StringBuffer result = new StringBuffer(128);
+ if (toplevel) {
+ result.append("(");
+ }
+ result.append('{');
+
+ // Make sure cx.iterating is set to null when done
+ // so we don't leak memory
+ try {
+ if (!iterating) {
+ cx.iterating.intern(thisObj); // stop recursion.
+ Object[] ids = thisObj.getIds();
+ for (int i=0; i < ids.length; i++) {
+ Object id = ids[i];
+ Object value;
+ if (id instanceof Integer) {
+ int intId = ((Integer)id).intValue();
+ value = thisObj.get(intId, thisObj);
+ if (value == Scriptable.NOT_FOUND)
+ continue; // a property has been removed
+ if (i > 0)
+ result.append(", ");
+ result.append(intId);
+ } else {
+ String strId = (String)id;
+ value = thisObj.get(strId, thisObj);
+ if (value == Scriptable.NOT_FOUND)
+ continue; // a property has been removed
+ if (i > 0)
+ result.append(", ");
+ if (ScriptRuntime.isValidIdentifierName(strId)) {
+ result.append(strId);
+ } else {
+ result.append('\'');
+ result.append(
+ ScriptRuntime.escapeString(strId, '\''));
+ result.append('\'');
+ }
+ }
+ result.append(':');
+ result.append(ScriptRuntime.uneval(cx, scope, value));
+ }
+ }
+ } finally {
+ if (toplevel) {
+ cx.iterating = null;
+ }
+ }
+
+ result.append('}');
+ if (toplevel) {
+ result.append(')');
+ }
+ return result.toString();
+ }
+
+ public static Scriptable toObject(Scriptable scope, Object val)
+ {
+ if (val instanceof Scriptable) {
+ return (Scriptable)val;
+ }
+ return toObject(Context.getContext(), scope, val);
+ }
+
+ public static Scriptable toObjectOrNull(Context cx, Object obj)
+ {
+ if (obj instanceof Scriptable) {
+ return (Scriptable)obj;
+ } else if (obj != null && obj != Undefined.instance) {
+ return toObject(cx, getTopCallScope(cx), obj);
+ }
+ return null;
+ }
+
+ /**
+ * @deprecated Use {@link #toObject(Scriptable, Object)} instead.
+ */
+ public static Scriptable toObject(Scriptable scope, Object val,
+ Class staticClass)
+ {
+ if (val instanceof Scriptable) {
+ return (Scriptable)val;
+ }
+ return toObject(Context.getContext(), scope, val);
+ }
+
+ /**
+ * Convert the value to an object.
+ *
+ * See ECMA 9.9.
+ */
+ public static Scriptable toObject(Context cx, Scriptable scope, Object val)
+ {
+ if (val instanceof Scriptable) {
+ return (Scriptable) val;
+ }
+ if (val == null) {
+ throw typeError0("msg.null.to.object");
+ }
+ if (val == Undefined.instance) {
+ throw typeError0("msg.undef.to.object");
+ }
+ String className = val instanceof String ? "String" :
+ val instanceof Number ? "Number" :
+ val instanceof Boolean ? "Boolean" :
+ null;
+ if (className != null) {
+ Object[] args = { val };
+ scope = ScriptableObject.getTopLevelScope(scope);
+ return newObject(cx, scope, className, args);
+ }
+
+ // Extension: Wrap as a LiveConnect object.
+ Object wrapped = cx.getWrapFactory().wrap(cx, scope, val, null);
+ if (wrapped instanceof Scriptable)
+ return (Scriptable) wrapped;
+ throw errorWithClassName("msg.invalid.type", val);
+ }
+
+ /**
+ * @deprecated Use {@link #toObject(Context, Scriptable, Object)} instead.
+ */
+ public static Scriptable toObject(Context cx, Scriptable scope, Object val,
+ Class staticClass)
+ {
+ return toObject(cx, scope, val);
+ }
+
+ /**
+ * @deprecated The method is only present for compatibility.
+ */
+ public static Object call(Context cx, Object fun, Object thisArg,
+ Object[] args, Scriptable scope)
+ {
+ if (!(fun instanceof Function)) {
+ throw notFunctionError(toString(fun));
+ }
+ Function function = (Function)fun;
+ Scriptable thisObj = toObjectOrNull(cx, thisArg);
+ if (thisObj == null) {
+ throw undefCallError(thisObj, "function");
+ }
+ return function.call(cx, scope, thisObj, args);
+ }
+
+ public static Scriptable newObject(Context cx, Scriptable scope,
+ String constructorName, Object[] args)
+ {
+ scope = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
+ Function ctor = getExistingCtor(cx, scope, constructorName);
+ if (args == null) { args = ScriptRuntime.emptyArgs; }
+ return ctor.construct(cx, scope, args);
+ }
+
+ /**
+ *
+ * See ECMA 9.4.
+ */
+ public static double toInteger(Object val) {
+ return toInteger(toNumber(val));
+ }
+
+ // convenience method
+ public static double toInteger(double d) {
+ // if it's NaN
+ if (d != d)
+ return +0.0;
+
+ if (d == 0.0 ||
+ d == Double.POSITIVE_INFINITY ||
+ d == Double.NEGATIVE_INFINITY)
+ return d;
+
+ if (d > 0.0)
+ return Math.floor(d);
+ else
+ return Math.ceil(d);
+ }
+
+ public static double toInteger(Object[] args, int index) {
+ return (index < args.length) ? toInteger(args[index]) : +0.0;
+ }
+
+ /**
+ *
+ * See ECMA 9.5.
+ */
+ public static int toInt32(Object val)
+ {
+ // short circuit for common integer values
+ if (val instanceof Integer)
+ return ((Integer)val).intValue();
+
+ return toInt32(toNumber(val));
+ }
+
+ public static int toInt32(Object[] args, int index) {
+ return (index < args.length) ? toInt32(args[index]) : 0;
+ }
+
+ public static int toInt32(double d) {
+ int id = (int)d;
+ if (id == d) {
+ // This covers -0.0 as well
+ return id;
+ }
+
+ if (d != d
+ || d == Double.POSITIVE_INFINITY
+ || d == Double.NEGATIVE_INFINITY)
+ {
+ return 0;
+ }
+
+ d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
+
+ double two32 = 4294967296.0;
+ d = Math.IEEEremainder(d, two32);
+ // (double)(long)d == d should hold here
+
+ long l = (long)d;
+ // returning (int)d does not work as d can be outside int range
+ // but the result must always be 32 lower bits of l
+ return (int)l;
+ }
+
+ /**
+ * See ECMA 9.6.
+ * @return long value representing 32 bits unsigned integer
+ */
+ public static long toUint32(double d) {
+ long l = (long)d;
+ if (l == d) {
+ // This covers -0.0 as well
+ return l & 0xffffffffL;
+ }
+
+ if (d != d
+ || d == Double.POSITIVE_INFINITY
+ || d == Double.NEGATIVE_INFINITY)
+ {
+ return 0;
+ }
+
+ d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
+
+ // 0x100000000 gives me a numeric overflow...
+ double two32 = 4294967296.0;
+ l = (long)Math.IEEEremainder(d, two32);
+
+ return l & 0xffffffffL;
+ }
+
+ public static long toUint32(Object val) {
+ return toUint32(toNumber(val));
+ }
+
+ /**
+ *
+ * See ECMA 9.7.
+ */
+ public static char toUint16(Object val) {
+ double d = toNumber(val);
+
+ int i = (int)d;
+ if (i == d) {
+ return (char)i;
+ }
+
+ if (d != d
+ || d == Double.POSITIVE_INFINITY
+ || d == Double.NEGATIVE_INFINITY)
+ {
+ return 0;
+ }
+
+ d = (d >= 0) ? Math.floor(d) : Math.ceil(d);
+
+ int int16 = 0x10000;
+ i = (int)Math.IEEEremainder(d, int16);
+
+ return (char)i;
+ }
+
+ // XXX: this is until setDefaultNamespace will learn how to store NS
+ // properly and separates namespace form Scriptable.get etc.
+ private static final String DEFAULT_NS_TAG = "__default_namespace__";
+
+ public static Object setDefaultNamespace(Object namespace, Context cx)
+ {
+ Scriptable scope = cx.currentActivationCall;
+ if (scope == null) {
+ scope = getTopCallScope(cx);
+ }
+
+ XMLLib xmlLib = currentXMLLib(cx);
+ Object ns = xmlLib.toDefaultXmlNamespace(cx, namespace);
+
+ // XXX : this should be in separated namesapce from Scriptable.get/put
+ if (!scope.has(DEFAULT_NS_TAG, scope)) {
+ // XXX: this is racy of cause
+ ScriptableObject.defineProperty(scope, DEFAULT_NS_TAG, ns,
+ ScriptableObject.PERMANENT
+ | ScriptableObject.DONTENUM);
+ } else {
+ scope.put(DEFAULT_NS_TAG, scope, ns);
+ }
+
+ return Undefined.instance;
+ }
+
+ public static Object searchDefaultNamespace(Context cx)
+ {
+ Scriptable scope = cx.currentActivationCall;
+ if (scope == null) {
+ scope = getTopCallScope(cx);
+ }
+ Object nsObject;
+ for (;;) {
+ Scriptable parent = scope.getParentScope();
+ if (parent == null) {
+ nsObject = ScriptableObject.getProperty(scope, DEFAULT_NS_TAG);
+ if (nsObject == Scriptable.NOT_FOUND) {
+ return null;
+ }
+ break;
+ }
+ nsObject = scope.get(DEFAULT_NS_TAG, scope);
+ if (nsObject != Scriptable.NOT_FOUND) {
+ break;
+ }
+ scope = parent;
+ }
+ return nsObject;
+ }
+
+ public static Object getTopLevelProp(Scriptable scope, String id) {
+ scope = ScriptableObject.getTopLevelScope(scope);
+ return ScriptableObject.getProperty(scope, id);
+ }
+
+ static Function getExistingCtor(Context cx, Scriptable scope,
+ String constructorName)
+ {
+ Object ctorVal = ScriptableObject.getProperty(scope, constructorName);
+ if (ctorVal instanceof Function) {
+ return (Function)ctorVal;
+ }
+ if (ctorVal == Scriptable.NOT_FOUND) {
+ throw Context.reportRuntimeError1(
+ "msg.ctor.not.found", constructorName);
+ } else {
+ throw Context.reportRuntimeError1(
+ "msg.not.ctor", constructorName);
+ }
+ }
+
+ /**
+ * Return -1L if str is not an index or the index value as lower 32
+ * bits of the result.
+ */
+ private static long indexFromString(String str)
+ {
+ // The length of the decimal string representation of
+ // Integer.MAX_VALUE, 2147483647
+ final int MAX_VALUE_LENGTH = 10;
+
+ int len = str.length();
+ if (len > 0) {
+ int i = 0;
+ boolean negate = false;
+ int c = str.charAt(0);
+ if (c == '-') {
+ if (len > 1) {
+ c = str.charAt(1);
+ i = 1;
+ negate = true;
+ }
+ }
+ c -= '0';
+ if (0 <= c && c <= 9
+ && len <= (negate ? MAX_VALUE_LENGTH + 1 : MAX_VALUE_LENGTH))
+ {
+ // Use negative numbers to accumulate index to handle
+ // Integer.MIN_VALUE that is greater by 1 in absolute value
+ // then Integer.MAX_VALUE
+ int index = -c;
+ int oldIndex = 0;
+ i++;
+ if (index != 0) {
+ // Note that 00, 01, 000 etc. are not indexes
+ while (i != len && 0 <= (c = str.charAt(i) - '0') && c <= 9)
+ {
+ oldIndex = index;
+ index = 10 * index - c;
+ i++;
+ }
+ }
+ // Make sure all characters were consumed and that it couldn't
+ // have overflowed.
+ if (i == len &&
+ (oldIndex > (Integer.MIN_VALUE / 10) ||
+ (oldIndex == (Integer.MIN_VALUE / 10) &&
+ c <= (negate ? -(Integer.MIN_VALUE % 10)
+ : (Integer.MAX_VALUE % 10)))))
+ {
+ return 0xFFFFFFFFL & (negate ? index : -index);
+ }
+ }
+ }
+ return -1L;
+ }
+
+ /**
+ * If str is a decimal presentation of Uint32 value, return it as long.
+ * Othewise return -1L;
+ */
+ public static long testUint32String(String str)
+ {
+ // The length of the decimal string representation of
+ // UINT32_MAX_VALUE, 4294967296
+ final int MAX_VALUE_LENGTH = 10;
+
+ int len = str.length();
+ if (1 <= len && len <= MAX_VALUE_LENGTH) {
+ int c = str.charAt(0);
+ c -= '0';
+ if (c == 0) {
+ // Note that 00,01 etc. are not valid Uint32 presentations
+ return (len == 1) ? 0L : -1L;
+ }
+ if (1 <= c && c <= 9) {
+ long v = c;
+ for (int i = 1; i != len; ++i) {
+ c = str.charAt(i) - '0';
+ if (!(0 <= c && c <= 9)) {
+ return -1;
+ }
+ v = 10 * v + c;
+ }
+ // Check for overflow
+ if ((v >>> 32) == 0) {
+ return v;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * If s represents index, then return index value wrapped as Integer
+ * and othewise return s.
+ */
+ static Object getIndexObject(String s)
+ {
+ long indexTest = indexFromString(s);
+ if (indexTest >= 0) {
+ return new Integer((int)indexTest);
+ }
+ return s;
+ }
+
+ /**
+ * If d is exact int value, return its value wrapped as Integer
+ * and othewise return d converted to String.
+ */
+ static Object getIndexObject(double d)
+ {
+ int i = (int)d;
+ if (i == d) {
+ return new Integer(i);
+ }
+ return toString(d);
+ }
+
+ /**
+ * If toString(id) is a decimal presentation of int32 value, then id
+ * is index. In this case return null and make the index available
+ * as ScriptRuntime.lastIndexResult(cx). Otherwise return toString(id).
+ */
+ static String toStringIdOrIndex(Context cx, Object id)
+ {
+ if (id instanceof Number) {
+ double d = ((Number)id).doubleValue();
+ int index = (int)d;
+ if (index == d) {
+ storeIndexResult(cx, index);
+ return null;
+ }
+ return toString(id);
+ } else {
+ String s;
+ if (id instanceof String) {
+ s = (String)id;
+ } else {
+ s = toString(id);
+ }
+ long indexTest = indexFromString(s);
+ if (indexTest >= 0) {
+ storeIndexResult(cx, (int)indexTest);
+ return null;
+ }
+ return s;
+ }
+ }
+
+ /**
+ * Call obj.[[Get]](id)
+ */
+ public static Object getObjectElem(Object obj, Object elem, Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefReadError(obj, elem);
+ }
+ return getObjectElem(sobj, elem, cx);
+ }
+
+ public static Object getObjectElem(Scriptable obj, Object elem,
+ Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)obj;
+ return xmlObject.ecmaGet(cx, elem);
+ }
+
+ Object result;
+
+ String s = toStringIdOrIndex(cx, elem);
+ if (s == null) {
+ int index = lastIndexResult(cx);
+ result = ScriptableObject.getProperty(obj, index);
+ } else {
+ result = ScriptableObject.getProperty(obj, s);
+ }
+
+ if (result == Scriptable.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+
+ return result;
+ }
+
+ /**
+ * Version of getObjectElem when elem is a valid JS identifier name.
+ */
+ public static Object getObjectProp(Object obj, String property,
+ Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefReadError(obj, property);
+ }
+ return getObjectProp(sobj, property, cx);
+ }
+
+ public static Object getObjectProp(Scriptable obj, String property,
+ Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ // TODO: Change XMLObject to just use Scriptable interface
+ // to avoid paying cost of instanceof check on *every property
+ // lookup* !
+ XMLObject xmlObject = (XMLObject)obj;
+ return xmlObject.ecmaGet(cx, property);
+ }
+
+ Object result = ScriptableObject.getProperty(obj, property);
+ if (result == Scriptable.NOT_FOUND) {
+ if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) {
+ Context.reportWarning(ScriptRuntime.getMessage1(
+ "msg.ref.undefined.prop", property));
+ }
+ result = Undefined.instance;
+ }
+
+ return result;
+ }
+
+ public static Object getObjectPropNoWarn(Object obj, String property,
+ Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefReadError(obj, property);
+ }
+ if (obj instanceof XMLObject) {
+ // TODO: fix as mentioned in note in method above
+ getObjectProp(sobj, property, cx);
+ }
+ Object result = ScriptableObject.getProperty(sobj, property);
+ if (result == Scriptable.NOT_FOUND) {
+ return Undefined.instance;
+ }
+ return result;
+ }
+
+ /*
+ * A cheaper and less general version of the above for well-known argument
+ * types.
+ */
+ public static Object getObjectIndex(Object obj, double dblIndex,
+ Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefReadError(obj, toString(dblIndex));
+ }
+
+ int index = (int)dblIndex;
+ if (index == dblIndex) {
+ return getObjectIndex(sobj, index, cx);
+ } else {
+ String s = toString(dblIndex);
+ return getObjectProp(sobj, s, cx);
+ }
+ }
+
+ public static Object getObjectIndex(Scriptable obj, int index,
+ Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)obj;
+ return xmlObject.ecmaGet(cx, new Integer(index));
+ }
+
+ Object result = ScriptableObject.getProperty(obj, index);
+ if (result == Scriptable.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+
+ return result;
+ }
+
+ /*
+ * Call obj.[[Put]](id, value)
+ */
+ public static Object setObjectElem(Object obj, Object elem, Object value,
+ Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefWriteError(obj, elem, value);
+ }
+ return setObjectElem(sobj, elem, value, cx);
+ }
+
+ public static Object setObjectElem(Scriptable obj, Object elem,
+ Object value, Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)obj;
+ xmlObject.ecmaPut(cx, elem, value);
+ return value;
+ }
+
+ String s = toStringIdOrIndex(cx, elem);
+ if (s == null) {
+ int index = lastIndexResult(cx);
+ ScriptableObject.putProperty(obj, index, value);
+ } else {
+ ScriptableObject.putProperty(obj, s, value);
+ }
+
+ return value;
+ }
+
+ /**
+ * Version of setObjectElem when elem is a valid JS identifier name.
+ */
+ public static Object setObjectProp(Object obj, String property,
+ Object value, Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefWriteError(obj, property, value);
+ }
+ return setObjectProp(sobj, property, value, cx);
+ }
+
+ public static Object setObjectProp(Scriptable obj, String property,
+ Object value, Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)obj;
+ xmlObject.ecmaPut(cx, property, value);
+ } else {
+ ScriptableObject.putProperty(obj, property, value);
+ }
+ return value;
+ }
+
+ /*
+ * A cheaper and less general version of the above for well-known argument
+ * types.
+ */
+ public static Object setObjectIndex(Object obj, double dblIndex,
+ Object value, Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw undefWriteError(obj, String.valueOf(dblIndex), value);
+ }
+
+ int index = (int)dblIndex;
+ if (index == dblIndex) {
+ return setObjectIndex(sobj, index, value, cx);
+ } else {
+ String s = toString(dblIndex);
+ return setObjectProp(sobj, s, value, cx);
+ }
+ }
+
+ public static Object setObjectIndex(Scriptable obj, int index, Object value,
+ Context cx)
+ {
+ if (obj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)obj;
+ xmlObject.ecmaPut(cx, new Integer(index), value);
+ } else {
+ ScriptableObject.putProperty(obj, index, value);
+ }
+ return value;
+ }
+
+ public static boolean deleteObjectElem(Scriptable target, Object elem,
+ Context cx)
+ {
+ boolean result;
+ if (target instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)target;
+ result = xmlObject.ecmaDelete(cx, elem);
+ } else {
+ String s = toStringIdOrIndex(cx, elem);
+ if (s == null) {
+ int index = lastIndexResult(cx);
+ result = ScriptableObject.deleteProperty(target, index);
+ } else {
+ result = ScriptableObject.deleteProperty(target, s);
+ }
+ }
+ return result;
+ }
+
+ public static boolean hasObjectElem(Scriptable target, Object elem,
+ Context cx)
+ {
+ boolean result;
+
+ if (target instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)target;
+ result = xmlObject.ecmaHas(cx, elem);
+ } else {
+ String s = toStringIdOrIndex(cx, elem);
+ if (s == null) {
+ int index = lastIndexResult(cx);
+ result = ScriptableObject.hasProperty(target, index);
+ } else {
+ result = ScriptableObject.hasProperty(target, s);
+ }
+ }
+
+ return result;
+ }
+
+ public static Object refGet(Ref ref, Context cx)
+ {
+ return ref.get(cx);
+ }
+
+ public static Object refSet(Ref ref, Object value, Context cx)
+ {
+ return ref.set(cx, value);
+ }
+
+ public static Object refDel(Ref ref, Context cx)
+ {
+ return wrapBoolean(ref.delete(cx));
+ }
+
+ static boolean isSpecialProperty(String s)
+ {
+ return s.equals("__proto__") || s.equals("__parent__");
+ }
+
+ public static Ref specialRef(Object obj, String specialProperty,
+ Context cx)
+ {
+ return SpecialRef.createSpecial(cx, obj, specialProperty);
+ }
+
+ /**
+ * The delete operator
+ *
+ * See ECMA 11.4.1
+ *
+ * In ECMA 0.19, the description of the delete operator (11.4.1)
+ * assumes that the [[Delete]] method returns a value. However,
+ * the definition of the [[Delete]] operator (8.6.2.5) does not
+ * define a return value. Here we assume that the [[Delete]]
+ * method doesn't return a value.
+ */
+ public static Object delete(Object obj, Object id, Context cx)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ String idStr = (id == null) ? "null" : id.toString();
+ throw typeError2("msg.undef.prop.delete", toString(obj), idStr);
+ }
+ boolean result = deleteObjectElem(sobj, id, cx);
+ return wrapBoolean(result);
+ }
+
+ /**
+ * Looks up a name in the scope chain and returns its value.
+ */
+ public static Object name(Context cx, Scriptable scope, String name)
+ {
+ Scriptable parent = scope.getParentScope();
+ if (parent == null) {
+ Object result = topScopeName(cx, scope, name);
+ if (result == Scriptable.NOT_FOUND) {
+ throw notFoundError(scope, name);
+ }
+ return result;
+ }
+
+ return nameOrFunction(cx, scope, parent, name, false);
+ }
+
+ private static Object nameOrFunction(Context cx, Scriptable scope,
+ Scriptable parentScope, String name,
+ boolean asFunctionCall)
+ {
+ Object result;
+ Scriptable thisObj = scope; // It is used only if asFunctionCall==true.
+
+ XMLObject firstXMLObject = null;
+ for (;;) {
+ if (scope instanceof NativeWith) {
+ Scriptable withObj = scope.getPrototype();
+ if (withObj instanceof XMLObject) {
+ XMLObject xmlObj = (XMLObject)withObj;
+ if (xmlObj.ecmaHas(cx, name)) {
+ // function this should be the target object of with
+ thisObj = xmlObj;
+ result = xmlObj.ecmaGet(cx, name);
+ break;
+ }
+ if (firstXMLObject == null) {
+ firstXMLObject = xmlObj;
+ }
+ } else {
+ result = ScriptableObject.getProperty(withObj, name);
+ if (result != Scriptable.NOT_FOUND) {
+ // function this should be the target object of with
+ thisObj = withObj;
+ break;
+ }
+ }
+ } else if (scope instanceof NativeCall) {
+ // NativeCall does not prototype chain and Scriptable.get
+ // can be called directly.
+ result = scope.get(name, scope);
+ if (result != Scriptable.NOT_FOUND) {
+ if (asFunctionCall) {
+ // ECMA 262 requires that this for nested funtions
+ // should be top scope
+ thisObj = ScriptableObject.
+ getTopLevelScope(parentScope);
+ }
+ break;
+ }
+ } else {
+ // Can happen if Rhino embedding decided that nested
+ // scopes are useful for what ever reasons.
+ result = ScriptableObject.getProperty(scope, name);
+ if (result != Scriptable.NOT_FOUND) {
+ thisObj = scope;
+ break;
+ }
+ }
+ scope = parentScope;
+ parentScope = parentScope.getParentScope();
+ if (parentScope == null) {
+ result = topScopeName(cx, scope, name);
+ if (result == Scriptable.NOT_FOUND) {
+ if (firstXMLObject == null || asFunctionCall) {
+ throw notFoundError(scope, name);
+ }
+ // The name was not found, but we did find an XML
+ // object in the scope chain and we are looking for name,
+ // not function. The result should be an empty XMLList
+ // in name context.
+ result = firstXMLObject.ecmaGet(cx, name);
+ }
+ // For top scope thisObj for functions is always scope itself.
+ thisObj = scope;
+ break;
+ }
+ }
+
+ if (asFunctionCall) {
+ if (!(result instanceof Callable)) {
+ throw notFunctionError(result, name);
+ }
+ storeScriptable(cx, thisObj);
+ }
+
+ return result;
+ }
+
+ private static Object topScopeName(Context cx, Scriptable scope,
+ String name)
+ {
+ if (cx.useDynamicScope) {
+ scope = checkDynamicScope(cx.topCallScope, scope);
+ }
+ return ScriptableObject.getProperty(scope, name);
+ }
+
+
+ /**
+ * Returns the object in the scope chain that has a given property.
+ *
+ * The order of evaluation of an assignment expression involves
+ * evaluating the lhs to a reference, evaluating the rhs, and then
+ * modifying the reference with the rhs value. This method is used
+ * to 'bind' the given name to an object containing that property
+ * so that the side effects of evaluating the rhs do not affect
+ * which property is modified.
+ * Typically used in conjunction with setName.
+ *
+ * See ECMA 10.1.4
+ */
+ public static Scriptable bind(Context cx, Scriptable scope, String id)
+ {
+ Scriptable firstXMLObject = null;
+ Scriptable parent = scope.getParentScope();
+ childScopesChecks: if (parent != null) {
+ // Check for possibly nested "with" scopes first
+ while (scope instanceof NativeWith) {
+ Scriptable withObj = scope.getPrototype();
+ if (withObj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)withObj;
+ if (xmlObject.ecmaHas(cx, id)) {
+ return xmlObject;
+ }
+ if (firstXMLObject == null) {
+ firstXMLObject = xmlObject;
+ }
+ } else {
+ if (ScriptableObject.hasProperty(withObj, id)) {
+ return withObj;
+ }
+ }
+ scope = parent;
+ parent = parent.getParentScope();
+ if (parent == null) {
+ break childScopesChecks;
+ }
+ }
+ for (;;) {
+ if (ScriptableObject.hasProperty(scope, id)) {
+ return scope;
+ }
+ scope = parent;
+ parent = parent.getParentScope();
+ if (parent == null) {
+ break childScopesChecks;
+ }
+ }
+ }
+ // scope here is top scope
+ if (cx.useDynamicScope) {
+ scope = checkDynamicScope(cx.topCallScope, scope);
+ }
+ if (ScriptableObject.hasProperty(scope, id)) {
+ return scope;
+ }
+ // Nothing was found, but since XML objects always bind
+ // return one if found
+ return firstXMLObject;
+ }
+
+ public static Object setName(Scriptable bound, Object value,
+ Context cx, Scriptable scope, String id)
+ {
+ if (bound != null) {
+ if (bound instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)bound;
+ xmlObject.ecmaPut(cx, id, value);
+ } else {
+ ScriptableObject.putProperty(bound, id, value);
+ }
+ } else {
+ // "newname = 7;", where 'newname' has not yet
+ // been defined, creates a new property in the
+ // top scope unless strict mode is specified.
+ if (cx.hasFeature(Context.FEATURE_STRICT_MODE) ||
+ cx.hasFeature(Context.FEATURE_STRICT_VARS))
+ {
+ Context.reportWarning(
+ ScriptRuntime.getMessage1("msg.assn.create.strict", id));
+ }
+ // Find the top scope by walking up the scope chain.
+ bound = ScriptableObject.getTopLevelScope(scope);
+ if (cx.useDynamicScope) {
+ bound = checkDynamicScope(cx.topCallScope, bound);
+ }
+ bound.put(id, bound, value);
+ }
+ return value;
+ }
+
+ public static Object setConst(Scriptable bound, Object value,
+ Context cx, String id)
+ {
+ if (bound instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)bound;
+ xmlObject.ecmaPut(cx, id, value);
+ } else {
+ ScriptableObject.putConstProperty(bound, id, value);
+ }
+ return value;
+ }
+
+ /**
+ * This is the enumeration needed by the for..in statement.
+ *
+ * See ECMA 12.6.3.
+ *
+ * IdEnumeration maintains a ObjToIntMap to make sure a given
+ * id is enumerated only once across multiple objects in a
+ * prototype chain.
+ *
+ * XXX - ECMA delete doesn't hide properties in the prototype,
+ * but js/ref does. This means that the js/ref for..in can
+ * avoid maintaining a hash table and instead perform lookups
+ * to see if a given property has already been enumerated.
+ *
+ */
+ private static class IdEnumeration implements Serializable
+ {
+ private static final long serialVersionUID = 1L;
+ Scriptable obj;
+ Object[] ids;
+ int index;
+ ObjToIntMap used;
+ Object currentId;
+ int enumType; /* one of ENUM_INIT_KEYS, ENUM_INIT_VALUES,
+ ENUM_INIT_ARRAY */
+
+ // if true, integer ids will be returned as numbers rather than strings
+ boolean enumNumbers;
+
+ Scriptable iterator;
+ }
+
+ public static Scriptable toIterator(Context cx, Scriptable scope,
+ Scriptable obj, boolean keyOnly)
+ {
+ /*APPJET 1.6*//*
+ if (ScriptableObject.hasProperty(obj,
+ NativeIterator.ITERATOR_PROPERTY_NAME))
+ {
+ Object v = ScriptableObject.getProperty(obj,
+ NativeIterator.ITERATOR_PROPERTY_NAME);
+ if (!(v instanceof Callable)) {
+ throw typeError0("msg.invalid.iterator");
+ }
+ Callable f = (Callable) v;
+ Object[] args = new Object[] { keyOnly ? Boolean.TRUE
+ : Boolean.FALSE };
+ v = f.call(cx, scope, obj, args);
+ if (!(v instanceof Scriptable)) {
+ throw typeError0("msg.iterator.primitive");
+ }
+ return (Scriptable) v;
+ }*/
+ return null;
+ }
+
+ // for backwards compatibility with generated class files
+ public static Object enumInit(Object value, Context cx, boolean enumValues)
+ {
+ return enumInit(value, cx, enumValues ? ENUMERATE_VALUES
+ : ENUMERATE_KEYS);
+ }
+
+ public static final int ENUMERATE_KEYS = 0;
+ public static final int ENUMERATE_VALUES = 1;
+ public static final int ENUMERATE_ARRAY = 2;
+ public static final int ENUMERATE_KEYS_NO_ITERATOR = 3;
+ public static final int ENUMERATE_VALUES_NO_ITERATOR = 4;
+ public static final int ENUMERATE_ARRAY_NO_ITERATOR = 5;
+
+ public static Object enumInit(Object value, Context cx, int enumType)
+ {
+ IdEnumeration x = new IdEnumeration();
+ x.obj = toObjectOrNull(cx, value);
+ if (x.obj == null) {
+ // null or undefined do not cause errors but rather lead to empty
+ // "for in" loop
+ return x;
+ }
+ x.enumType = enumType;
+ x.iterator = null;
+ if (enumType != ENUMERATE_KEYS_NO_ITERATOR &&
+ enumType != ENUMERATE_VALUES_NO_ITERATOR &&
+ enumType != ENUMERATE_ARRAY_NO_ITERATOR)
+ {
+ x.iterator = toIterator(cx, x.obj.getParentScope(), x.obj, true);
+ }
+ if (x.iterator == null) {
+ // enumInit should read all initial ids before returning
+ // or "for (a.i in a)" would wrongly enumerate i in a as well
+ enumChangeObject(x);
+ }
+
+ return x;
+ }
+
+ public static void setEnumNumbers(Object enumObj, boolean enumNumbers) {
+ ((IdEnumeration)enumObj).enumNumbers = enumNumbers;
+ }
+
+ public static Boolean enumNext(Object enumObj)
+ {
+ IdEnumeration x = (IdEnumeration)enumObj;
+ if (x.iterator != null) {
+ Object v = ScriptableObject.getProperty(x.iterator, "next");
+ if (!(v instanceof Callable))
+ return Boolean.FALSE;
+ Callable f = (Callable) v;
+ Context cx = Context.enter();
+ try {
+ x.currentId = f.call(cx, x.iterator.getParentScope(),
+ x.iterator, emptyArgs);
+ return Boolean.TRUE;
+ } catch (JavaScriptException e) {
+ if (e.getValue() instanceof NativeIterator.StopIteration) {
+ return Boolean.FALSE;
+ }
+ throw e;
+ } finally {
+ Context.exit();
+ }
+ }
+ for (;;) {
+ if (x.obj == null) {
+ return Boolean.FALSE;
+ }
+ if (x.index == x.ids.length) {
+ x.obj = x.obj.getPrototype();
+ enumChangeObject(x);
+ continue;
+ }
+ Object id = x.ids[x.index++];
+ if (x.used != null && x.used.has(id)) {
+ continue;
+ }
+ if (id instanceof String) {
+ String strId = (String)id;
+ if (!x.obj.has(strId, x.obj))
+ continue; // must have been deleted
+ x.currentId = strId;
+ } else {
+ int intId = ((Number)id).intValue();
+ if (!x.obj.has(intId, x.obj))
+ continue; // must have been deleted
+ x.currentId = x.enumNumbers ? (Object) (new Integer(intId))
+ : String.valueOf(intId);
+ }
+ return Boolean.TRUE;
+ }
+ }
+
+ public static Object enumId(Object enumObj, Context cx)
+ {
+ IdEnumeration x = (IdEnumeration)enumObj;
+ if (x.iterator != null) {
+ return x.currentId;
+ }
+ switch (x.enumType) {
+ case ENUMERATE_KEYS:
+ case ENUMERATE_KEYS_NO_ITERATOR:
+ return x.currentId;
+ case ENUMERATE_VALUES:
+ case ENUMERATE_VALUES_NO_ITERATOR:
+ return enumValue(enumObj, cx);
+ case ENUMERATE_ARRAY:
+ case ENUMERATE_ARRAY_NO_ITERATOR:
+ Object[] elements = { x.currentId, enumValue(enumObj, cx) };
+ return cx.newArray(x.obj.getParentScope(), elements);
+ default:
+ throw Kit.codeBug();
+ }
+ }
+
+ public static Object enumValue(Object enumObj, Context cx) {
+ IdEnumeration x = (IdEnumeration)enumObj;
+
+ Object result;
+
+ String s = toStringIdOrIndex(cx, x.currentId);
+ if (s == null) {
+ int index = lastIndexResult(cx);
+ result = x.obj.get(index, x.obj);
+ } else {
+ result = x.obj.get(s, x.obj);
+ }
+
+ return result;
+ }
+
+ private static void enumChangeObject(IdEnumeration x)
+ {
+ Object[] ids = null;
+ while (x.obj != null) {
+ ids = x.obj.getIds();
+ if (ids.length != 0) {
+ break;
+ }
+ x.obj = x.obj.getPrototype();
+ }
+ if (x.obj != null && x.ids != null) {
+ Object[] previous = x.ids;
+ int L = previous.length;
+ if (x.used == null) {
+ x.used = new ObjToIntMap(L);
+ }
+ for (int i = 0; i != L; ++i) {
+ x.used.intern(previous[i]);
+ }
+ }
+ x.ids = ids;
+ x.index = 0;
+ }
+
+ /**
+ * Prepare for calling name(...): return function corresponding to
+ * name and make current top scope available
+ * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
+ * The caller must call ScriptRuntime.lastStoredScriptable() immediately
+ * after calling this method.
+ */
+ public static Callable getNameFunctionAndThis(String name,
+ Context cx,
+ Scriptable scope)
+ {
+ Scriptable parent = scope.getParentScope();
+ if (parent == null) {
+ Object result = topScopeName(cx, scope, name);
+ if (!(result instanceof Callable)) {
+ if (result == Scriptable.NOT_FOUND) {
+ throw notFoundError(scope, name);
+ } else {
+ throw notFunctionError(result, name);
+ }
+ }
+ // Top scope is not NativeWith or NativeCall => thisObj == scope
+ Scriptable thisObj = scope;
+ storeScriptable(cx, thisObj);
+ return (Callable)result;
+ }
+
+ // name will call storeScriptable(cx, thisObj);
+ return (Callable)nameOrFunction(cx, scope, parent, name, true);
+ }
+
+ /**
+ * Prepare for calling obj[id](...): return function corresponding to
+ * obj[id] and make obj properly converted to Scriptable available
+ * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
+ * The caller must call ScriptRuntime.lastStoredScriptable() immediately
+ * after calling this method.
+ */
+ public static Callable getElemFunctionAndThis(Object obj,
+ Object elem,
+ Context cx)
+ {
+ String s = toStringIdOrIndex(cx, elem);
+ if (s != null) {
+ return getPropFunctionAndThis(obj, s, cx);
+ }
+ int index = lastIndexResult(cx);
+
+ Scriptable thisObj = toObjectOrNull(cx, obj);
+ if (thisObj == null) {
+ throw undefCallError(obj, String.valueOf(index));
+ }
+
+ Object value;
+ for (;;) {
+ // Ignore XML lookup as requred by ECMA 357, 11.2.2.1
+ value = ScriptableObject.getProperty(thisObj, index);
+ if (value != Scriptable.NOT_FOUND) {
+ break;
+ }
+ if (!(thisObj instanceof XMLObject)) {
+ break;
+ }
+ XMLObject xmlObject = (XMLObject)thisObj;
+ Scriptable extra = xmlObject.getExtraMethodSource(cx);
+ if (extra == null) {
+ break;
+ }
+ thisObj = extra;
+ }
+ if (!(value instanceof Callable)) {
+ throw notFunctionError(value, elem);
+ }
+
+ storeScriptable(cx, thisObj);
+ return (Callable)value;
+ }
+
+ /**
+ * Prepare for calling obj.property(...): return function corresponding to
+ * obj.property and make obj properly converted to Scriptable available
+ * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
+ * The caller must call ScriptRuntime.lastStoredScriptable() immediately
+ * after calling this method.
+ */
+ public static Callable getPropFunctionAndThis(Object obj,
+ String property,
+ Context cx)
+ {
+ Scriptable thisObj = toObjectOrNull(cx, obj);
+ if (thisObj == null) {
+ throw undefCallError(obj, property);
+ }
+
+ Object value;
+ for (;;) {
+ // Ignore XML lookup as required by ECMA 357, 11.2.2.1
+ value = ScriptableObject.getProperty(thisObj, property);
+ if (value != Scriptable.NOT_FOUND) {
+ break;
+ }
+ if (!(thisObj instanceof XMLObject)) {
+ break;
+ }
+ XMLObject xmlObject = (XMLObject)thisObj;
+ Scriptable extra = xmlObject.getExtraMethodSource(cx);
+ if (extra == null) {
+ break;
+ }
+ thisObj = extra;
+ }
+
+ if (!(value instanceof Callable)) {
+ Object noSuchMethod = ScriptableObject.getProperty(thisObj, "__noSuchMethod__");
+ if (noSuchMethod instanceof Callable)
+ value = new NoSuchMethodShim((Callable)noSuchMethod, property);
+ else
+ throw notFunctionError(thisObj, value, property);
+ }
+
+ storeScriptable(cx, thisObj);
+ return (Callable)value;
+ }
+
+ /**
+ * Prepare for calling <expression>(...): return function corresponding to
+ * <expression> and make parent scope of the function available
+ * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.
+ * The caller must call ScriptRuntime.lastStoredScriptable() immediately
+ * after calling this method.
+ */
+ public static Callable getValueFunctionAndThis(Object value, Context cx)
+ {
+ if (!(value instanceof Callable)) {
+ throw notFunctionError(value);
+ }
+
+ Callable f = (Callable)value;
+ Scriptable thisObj = null;
+ if (f instanceof Scriptable) {
+ thisObj = ((Scriptable)f).getParentScope();
+ }
+ if (thisObj == null) {
+ if (cx.topCallScope == null) throw new IllegalStateException();
+ thisObj = cx.topCallScope;
+ }
+ if (thisObj.getParentScope() != null) {
+ if (thisObj instanceof NativeWith) {
+ // functions defined inside with should have with target
+ // as their thisObj
+ } else if (thisObj instanceof NativeCall) {
+ // nested functions should have top scope as their thisObj
+ thisObj = ScriptableObject.getTopLevelScope(thisObj);
+ }
+ }
+ storeScriptable(cx, thisObj);
+ return f;
+ }
+
+ /**
+ * Perform function call in reference context. Should always
+ * return value that can be passed to
+ * {@link #refGet(Ref, Context)} or {@link #refSet(Ref, Object, Context)}
+ * arbitrary number of times.
+ * The args array reference should not be stored in any object that is
+ * can be GC-reachable after this method returns. If this is necessary,
+ * store args.clone(), not args array itself.
+ */
+ public static Ref callRef(Callable function, Scriptable thisObj,
+ Object[] args, Context cx)
+ {
+ if (function instanceof RefCallable) {
+ RefCallable rfunction = (RefCallable)function;
+ Ref ref = rfunction.refCall(cx, thisObj, args);
+ if (ref == null) {
+ throw new IllegalStateException(rfunction.getClass().getName()+".refCall() returned null");
+ }
+ return ref;
+ }
+ // No runtime support for now
+ String msg = getMessage1("msg.no.ref.from.function",
+ toString(function));
+ throw constructError("ReferenceError", msg);
+ }
+
+ /**
+ * Operator new.
+ *
+ * See ECMA 11.2.2
+ */
+ public static Scriptable newObject(Object fun, Context cx,
+ Scriptable scope, Object[] args)
+ {
+ if (!(fun instanceof Function)) {
+ throw notFunctionError(fun);
+ }
+ Function function = (Function)fun;
+ return function.construct(cx, scope, args);
+ }
+
+ public static Object callSpecial(Context cx, Callable fun,
+ Scriptable thisObj,
+ Object[] args, Scriptable scope,
+ Scriptable callerThis, int callType,
+ String filename, int lineNumber)
+ {
+ if (callType == Node.SPECIALCALL_EVAL) {
+ if (NativeGlobal.isEvalFunction(fun)) {
+ return evalSpecial(cx, scope, callerThis, args,
+ filename, lineNumber);
+ }
+ } else if (callType == Node.SPECIALCALL_WITH) {
+ if (NativeWith.isWithFunction(fun)) {
+ throw Context.reportRuntimeError1("msg.only.from.new",
+ "With");
+ }
+ } else {
+ throw Kit.codeBug();
+ }
+
+ return fun.call(cx, scope, thisObj, args);
+ }
+
+ public static Object newSpecial(Context cx, Object fun,
+ Object[] args, Scriptable scope,
+ int callType)
+ {
+ if (callType == Node.SPECIALCALL_EVAL) {
+ if (NativeGlobal.isEvalFunction(fun)) {
+ throw typeError1("msg.not.ctor", "eval");
+ }
+ } else if (callType == Node.SPECIALCALL_WITH) {
+ if (NativeWith.isWithFunction(fun)) {
+ return NativeWith.newWithSpecial(cx, scope, args);
+ }
+ } else {
+ throw Kit.codeBug();
+ }
+
+ return newObject(fun, cx, scope, args);
+ }
+
+ /**
+ * Function.prototype.apply and Function.prototype.call
+ *
+ * See Ecma 15.3.4.[34]
+ */
+ public static Object applyOrCall(boolean isApply,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ int L = args.length;
+ Callable function = getCallable(thisObj);
+
+ Scriptable callThis = null;
+ if (L != 0) {
+ callThis = toObjectOrNull(cx, args[0]);
+ }
+ if (callThis == null) {
+ // This covers the case of args[0] == (null|undefined) as well.
+ callThis = getTopCallScope(cx);
+ }
+
+ Object[] callArgs;
+ if (isApply) {
+ // Follow Ecma 15.3.4.3
+ callArgs = L <= 1 ? ScriptRuntime.emptyArgs :
+ getApplyArguments(cx, args[1]);
+ } else {
+ // Follow Ecma 15.3.4.4
+ if (L <= 1) {
+ callArgs = ScriptRuntime.emptyArgs;
+ } else {
+ callArgs = new Object[L - 1];
+ System.arraycopy(args, 1, callArgs, 0, L - 1);
+ }
+ }
+
+ return function.call(cx, scope, callThis, callArgs);
+ }
+
+ static Object[] getApplyArguments(Context cx, Object arg1)
+ {
+ if (arg1 == null || arg1 == Undefined.instance) {
+ return ScriptRuntime.emptyArgs;
+ } else if (arg1 instanceof NativeArray || arg1 instanceof Arguments) {
+ return cx.getElements((Scriptable) arg1);
+ } else {
+ throw ScriptRuntime.typeError0("msg.arg.isnt.array");
+ }
+ }
+
+ static Callable getCallable(Scriptable thisObj)
+ {
+ Callable function;
+ if (thisObj instanceof Callable) {
+ function = (Callable)thisObj;
+ } else {
+ Object value = thisObj.getDefaultValue(ScriptRuntime.FunctionClass);
+ if (!(value instanceof Callable)) {
+ throw ScriptRuntime.notFunctionError(value, thisObj);
+ }
+ function = (Callable)value;
+ }
+ return function;
+ }
+
+ /**
+ * The eval function property of the global object.
+ *
+ * See ECMA 15.1.2.1
+ */
+ public static Object evalSpecial(Context cx, Scriptable scope,
+ Object thisArg, Object[] args,
+ String filename, int lineNumber)
+ {
+ if (args.length < 1)
+ return Undefined.instance;
+ Object x = args[0];
+ if (!(x instanceof String)) {
+ if (cx.hasFeature(Context.FEATURE_STRICT_MODE) ||
+ cx.hasFeature(Context.FEATURE_STRICT_EVAL))
+ {
+ throw Context.reportRuntimeError0("msg.eval.nonstring.strict");
+ }
+ String message = ScriptRuntime.getMessage0("msg.eval.nonstring");
+ Context.reportWarning(message);
+ return x;
+ }
+ if (filename == null) {
+ int[] linep = new int[1];
+ filename = Context.getSourcePositionFromStack(linep);
+ if (filename != null) {
+ lineNumber = linep[0];
+ } else {
+ filename = "";
+ }
+ }
+ String sourceName = ScriptRuntime.
+ makeUrlForGeneratedScript(true, filename, lineNumber);
+
+ ErrorReporter reporter;
+ reporter = DefaultErrorReporter.forEval(cx.getErrorReporter());
+
+ Evaluator evaluator = Context.createInterpreter();
+ if (evaluator == null) {
+ throw new JavaScriptException("Interpreter not present",
+ filename, lineNumber);
+ }
+
+ // Compile with explicit interpreter instance to force interpreter
+ // mode.
+ Script script = cx.compileString((String)x, evaluator,
+ reporter, sourceName, 1, null);
+ evaluator.setEvalScriptFlag(script);
+ Callable c = (Callable)script;
+ return c.call(cx, scope, (Scriptable)thisArg, ScriptRuntime.emptyArgs);
+ }
+
+ /**
+ * The typeof operator
+ */
+ public static String typeof(Object value)
+ {
+ if (value == null)
+ return "object";
+ if (value == Undefined.instance)
+ return "undefined";
+ if (value instanceof Scriptable)
+ {
+ if (value instanceof ScriptableObject &&
+ ((ScriptableObject)value).avoidObjectDetection())
+ {
+ return "undefined";
+ }
+ if (value instanceof XMLObject)
+ return "xml";
+ return (value instanceof Callable) ? "function" : "object";
+ }
+ if (value instanceof String)
+ return "string";
+ if (value instanceof Number)
+ return "number";
+ if (value instanceof Boolean)
+ return "boolean";
+ throw errorWithClassName("msg.invalid.type", value);
+ }
+
+ /**
+ * The typeof operator that correctly handles the undefined case
+ */
+ public static String typeofName(Scriptable scope, String id)
+ {
+ Context cx = Context.getContext();
+ Scriptable val = bind(cx, scope, id);
+ if (val == null)
+ return "undefined";
+ return typeof(getObjectProp(val, id, cx));
+ }
+
+ // neg:
+ // implement the '-' operator inline in the caller
+ // as "-toNumber(val)"
+
+ // not:
+ // implement the '!' operator inline in the caller
+ // as "!toBoolean(val)"
+
+ // bitnot:
+ // implement the '~' operator inline in the caller
+ // as "~toInt32(val)"
+
+ public static Object add(Object val1, Object val2, Context cx)
+ {
+ if(val1 instanceof Number && val2 instanceof Number) {
+ return wrapNumber(((Number)val1).doubleValue() +
+ ((Number)val2).doubleValue());
+ }
+ if (val1 instanceof XMLObject) {
+ Object test = ((XMLObject)val1).addValues(cx, true, val2);
+ if (test != Scriptable.NOT_FOUND) {
+ return test;
+ }
+ }
+ if (val2 instanceof XMLObject) {
+ Object test = ((XMLObject)val2).addValues(cx, false, val1);
+ if (test != Scriptable.NOT_FOUND) {
+ return test;
+ }
+ }
+ if (val1 instanceof Scriptable)
+ val1 = ((Scriptable) val1).getDefaultValue(null);
+ if (val2 instanceof Scriptable)
+ val2 = ((Scriptable) val2).getDefaultValue(null);
+ if (!(val1 instanceof String) && !(val2 instanceof String))
+ if ((val1 instanceof Number) && (val2 instanceof Number))
+ return wrapNumber(((Number)val1).doubleValue() +
+ ((Number)val2).doubleValue());
+ else
+ return wrapNumber(toNumber(val1) + toNumber(val2));
+ return toString(val1).concat(toString(val2));
+ }
+
+ public static String add(String val1, Object val2) {
+ return val1.concat(toString(val2));
+ }
+
+ public static String add(Object val1, String val2) {
+ return toString(val1).concat(val2);
+ }
+
+ /**
+ * @deprecated The method is only present for compatibility.
+ */
+ public static Object nameIncrDecr(Scriptable scopeChain, String id,
+ int incrDecrMask)
+ {
+ return nameIncrDecr(scopeChain, id, Context.getContext(), incrDecrMask);
+ }
+
+ public static Object nameIncrDecr(Scriptable scopeChain, String id,
+ Context cx, int incrDecrMask)
+ {
+ Scriptable target;
+ Object value;
+ search: {
+ do {
+ if (cx.useDynamicScope && scopeChain.getParentScope() == null) {
+ scopeChain = checkDynamicScope(cx.topCallScope, scopeChain);
+ }
+ target = scopeChain;
+ do {
+ value = target.get(id, scopeChain);
+ if (value != Scriptable.NOT_FOUND) {
+ break search;
+ }
+ target = target.getPrototype();
+ } while (target != null);
+ scopeChain = scopeChain.getParentScope();
+ } while (scopeChain != null);
+ throw notFoundError(scopeChain, id);
+ }
+ return doScriptableIncrDecr(target, id, scopeChain, value,
+ incrDecrMask);
+ }
+
+ public static Object propIncrDecr(Object obj, String id,
+ Context cx, int incrDecrMask)
+ {
+ Scriptable start = toObjectOrNull(cx, obj);
+ if (start == null) {
+ throw undefReadError(obj, id);
+ }
+
+ Scriptable target = start;
+ Object value;
+ search: {
+ do {
+ value = target.get(id, start);
+ if (value != Scriptable.NOT_FOUND) {
+ break search;
+ }
+ target = target.getPrototype();
+ } while (target != null);
+ start.put(id, start, NaNobj);
+ return NaNobj;
+ }
+ return doScriptableIncrDecr(target, id, start, value,
+ incrDecrMask);
+ }
+
+ private static Object doScriptableIncrDecr(Scriptable target,
+ String id,
+ Scriptable protoChainStart,
+ Object value,
+ int incrDecrMask)
+ {
+ boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
+ double number;
+ if (value instanceof Number) {
+ number = ((Number)value).doubleValue();
+ } else {
+ number = toNumber(value);
+ if (post) {
+ // convert result to number
+ value = wrapNumber(number);
+ }
+ }
+ if ((incrDecrMask & Node.DECR_FLAG) == 0) {
+ ++number;
+ } else {
+ --number;
+ }
+ Number result = wrapNumber(number);
+ target.put(id, protoChainStart, result);
+ if (post) {
+ return value;
+ } else {
+ return result;
+ }
+ }
+
+ public static Object elemIncrDecr(Object obj, Object index,
+ Context cx, int incrDecrMask)
+ {
+ Object value = getObjectElem(obj, index, cx);
+ boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
+ double number;
+ if (value instanceof Number) {
+ number = ((Number)value).doubleValue();
+ } else {
+ number = toNumber(value);
+ if (post) {
+ // convert result to number
+ value = wrapNumber(number);
+ }
+ }
+ if ((incrDecrMask & Node.DECR_FLAG) == 0) {
+ ++number;
+ } else {
+ --number;
+ }
+ Number result = wrapNumber(number);
+ setObjectElem(obj, index, result, cx);
+ if (post) {
+ return value;
+ } else {
+ return result;
+ }
+ }
+
+ public static Object refIncrDecr(Ref ref, Context cx, int incrDecrMask)
+ {
+ Object value = ref.get(cx);
+ boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
+ double number;
+ if (value instanceof Number) {
+ number = ((Number)value).doubleValue();
+ } else {
+ number = toNumber(value);
+ if (post) {
+ // convert result to number
+ value = wrapNumber(number);
+ }
+ }
+ if ((incrDecrMask & Node.DECR_FLAG) == 0) {
+ ++number;
+ } else {
+ --number;
+ }
+ Number result = wrapNumber(number);
+ ref.set(cx, result);
+ if (post) {
+ return value;
+ } else {
+ return result;
+ }
+ }
+
+ private static Object toPrimitive(Object val)
+ {
+ if (!(val instanceof Scriptable)) {
+ return val;
+ }
+ Scriptable s = (Scriptable)val;
+ Object result = s.getDefaultValue(null);
+ if (result instanceof Scriptable)
+ throw typeError0("msg.bad.default.value");
+ return result;
+ }
+
+ /**
+ * Equality
+ *
+ * See ECMA 11.9
+ */
+ public static boolean eq(Object x, Object y)
+ {
+ if (x == null || x == Undefined.instance) {
+ if (y == null || y == Undefined.instance) {
+ return true;
+ }
+ if (y instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)y).equivalentValues(x);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ return false;
+ } else if (x instanceof Number) {
+ return eqNumber(((Number)x).doubleValue(), y);
+ } else if (x instanceof String) {
+ return eqString((String)x, y);
+ } else if (x instanceof Boolean) {
+ boolean b = ((Boolean)x).booleanValue();
+ if (y instanceof Boolean) {
+ return b == ((Boolean)y).booleanValue();
+ }
+ if (y instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)y).equivalentValues(x);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ return eqNumber(b ? 1.0 : 0.0, y);
+ } else if (x instanceof Scriptable) {
+ if (y instanceof Scriptable) {
+ if (x == y) {
+ return true;
+ }
+ if (x instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)x).equivalentValues(y);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ if (y instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)y).equivalentValues(x);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ if (x instanceof Wrapper && y instanceof Wrapper) {
+ // See bug 413838. Effectively an extension to ECMA for
+ // the LiveConnect case.
+ Object unwrappedX = ((Wrapper)x).unwrap();
+ Object unwrappedY = ((Wrapper)y).unwrap();
+ return unwrappedX == unwrappedY ||
+ (isPrimitive(unwrappedX) &&
+ isPrimitive(unwrappedY) &&
+ eq(unwrappedX, unwrappedY));
+ }
+ return false;
+ } else if (y instanceof Boolean) {
+ if (x instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)x).equivalentValues(y);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ double d = ((Boolean)y).booleanValue() ? 1.0 : 0.0;
+ return eqNumber(d, x);
+ } else if (y instanceof Number) {
+ return eqNumber(((Number)y).doubleValue(), x);
+ } else if (y instanceof String) {
+ return eqString((String)y, x);
+ }
+ // covers the case when y == Undefined.instance as well
+ return false;
+ } else {
+ warnAboutNonJSObject(x);
+ return x == y;
+ }
+ }
+
+ private static boolean isPrimitive(Object obj) {
+ return (obj instanceof Number) || (obj instanceof String) ||
+ (obj instanceof Boolean);
+ }
+
+ static boolean eqNumber(double x, Object y)
+ {
+ for (;;) {
+ if (y == null || y == Undefined.instance) {
+ return false;
+ } else if (y instanceof Number) {
+ return x == ((Number)y).doubleValue();
+ } else if (y instanceof String) {
+ return x == toNumber(y);
+ } else if (y instanceof Boolean) {
+ return x == (((Boolean)y).booleanValue() ? 1.0 : +0.0);
+ } else if (y instanceof Scriptable) {
+ if (y instanceof ScriptableObject) {
+ Object xval = wrapNumber(x);
+ Object test = ((ScriptableObject)y).equivalentValues(xval);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ y = toPrimitive(y);
+ } else {
+ warnAboutNonJSObject(y);
+ return false;
+ }
+ }
+ }
+
+ private static boolean eqString(String x, Object y)
+ {
+ for (;;) {
+ if (y == null || y == Undefined.instance) {
+ return false;
+ } else if (y instanceof String) {
+ return x.equals(y);
+ } else if (y instanceof Number) {
+ return toNumber(x) == ((Number)y).doubleValue();
+ } else if (y instanceof Boolean) {
+ return toNumber(x) == (((Boolean)y).booleanValue() ? 1.0 : 0.0);
+ } else if (y instanceof Scriptable) {
+ if (y instanceof ScriptableObject) {
+ Object test = ((ScriptableObject)y).equivalentValues(x);
+ if (test != Scriptable.NOT_FOUND) {
+ return ((Boolean)test).booleanValue();
+ }
+ }
+ y = toPrimitive(y);
+ continue;
+ } else {
+ warnAboutNonJSObject(y);
+ return false;
+ }
+ }
+ }
+ public static boolean shallowEq(Object x, Object y)
+ {
+ if (x == y) {
+ if (!(x instanceof Number)) {
+ return true;
+ }
+ // NaN check
+ double d = ((Number)x).doubleValue();
+ return d == d;
+ }
+ if (x == null || x == Undefined.instance) {
+ return false;
+ } else if (x instanceof Number) {
+ if (y instanceof Number) {
+ return ((Number)x).doubleValue() == ((Number)y).doubleValue();
+ }
+ } else if (x instanceof String) {
+ if (y instanceof String) {
+ return x.equals(y);
+ }
+ } else if (x instanceof Boolean) {
+ if (y instanceof Boolean) {
+ return x.equals(y);
+ }
+ } else if (x instanceof Scriptable) {
+ if (x instanceof Wrapper && y instanceof Wrapper) {
+ return ((Wrapper)x).unwrap() == ((Wrapper)y).unwrap();
+ }
+ } else {
+ warnAboutNonJSObject(x);
+ return x == y;
+ }
+ return false;
+ }
+
+ /**
+ * The instanceof operator.
+ *
+ * @return a instanceof b
+ */
+ public static boolean instanceOf(Object a, Object b, Context cx)
+ {
+ // Check RHS is an object
+ if (! (b instanceof Scriptable)) {
+ throw typeError0("msg.instanceof.not.object");
+ }
+
+ // for primitive values on LHS, return false
+ // XXX we may want to change this so that
+ // 5 instanceof Number == true
+ if (! (a instanceof Scriptable))
+ return false;
+
+ return ((Scriptable)b).hasInstance((Scriptable)a);
+ }
+
+ /**
+ * Delegates to
+ *
+ * @return true iff rhs appears in lhs' proto chain
+ */
+ public static boolean jsDelegatesTo(Scriptable lhs, Scriptable rhs) {
+ Scriptable proto = lhs.getPrototype();
+
+ while (proto != null) {
+ if (proto.equals(rhs)) return true;
+ proto = proto.getPrototype();
+ }
+
+ return false;
+ }
+
+ /**
+ * The in operator.
+ *
+ * This is a new JS 1.3 language feature. The in operator mirrors
+ * the operation of the for .. in construct, and tests whether the
+ * rhs has the property given by the lhs. It is different from the
+ * for .. in construct in that:
+ * <BR> - it doesn't perform ToObject on the right hand side
+ * <BR> - it returns true for DontEnum properties.
+ * @param a the left hand operand
+ * @param b the right hand operand
+ *
+ * @return true if property name or element number a is a property of b
+ */
+ public static boolean in(Object a, Object b, Context cx)
+ {
+ if (!(b instanceof Scriptable)) {
+ throw typeError0("msg.instanceof.not.object");
+ }
+
+ return hasObjectElem((Scriptable)b, a, cx);
+ }
+
+ public static boolean cmp_LT(Object val1, Object val2)
+ {
+ double d1, d2;
+ if (val1 instanceof Number && val2 instanceof Number) {
+ d1 = ((Number)val1).doubleValue();
+ d2 = ((Number)val2).doubleValue();
+ } else {
+ if (val1 instanceof Scriptable)
+ val1 = ((Scriptable) val1).getDefaultValue(NumberClass);
+ if (val2 instanceof Scriptable)
+ val2 = ((Scriptable) val2).getDefaultValue(NumberClass);
+ if (val1 instanceof String && val2 instanceof String) {
+ return ((String)val1).compareTo((String)val2) < 0;
+ }
+ d1 = toNumber(val1);
+ d2 = toNumber(val2);
+ }
+ return d1 < d2;
+ }
+
+ public static boolean cmp_LE(Object val1, Object val2)
+ {
+ double d1, d2;
+ if (val1 instanceof Number && val2 instanceof Number) {
+ d1 = ((Number)val1).doubleValue();
+ d2 = ((Number)val2).doubleValue();
+ } else {
+ if (val1 instanceof Scriptable)
+ val1 = ((Scriptable) val1).getDefaultValue(NumberClass);
+ if (val2 instanceof Scriptable)
+ val2 = ((Scriptable) val2).getDefaultValue(NumberClass);
+ if (val1 instanceof String && val2 instanceof String) {
+ return ((String)val1).compareTo((String)val2) <= 0;
+ }
+ d1 = toNumber(val1);
+ d2 = toNumber(val2);
+ }
+ return d1 <= d2;
+ }
+
+ // ------------------
+ // Statements
+ // ------------------
+
+ public static ScriptableObject getGlobal(Context cx) {
+ final String GLOBAL_CLASS = "org.mozilla.javascript.tools.shell.Global";
+ Class globalClass = Kit.classOrNull(GLOBAL_CLASS);
+ if (globalClass != null) {
+ try {
+ Class[] parm = { ScriptRuntime.ContextClass };
+ Constructor globalClassCtor = globalClass.getConstructor(parm);
+ Object[] arg = { cx };
+ return (ScriptableObject) globalClassCtor.newInstance(arg);
+ } catch (Exception e) {
+ // fall through...
+ }
+ }
+ return new ImporterTopLevel(cx);
+ }
+
+ public static boolean hasTopCall(Context cx)
+ {
+ return (cx.topCallScope != null);
+ }
+
+ public static Scriptable getTopCallScope(Context cx)
+ {
+ Scriptable scope = cx.topCallScope;
+ if (scope == null) {
+ throw new IllegalStateException();
+ }
+ return scope;
+ }
+
+ public static Object doTopCall(Callable callable,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (scope == null) throw new IllegalArgumentException();
+ if (cx.topCallScope != null) throw new IllegalStateException();
+
+ Object result;
+ cx.topCallScope = ScriptableObject.getTopLevelScope(scope);
+ cx.useDynamicScope = cx.hasFeature(Context.FEATURE_DYNAMIC_SCOPE);
+ ContextFactory f = cx.getFactory();
+ try {
+ result = f.doTopCall(callable, cx, scope, thisObj, args);
+ } finally {
+ cx.topCallScope = null;
+ // Cleanup cached references
+ cx.cachedXMLLib = null;
+
+ if (cx.currentActivationCall != null) {
+ // Function should always call exitActivationFunction
+ // if it creates activation record
+ throw new IllegalStateException();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return <tt>possibleDynamicScope</tt> if <tt>staticTopScope</tt>
+ * is present on its prototype chain and return <tt>staticTopScope</tt>
+ * otherwise.
+ * Should only be called when <tt>staticTopScope</tt> is top scope.
+ */
+ static Scriptable checkDynamicScope(Scriptable possibleDynamicScope,
+ Scriptable staticTopScope)
+ {
+ // Return cx.topCallScope if scope
+ if (possibleDynamicScope == staticTopScope) {
+ return possibleDynamicScope;
+ }
+ Scriptable proto = possibleDynamicScope;
+ for (;;) {
+ proto = proto.getPrototype();
+ if (proto == staticTopScope) {
+ return possibleDynamicScope;
+ }
+ if (proto == null) {
+ return staticTopScope;
+ }
+ }
+ }
+
+ public static void addInstructionCount(Context cx, int instructionsToAdd)
+ {
+ cx.instructionCount += instructionsToAdd;
+ if (cx.instructionCount > cx.instructionThreshold)
+ {
+ cx.observeInstructionCount(cx.instructionCount);
+ cx.instructionCount = 0;
+ }
+ }
+
+ public static void initScript(NativeFunction funObj, Scriptable thisObj,
+ Context cx, Scriptable scope,
+ boolean evalScript)
+ {
+ if (cx.topCallScope == null)
+ throw new IllegalStateException();
+
+ int varCount = funObj.getParamAndVarCount();
+ if (varCount != 0) {
+
+ Scriptable varScope = scope;
+ // Never define any variables from var statements inside with
+ // object. See bug 38590.
+ while (varScope instanceof NativeWith) {
+ varScope = varScope.getParentScope();
+ }
+
+ for (int i = varCount; i-- != 0;) {
+ String name = funObj.getParamOrVarName(i);
+ boolean isConst = funObj.getParamOrVarConst(i);
+ // Don't overwrite existing def if already defined in object
+ // or prototypes of object.
+ if (!ScriptableObject.hasProperty(scope, name)) {
+ if (!evalScript) {
+ // Global var definitions are supposed to be DONTDELETE
+ if (isConst)
+ ScriptableObject.defineConstProperty(varScope, name);
+ else
+ ScriptableObject.defineProperty(
+ varScope, name, Undefined.instance,
+ ScriptableObject.PERMANENT);
+ } else {
+ varScope.put(name, varScope, Undefined.instance);
+ }
+ } else {
+ ScriptableObject.redefineProperty(scope, name, isConst);
+ }
+ }
+ }
+ }
+
+ public static Scriptable createFunctionActivation(NativeFunction funObj,
+ Scriptable scope,
+ Object[] args)
+ {
+ return new NativeCall(funObj, scope, args);
+ }
+
+
+ public static void enterActivationFunction(Context cx,
+ Scriptable scope)
+ {
+ if (cx.topCallScope == null)
+ throw new IllegalStateException();
+ NativeCall call = (NativeCall)scope;
+ call.parentActivationCall = cx.currentActivationCall;
+ cx.currentActivationCall = call;
+ }
+
+ public static void exitActivationFunction(Context cx)
+ {
+ NativeCall call = cx.currentActivationCall;
+ cx.currentActivationCall = call.parentActivationCall;
+ call.parentActivationCall = null;
+ }
+
+ static NativeCall findFunctionActivation(Context cx, Function f)
+ {
+ NativeCall call = cx.currentActivationCall;
+ while (call != null) {
+ if (call.function == f)
+ return call;
+ call = call.parentActivationCall;
+ }
+ return null;
+ }
+
+ public static Scriptable newCatchScope(Throwable t,
+ Scriptable lastCatchScope,
+ String exceptionName,
+ Context cx, Scriptable scope)
+ {
+ Object obj;
+ boolean cacheObj;
+
+ getObj:
+ if (t instanceof JavaScriptException) {
+ cacheObj = false;
+ obj = ((JavaScriptException)t).getValue();
+ } else {
+ cacheObj = true;
+
+ // Create wrapper object unless it was associated with
+ // the previous scope object
+
+ if (lastCatchScope != null) {
+ NativeObject last = (NativeObject)lastCatchScope;
+ obj = last.getAssociatedValue(t);
+ if (obj == null) Kit.codeBug();
+ break getObj;
+ }
+
+ RhinoException re;
+ String errorName;
+ String errorMsg;
+ Throwable javaException = null;
+
+ if (t instanceof EcmaError) {
+ EcmaError ee = (EcmaError)t;
+ re = ee;
+ errorName = ee.getName();
+ errorMsg = ee.getErrorMessage();
+ } else if (t instanceof WrappedException) {
+ WrappedException we = (WrappedException)t;
+ re = we;
+ javaException = we.getWrappedException();
+ errorName = "JavaException";
+ errorMsg = javaException.getClass().getName()
+ +": "+javaException.getMessage();
+ } else if (t instanceof EvaluatorException) {
+ // Pure evaluator exception, nor WrappedException instance
+ EvaluatorException ee = (EvaluatorException)t;
+ re = ee;
+ errorName = "InternalError";
+ errorMsg = ee.getMessage();
+ } else if (cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS)) {
+ // With FEATURE_ENHANCED_JAVA_ACCESS, scripts can catch
+ // all exception types
+ re = new WrappedException(t);
+ errorName = "JavaException";
+ errorMsg = t.toString();
+ } else {
+ // Script can catch only instances of JavaScriptException,
+ // EcmaError and EvaluatorException
+ throw Kit.codeBug();
+ }
+
+ String sourceUri = re.sourceName();
+ if (sourceUri == null) {
+ sourceUri = "";
+ }
+ int line = re.lineNumber();
+ Object args[];
+ if (line > 0) {
+ args = new Object[] { errorMsg, sourceUri, new Integer(line) };
+ } else {
+ args = new Object[] { errorMsg, sourceUri };
+ }
+
+ Scriptable errorObject = cx.newObject(scope, errorName, args);
+ ScriptableObject.putProperty(errorObject, "name", errorName);
+
+ if (javaException != null) {
+ Object wrap = cx.getWrapFactory().wrap(cx, scope, javaException,
+ null);
+ ScriptableObject.defineProperty(
+ errorObject, "javaException", wrap,
+ ScriptableObject.PERMANENT | ScriptableObject.READONLY);
+ }
+ Object wrap = cx.getWrapFactory().wrap(cx, scope, re, null);
+ ScriptableObject.defineProperty(
+ errorObject, "rhinoException", wrap,
+ ScriptableObject.PERMANENT | ScriptableObject.READONLY);
+
+ obj = errorObject;
+ }
+
+ NativeObject catchScopeObject = new NativeObject();
+ // See ECMA 12.4
+ catchScopeObject.defineProperty(
+ exceptionName, obj, ScriptableObject.PERMANENT);
+
+ // Add special Rhino object __exception__ defined in the catch
+ // scope that can be used to retrieve the Java exception associated
+ // with the JavaScript exception (to get stack trace info, etc.)
+ /*APPJET NOJAVA*/
+ /*catchScopeObject.defineProperty(
+ "__exception__", Context.javaToJS(t, scope),
+ ScriptableObject.PERMANENT|ScriptableObject.DONTENUM);*/
+
+ if (cacheObj) {
+ catchScopeObject.associateValue(t, obj);
+ }
+ return catchScopeObject;
+ }
+
+ public static Scriptable enterWith(Object obj, Context cx,
+ Scriptable scope)
+ {
+ Scriptable sobj = toObjectOrNull(cx, obj);
+ if (sobj == null) {
+ throw typeError1("msg.undef.with", toString(obj));
+ }
+ if (sobj instanceof XMLObject) {
+ XMLObject xmlObject = (XMLObject)sobj;
+ return xmlObject.enterWith(scope);
+ }
+ return new NativeWith(scope, sobj);
+ }
+
+ public static Scriptable leaveWith(Scriptable scope)
+ {
+ NativeWith nw = (NativeWith)scope;
+ return nw.getParentScope();
+ }
+
+ public static Scriptable enterDotQuery(Object value, Scriptable scope)
+ {
+ if (!(value instanceof XMLObject)) {
+ throw notXmlError(value);
+ }
+ XMLObject object = (XMLObject)value;
+ return object.enterDotQuery(scope);
+ }
+
+ public static Object updateDotQuery(boolean value, Scriptable scope)
+ {
+ // Return null to continue looping
+ NativeWith nw = (NativeWith)scope;
+ return nw.updateDotQuery(value);
+ }
+
+ public static Scriptable leaveDotQuery(Scriptable scope)
+ {
+ NativeWith nw = (NativeWith)scope;
+ return nw.getParentScope();
+ }
+
+ public static void setFunctionProtoAndParent(BaseFunction fn,
+ Scriptable scope)
+ {
+ fn.setParentScope(scope);
+ fn.setPrototype(ScriptableObject.getFunctionPrototype(scope));
+ }
+
+ public static void setObjectProtoAndParent(ScriptableObject object,
+ Scriptable scope)
+ {
+ // Compared with function it always sets the scope to top scope
+ scope = ScriptableObject.getVeryTopLevelScope(scope); // APPJET
+ object.setParentScope(scope);
+ Scriptable proto
+ = ScriptableObject.getClassPrototype(scope, object.getClassName());
+ object.setPrototype(proto);
+ }
+
+ public static void initFunction(Context cx, Scriptable scope,
+ NativeFunction function, int type,
+ boolean fromEvalCode)
+ {
+ if (type == FunctionNode.FUNCTION_STATEMENT) {
+ String name = function.getFunctionName();
+ if (name != null && name.length() != 0) {
+ if (!fromEvalCode) {
+ // ECMA specifies that functions defined in global and
+ // function scope outside eval should have DONTDELETE set.
+ ScriptableObject.defineProperty
+ (scope, name, function, ScriptableObject.PERMANENT);
+ } else {
+ scope.put(name, scope, function);
+ }
+ }
+ } else if (type == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
+ String name = function.getFunctionName();
+ if (name != null && name.length() != 0) {
+ // Always put function expression statements into initial
+ // activation object ignoring the with statement to follow
+ // SpiderMonkey
+ while (scope instanceof NativeWith) {
+ scope = scope.getParentScope();
+ }
+ scope.put(name, scope, function);
+ }
+ } else {
+ throw Kit.codeBug();
+ }
+ }
+
+ public static Scriptable newArrayLiteral(Object[] objects,
+ int[] skipIndices,
+ Context cx, Scriptable scope)
+ {
+ final int SKIP_DENSITY = 2;
+ int count = objects.length;
+ int skipCount = 0;
+ if (skipIndices != null) {
+ skipCount = skipIndices.length;
+ }
+ int length = count + skipCount;
+ if (length > 1 && skipCount * SKIP_DENSITY < length) {
+ // If not too sparse, create whole array for constructor
+ Object[] sparse;
+ if (skipCount == 0) {
+ sparse = objects;
+ } else {
+ sparse = new Object[length];
+ int skip = 0;
+ for (int i = 0, j = 0; i != length; ++i) {
+ if (skip != skipCount && skipIndices[skip] == i) {
+ sparse[i] = Scriptable.NOT_FOUND;
+ ++skip;
+ continue;
+ }
+ sparse[i] = objects[j];
+ ++j;
+ }
+ }
+ return cx.newObject(scope, "Array", sparse);
+ }
+
+ Scriptable arrayObj = cx.newObject(scope, "Array",
+ ScriptRuntime.emptyArgs);
+ int skip = 0;
+ for (int i = 0, j = 0; i != length; ++i) {
+ if (skip != skipCount && skipIndices[skip] == i) {
+ ++skip;
+ continue;
+ }
+ ScriptableObject.putProperty(arrayObj, i, objects[j]);
+ ++j;
+ }
+ return arrayObj;
+ }
+
+ /**
+ * This method is here for backward compat with existing compiled code. It
+ * is called when an object literal is compiled. The next instance will be
+ * the version called from new code.
+ * @deprecated This method only present for compatibility.
+ */
+ public static Scriptable newObjectLiteral(Object[] propertyIds,
+ Object[] propertyValues,
+ Context cx, Scriptable scope)
+ {
+ // This will initialize to all zeros, exactly what we need for old-style
+ // getterSetters values (no getters or setters in the list)
+ int [] getterSetters = new int[propertyIds.length];
+ return newObjectLiteral(propertyIds, propertyValues, getterSetters,
+ cx, scope);
+ }
+
+ public static Scriptable newObjectLiteral(Object[] propertyIds,
+ Object[] propertyValues,
+ int [] getterSetters,
+ Context cx, Scriptable scope)
+ {
+ Scriptable object = cx.newObject(scope);
+ for (int i = 0, end = propertyIds.length; i != end; ++i) {
+ Object id = propertyIds[i];
+ int getterSetter = getterSetters[i];
+ Object value = propertyValues[i];
+ if (id instanceof String) {
+ if (getterSetter == 0)
+ ScriptableObject.putProperty(object, (String)id, value);
+ else {
+ Callable fun;
+ String definer;
+ if (getterSetter < 0) // < 0 means get foo() ...
+ definer = "__defineGetter__";
+ else
+ definer = "__defineSetter__";
+ fun = getPropFunctionAndThis(object, definer, cx);
+ // Must consume the last scriptable object in cx
+ lastStoredScriptable(cx);
+ Object[] outArgs = new Object[2];
+ outArgs[0] = id;
+ outArgs[1] = value;
+ fun.call(cx, scope, object, outArgs);
+ }
+ } else {
+ int index = ((Integer)id).intValue();
+ ScriptableObject.putProperty(object, index, value);
+ }
+ }
+ return object;
+ }
+
+ public static boolean isArrayObject(Object obj)
+ {
+ return obj instanceof NativeArray || obj instanceof Arguments;
+ }
+
+ public static Object[] getArrayElements(Scriptable object)
+ {
+ Context cx = Context.getContext();
+ long longLen = NativeArray.getLengthProperty(cx, object);
+ if (longLen > Integer.MAX_VALUE) {
+ // arrays beyond MAX_INT is not in Java in any case
+ throw new IllegalArgumentException();
+ }
+ int len = (int) longLen;
+ if (len == 0) {
+ return ScriptRuntime.emptyArgs;
+ } else {
+ Object[] result = new Object[len];
+ for (int i=0; i < len; i++) {
+ Object elem = ScriptableObject.getProperty(object, i);
+ result[i] = (elem == Scriptable.NOT_FOUND) ? Undefined.instance
+ : elem;
+ }
+ return result;
+ }
+ }
+
+ static void checkDeprecated(Context cx, String name) {
+ int version = cx.getLanguageVersion();
+ if (version >= Context.VERSION_1_4 || version == Context.VERSION_DEFAULT) {
+ String msg = getMessage1("msg.deprec.ctor", name);
+ if (version == Context.VERSION_DEFAULT)
+ Context.reportWarning(msg);
+ else
+ throw Context.reportRuntimeError(msg);
+ }
+ }
+
+ public static String getMessage0(String messageId)
+ {
+ return getMessage(messageId, null);
+ }
+
+ public static String getMessage1(String messageId, Object arg1)
+ {
+ Object[] arguments = {arg1};
+ return getMessage(messageId, arguments);
+ }
+
+ public static String getMessage2(
+ String messageId, Object arg1, Object arg2)
+ {
+ Object[] arguments = {arg1, arg2};
+ return getMessage(messageId, arguments);
+ }
+
+ public static String getMessage3(
+ String messageId, Object arg1, Object arg2, Object arg3)
+ {
+ Object[] arguments = {arg1, arg2, arg3};
+ return getMessage(messageId, arguments);
+ }
+
+ public static String getMessage4(
+ String messageId, Object arg1, Object arg2, Object arg3, Object arg4)
+ {
+ Object[] arguments = {arg1, arg2, arg3, arg4};
+ return getMessage(messageId, arguments);
+ }
+
+ /* OPT there's a noticable delay for the first error! Maybe it'd
+ * make sense to use a ListResourceBundle instead of a properties
+ * file to avoid (synchronized) text parsing.
+ */
+ public static String getMessage(String messageId, Object[] arguments)
+ {
+ final String defaultResource
+ = "org.mozilla.javascript.resources.Messages";
+
+ Context cx = Context.getCurrentContext();
+ Locale locale = cx != null ? cx.getLocale() : Locale.getDefault();
+
+ // ResourceBundle does cacheing.
+ ResourceBundle rb = ResourceBundle.getBundle(defaultResource, locale);
+
+ String formatString;
+ try {
+ formatString = rb.getString(messageId);
+ } catch (java.util.MissingResourceException mre) {
+ throw new RuntimeException
+ ("no message resource found for message property "+ messageId);
+ }
+
+ /*
+ * It's OK to format the string, even if 'arguments' is null;
+ * we need to format it anyway, to make double ''s collapse to
+ * single 's.
+ */
+ MessageFormat formatter = new MessageFormat(formatString);
+ return formatter.format(arguments);
+ }
+
+ public static EcmaError constructError(String error, String message)
+ {
+ int[] linep = new int[1];
+ String filename = Context.getSourcePositionFromStack(linep);
+ return constructError(error, message, filename, linep[0], null, 0);
+ }
+
+ public static EcmaError constructError(String error,
+ String message,
+ int lineNumberDelta)
+ {
+ int[] linep = new int[1];
+ String filename = Context.getSourcePositionFromStack(linep);
+ if (linep[0] != 0) {
+ linep[0] += lineNumberDelta;
+ }
+ return constructError(error, message, filename, linep[0], null, 0);
+ }
+
+ public static EcmaError constructError(String error,
+ String message,
+ String sourceName,
+ int lineNumber,
+ String lineSource,
+ int columnNumber)
+ {
+ return new EcmaError(error, message, sourceName,
+ lineNumber, lineSource, columnNumber);
+ }
+
+ public static EcmaError typeError(String message)
+ {
+ return constructError("TypeError", message);
+ }
+
+ public static EcmaError typeError0(String messageId)
+ {
+ String msg = getMessage0(messageId);
+ return typeError(msg);
+ }
+
+ public static EcmaError typeError1(String messageId, String arg1)
+ {
+ String msg = getMessage1(messageId, arg1);
+ return typeError(msg);
+ }
+
+ public static EcmaError typeError2(String messageId, String arg1,
+ String arg2)
+ {
+ String msg = getMessage2(messageId, arg1, arg2);
+ return typeError(msg);
+ }
+
+ public static EcmaError typeError3(String messageId, String arg1,
+ String arg2, String arg3)
+ {
+ String msg = getMessage3(messageId, arg1, arg2, arg3);
+ return typeError(msg);
+ }
+
+ public static RuntimeException undefReadError(Object object, Object id)
+ {
+ String idStr = (id == null) ? "null" : id.toString();
+ return typeError2("msg.undef.prop.read", toString(object), idStr);
+ }
+
+ public static RuntimeException undefCallError(Object object, Object id)
+ {
+ String idStr = (id == null) ? "null" : id.toString();
+ return typeError2("msg.undef.method.call", toString(object), idStr);
+ }
+
+ public static RuntimeException undefWriteError(Object object,
+ Object id,
+ Object value)
+ {
+ String idStr = (id == null) ? "null" : id.toString();
+ String valueStr = (value instanceof Scriptable)
+ ? value.toString() : toString(value);
+ return typeError3("msg.undef.prop.write", toString(object), idStr,
+ valueStr);
+ }
+
+ public static RuntimeException notFoundError(Scriptable object,
+ String property)
+ {
+ // XXX: use object to improve the error message
+ String msg = getMessage1("msg.is.not.defined", property);
+ throw constructError("ReferenceError", msg);
+ }
+
+ public static RuntimeException notFunctionError(Object value)
+ {
+ return notFunctionError(value, value);
+ }
+
+ public static RuntimeException notFunctionError(Object value,
+ Object messageHelper)
+ {
+ // Use value for better error reporting
+ String msg = (messageHelper == null)
+ ? "null" : messageHelper.toString();
+ if (value == Scriptable.NOT_FOUND) {
+ return typeError1("msg.function.not.found", msg);
+ }
+ return typeError2("msg.isnt.function", msg, typeof(value));
+ }
+
+ public static RuntimeException notFunctionError(Object obj, Object value,
+ String propertyName)
+ {
+ // Use obj and value for better error reporting
+ String objString = toString(obj);
+ if (value == Scriptable.NOT_FOUND) {
+ return typeError2("msg.function.not.found.in", propertyName,
+ objString);
+ }
+ return typeError3("msg.isnt.function.in", propertyName, objString,
+ typeof(value));
+ }
+
+ private static RuntimeException notXmlError(Object value)
+ {
+ throw typeError1("msg.isnt.xml.object", toString(value));
+ }
+
+ private static void warnAboutNonJSObject(Object nonJSObject)
+ {
+ String message =
+"RHINO USAGE WARNING: Missed Context.javaToJS() conversion:\n"
++"Rhino runtime detected object "+nonJSObject+" of class "+nonJSObject.getClass().getName()+" where it expected String, Number, Boolean or Scriptable instance. Please check your code for missing Context.javaToJS() call.";
+ Context.reportWarning(message);
+ // Just to be sure that it would be noticed
+ System.err.println(message);
+ }
+
+ public static RegExpProxy getRegExpProxy(Context cx)
+ {
+ return cx.getRegExpProxy();
+ }
+
+ public static void setRegExpProxy(Context cx, RegExpProxy proxy)
+ {
+ if (proxy == null) throw new IllegalArgumentException();
+ cx.regExpProxy = proxy;
+ }
+
+ public static RegExpProxy checkRegExpProxy(Context cx)
+ {
+ RegExpProxy result = getRegExpProxy(cx);
+ if (result == null) {
+ throw Context.reportRuntimeError0("msg.no.regexp");
+ }
+ return result;
+ }
+
+ private static XMLLib currentXMLLib(Context cx)
+ {
+ // Scripts should be running to access this
+ if (cx.topCallScope == null)
+ throw new IllegalStateException();
+
+ XMLLib xmlLib = cx.cachedXMLLib;
+ if (xmlLib == null) {
+ xmlLib = XMLLib.extractFromScope(cx.topCallScope);
+ if (xmlLib == null)
+ throw new IllegalStateException();
+ cx.cachedXMLLib = xmlLib;
+ }
+
+ return xmlLib;
+ }
+
+ /**
+ * Escapes the reserved characters in a value of an attribute
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public static String escapeAttributeValue(Object value, Context cx)
+ {
+ XMLLib xmlLib = currentXMLLib(cx);
+ return xmlLib.escapeAttributeValue(value);
+ }
+
+ /**
+ * Escapes the reserved characters in a value of a text node
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public static String escapeTextValue(Object value, Context cx)
+ {
+ XMLLib xmlLib = currentXMLLib(cx);
+ return xmlLib.escapeTextValue(value);
+ }
+
+ public static Ref memberRef(Object obj, Object elem,
+ Context cx, int memberTypeFlags)
+ {
+ if (!(obj instanceof XMLObject)) {
+ throw notXmlError(obj);
+ }
+ XMLObject xmlObject = (XMLObject)obj;
+ return xmlObject.memberRef(cx, elem, memberTypeFlags);
+ }
+
+ public static Ref memberRef(Object obj, Object namespace, Object elem,
+ Context cx, int memberTypeFlags)
+ {
+ if (!(obj instanceof XMLObject)) {
+ throw notXmlError(obj);
+ }
+ XMLObject xmlObject = (XMLObject)obj;
+ return xmlObject.memberRef(cx, namespace, elem, memberTypeFlags);
+ }
+
+ public static Ref nameRef(Object name, Context cx,
+ Scriptable scope, int memberTypeFlags)
+ {
+ XMLLib xmlLib = currentXMLLib(cx);
+ return xmlLib.nameRef(cx, name, scope, memberTypeFlags);
+ }
+
+ public static Ref nameRef(Object namespace, Object name, Context cx,
+ Scriptable scope, int memberTypeFlags)
+ {
+ XMLLib xmlLib = currentXMLLib(cx);
+ return xmlLib.nameRef(cx, namespace, name, scope, memberTypeFlags);
+ }
+
+ private static void storeIndexResult(Context cx, int index)
+ {
+ cx.scratchIndex = index;
+ }
+
+ static int lastIndexResult(Context cx)
+ {
+ return cx.scratchIndex;
+ }
+
+ public static void storeUint32Result(Context cx, long value)
+ {
+ if ((value >>> 32) != 0)
+ throw new IllegalArgumentException();
+ cx.scratchUint32 = value;
+ }
+
+ public static long lastUint32Result(Context cx)
+ {
+ long value = cx.scratchUint32;
+ if ((value >>> 32) != 0)
+ throw new IllegalStateException();
+ return value;
+ }
+
+ private static void storeScriptable(Context cx, Scriptable value)
+ {
+ // The previosly stored scratchScriptable should be consumed
+ if (cx.scratchScriptable != null)
+ throw new IllegalStateException();
+ cx.scratchScriptable = value;
+ }
+
+ public static Scriptable lastStoredScriptable(Context cx)
+ {
+ Scriptable result = cx.scratchScriptable;
+ cx.scratchScriptable = null;
+ return result;
+ }
+
+ static String makeUrlForGeneratedScript
+ (boolean isEval, String masterScriptUrl, int masterScriptLine)
+ {
+ if (isEval) {
+ return masterScriptUrl+'#'+masterScriptLine+"(eval)";
+ } else {
+ return masterScriptUrl+'#'+masterScriptLine+"(Function)";
+ }
+ }
+
+ static boolean isGeneratedScript(String sourceUrl) {
+ // ALERT: this may clash with a valid URL containing (eval) or
+ // (Function)
+ return sourceUrl.indexOf("(eval)") >= 0
+ || sourceUrl.indexOf("(Function)") >= 0;
+ }
+
+ private static RuntimeException errorWithClassName(String msg, Object val)
+ {
+ return Context.reportRuntimeError1(msg, val.getClass().getName());
+ }
+
+ public static final Object[] emptyArgs = new Object[0];
+ public static final String[] emptyStrings = new String[0];
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java
new file mode 100644
index 0000000..74e5ba7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Scriptable.java
@@ -0,0 +1,342 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This is interface that all objects in JavaScript must implement.
+ * The interface provides for the management of properties and for
+ * performing conversions.
+ * <p>
+ * Host system implementors may find it easier to extend the ScriptableObject
+ * class rather than implementing Scriptable when writing host objects.
+ * <p>
+ * There are many static methods defined in ScriptableObject that perform
+ * the multiple calls to the Scriptable interface needed in order to
+ * manipulate properties in prototype chains.
+ * <p>
+ *
+ * @see org.mozilla.javascript.ScriptableObject
+ * @author Norris Boyd
+ * @author Nick Thompson
+ * @author Brendan Eich
+ */
+
+public interface Scriptable {
+
+ /**
+ * Get the name of the set of objects implemented by this Java class.
+ * This corresponds to the [[Class]] operation in ECMA and is used
+ * by Object.prototype.toString() in ECMA.<p>
+ * See ECMA 8.6.2 and 15.2.4.2.
+ */
+ public String getClassName();
+
+ /**
+ * Value returned from <code>get</code> if the property is not
+ * found.
+ */
+ public static final Object NOT_FOUND = UniqueTag.NOT_FOUND;
+
+ /**
+ * Get a named property from the object.
+ *
+ * Looks property up in this object and returns the associated value
+ * if found. Returns NOT_FOUND if not found.
+ * Note that this method is not expected to traverse the prototype
+ * chain. This is different from the ECMA [[Get]] operation.
+ *
+ * Depending on the property selector, the runtime will call
+ * this method or the form of <code>get</code> that takes an
+ * integer:
+ * <table>
+ * <tr><th>JavaScript code</th><th>Java code</th></tr>
+ * <tr><td>a.b </td><td>a.get("b", a)</td></tr>
+ * <tr><td>a["foo"] </td><td>a.get("foo", a)</td></tr>
+ * <tr><td>a[3] </td><td>a.get(3, a)</td></tr>
+ * <tr><td>a["3"] </td><td>a.get(3, a)</td></tr>
+ * <tr><td>a[3.0] </td><td>a.get(3, a)</td></tr>
+ * <tr><td>a["3.0"] </td><td>a.get("3.0", a)</td></tr>
+ * <tr><td>a[1.1] </td><td>a.get("1.1", a)</td></tr>
+ * <tr><td>a[-4] </td><td>a.get(-4, a)</td></tr>
+ * </table>
+ * <p>
+ * The values that may be returned are limited to the following:
+ * <UL>
+ * <LI>java.lang.Boolean objects</LI>
+ * <LI>java.lang.String objects</LI>
+ * <LI>java.lang.Number objects</LI>
+ * <LI>org.mozilla.javascript.Scriptable objects</LI>
+ * <LI>null</LI>
+ * <LI>The value returned by Context.getUndefinedValue()</LI>
+ * <LI>NOT_FOUND</LI>
+ * </UL>
+ * @param name the name of the property
+ * @param start the object in which the lookup began
+ * @return the value of the property (may be null), or NOT_FOUND
+ * @see org.mozilla.javascript.Context#getUndefinedValue
+ */
+ public Object get(String name, Scriptable start);
+
+ /**
+ * Get a property from the object selected by an integral index.
+ *
+ * Identical to <code>get(String, Scriptable)</code> except that
+ * an integral index is used to select the property.
+ *
+ * @param index the numeric index for the property
+ * @param start the object in which the lookup began
+ * @return the value of the property (may be null), or NOT_FOUND
+ * @see org.mozilla.javascript.Scriptable#get(String,Scriptable)
+ */
+ public Object get(int index, Scriptable start);
+
+ /**
+ * Indicates whether or not a named property is defined in an object.
+ *
+ * Does not traverse the prototype chain.<p>
+ *
+ * The property is specified by a String name
+ * as defined for the <code>get</code> method.<p>
+ *
+ * @param name the name of the property
+ * @param start the object in which the lookup began
+ * @return true if and only if the named property is found in the object
+ * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, String)
+ */
+ public boolean has(String name, Scriptable start);
+
+ /**
+ * Indicates whether or not an indexed property is defined in an object.
+ *
+ * Does not traverse the prototype chain.<p>
+ *
+ * The property is specified by an integral index
+ * as defined for the <code>get</code> method.<p>
+ *
+ * @param index the numeric index for the property
+ * @param start the object in which the lookup began
+ * @return true if and only if the indexed property is found in the object
+ * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#getProperty(Scriptable, int)
+ */
+ public boolean has(int index, Scriptable start);
+
+ /**
+ * Sets a named property in this object.
+ * <p>
+ * The property is specified by a string name
+ * as defined for <code>get</code>.
+ * <p>
+ * The possible values that may be passed in are as defined for
+ * <code>get</code>. A class that implements this method may choose
+ * to ignore calls to set certain properties, in which case those
+ * properties are effectively read-only.<p>
+ * For properties defined in a prototype chain,
+ * use <code>putProperty</code> in ScriptableObject. <p>
+ * Note that if a property <i>a</i> is defined in the prototype <i>p</i>
+ * of an object <i>o</i>, then evaluating <code>o.a = 23</code> will cause
+ * <code>set</code> to be called on the prototype <i>p</i> with
+ * <i>o</i> as the <i>start</i> parameter.
+ * To preserve JavaScript semantics, it is the Scriptable
+ * object's responsibility to modify <i>o</i>. <p>
+ * This design allows properties to be defined in prototypes and implemented
+ * in terms of getters and setters of Java values without consuming slots
+ * in each instance.<p>
+ * <p>
+ * The values that may be set are limited to the following:
+ * <UL>
+ * <LI>java.lang.Boolean objects</LI>
+ * <LI>java.lang.String objects</LI>
+ * <LI>java.lang.Number objects</LI>
+ * <LI>org.mozilla.javascript.Scriptable objects</LI>
+ * <LI>null</LI>
+ * <LI>The value returned by Context.getUndefinedValue()</LI>
+ * </UL><p>
+ * Arbitrary Java objects may be wrapped in a Scriptable by first calling
+ * <code>Context.toObject</code>. This allows the property of a JavaScript
+ * object to contain an arbitrary Java object as a value.<p>
+ * Note that <code>has</code> will be called by the runtime first before
+ * <code>set</code> is called to determine in which object the
+ * property is defined.
+ * Note that this method is not expected to traverse the prototype chain,
+ * which is different from the ECMA [[Put]] operation.
+ * @param name the name of the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
+ * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, String, Object)
+ * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
+ */
+ public void put(String name, Scriptable start, Object value);
+
+ /**
+ * Sets an indexed property in this object.
+ * <p>
+ * The property is specified by an integral index
+ * as defined for <code>get</code>.<p>
+ *
+ * Identical to <code>put(String, Scriptable, Object)</code> except that
+ * an integral index is used to select the property.
+ *
+ * @param index the numeric index for the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ * @see org.mozilla.javascript.Scriptable#has(int, Scriptable)
+ * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#putProperty(Scriptable, int, Object)
+ * @see org.mozilla.javascript.Context#toObject(Object, Scriptable)
+ */
+ public void put(int index, Scriptable start, Object value);
+
+ /**
+ * Removes a property from this object.
+ * This operation corresponds to the ECMA [[Delete]] except that
+ * the no result is returned. The runtime will guarantee that this
+ * method is called only if the property exists. After this method
+ * is called, the runtime will call Scriptable.has to see if the
+ * property has been removed in order to determine the boolean
+ * result of the delete operator as defined by ECMA 11.4.1.
+ * <p>
+ * A property can be made permanent by ignoring calls to remove
+ * it.<p>
+ * The property is specified by a String name
+ * as defined for <code>get</code>.
+ * <p>
+ * To delete properties defined in a prototype chain,
+ * see deleteProperty in ScriptableObject.
+ * @param name the identifier for the property
+ * @see org.mozilla.javascript.Scriptable#get(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, String)
+ */
+ public void delete(String name);
+
+ /**
+ * Removes a property from this object.
+ *
+ * The property is specified by an integral index
+ * as defined for <code>get</code>.
+ * <p>
+ * To delete properties defined in a prototype chain,
+ * see deleteProperty in ScriptableObject.
+ *
+ * Identical to <code>delete(String)</code> except that
+ * an integral index is used to select the property.
+ *
+ * @param index the numeric index for the property
+ * @see org.mozilla.javascript.Scriptable#get(int, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#deleteProperty(Scriptable, int)
+ */
+ public void delete(int index);
+
+ /**
+ * Get the prototype of the object.
+ * @return the prototype
+ */
+ public Scriptable getPrototype();
+
+ /**
+ * Set the prototype of the object.
+ * @param prototype the prototype to set
+ */
+ public void setPrototype(Scriptable prototype);
+
+ /**
+ * Get the parent scope of the object.
+ * @return the parent scope
+ */
+ public Scriptable getParentScope();
+
+ /**
+ * Set the parent scope of the object.
+ * @param parent the parent scope to set
+ */
+ public void setParentScope(Scriptable parent);
+
+ /**
+ * Get an array of property ids.
+ *
+ * Not all property ids need be returned. Those properties
+ * whose ids are not returned are considered non-enumerable.
+ *
+ * @return an array of Objects. Each entry in the array is either
+ * a java.lang.String or a java.lang.Number
+ */
+ public Object[] getIds();
+
+ /**
+ * Get the default value of the object with a given hint.
+ * The hints are String.class for type String, Number.class for type
+ * Number, Scriptable.class for type Object, and Boolean.class for
+ * type Boolean. <p>
+ *
+ * A <code>hint</code> of null means "no hint".
+ *
+ * See ECMA 8.6.2.6.
+ *
+ * @param hint the type hint
+ * @return the default value
+ */
+ public Object getDefaultValue(Class hint);
+
+ /**
+ * The instanceof operator.
+ *
+ * <p>
+ * The JavaScript code "lhs instanceof rhs" causes rhs.hasInstance(lhs) to
+ * be called.
+ *
+ * <p>
+ * The return value is implementation dependent so that embedded host objects can
+ * return an appropriate value. See the JS 1.3 language documentation for more
+ * detail.
+ *
+ * <p>This operator corresponds to the proposed EMCA [[HasInstance]] operator.
+ *
+ * @param instance The value that appeared on the LHS of the instanceof
+ * operator
+ *
+ * @return an implementation dependent value
+ */
+ public boolean hasInstance(Scriptable instance);
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java
new file mode 100644
index 0000000..53de1fc
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/ScriptableObject.java
@@ -0,0 +1,2428 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Bob Jervis
+ * Roger Lawrence
+ * Steve Weiss
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.*;
+import java.util.Hashtable;
+import java.io.*;
+import org.mozilla.javascript.debug.DebuggableObject;
+
+/**
+ * This is the default implementation of the Scriptable interface. This
+ * class provides convenient default behavior that makes it easier to
+ * define host objects.
+ * <p>
+ * Various properties and methods of JavaScript objects can be conveniently
+ * defined using methods of ScriptableObject.
+ * <p>
+ * Classes extending ScriptableObject must define the getClassName method.
+ *
+ * @see org.mozilla.javascript.Scriptable
+ * @author Norris Boyd
+ */
+
+public abstract class ScriptableObject implements Scriptable, Serializable,
+ DebuggableObject,
+ ConstProperties
+{
+
+ /**
+ * The empty property attribute.
+ *
+ * Used by getAttributes() and setAttributes().
+ *
+ * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
+ * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
+ */
+ public static final int EMPTY = 0x00;
+
+ /**
+ * Property attribute indicating assignment to this property is ignored.
+ *
+ * @see org.mozilla.javascript.ScriptableObject
+ * #put(String, Scriptable, Object)
+ * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
+ * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
+ */
+ public static final int READONLY = 0x01;
+
+ /**
+ * Property attribute indicating property is not enumerated.
+ *
+ * Only enumerated properties will be returned by getIds().
+ *
+ * @see org.mozilla.javascript.ScriptableObject#getIds()
+ * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
+ * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
+ */
+ public static final int DONTENUM = 0x02;
+
+ /**
+ * Property attribute indicating property cannot be deleted.
+ *
+ * @see org.mozilla.javascript.ScriptableObject#delete(String)
+ * @see org.mozilla.javascript.ScriptableObject#getAttributes(String)
+ * @see org.mozilla.javascript.ScriptableObject#setAttributes(String, int)
+ */
+ public static final int PERMANENT = 0x04;
+
+ /**
+ * Property attribute indicating that this is a const property that has not
+ * been assigned yet. The first 'const' assignment to the property will
+ * clear this bit.
+ */
+ public static final int UNINITIALIZED_CONST = 0x08;
+
+ public static final int CONST = PERMANENT|READONLY|UNINITIALIZED_CONST;
+ /**
+ * The prototype of this object.
+ */
+ private Scriptable prototypeObject;
+
+ /**
+ * The parent scope of this object.
+ */
+ private Scriptable parentScopeObject;
+
+ private static final Slot REMOVED = new Slot(null, 0, READONLY);
+
+ static {
+ REMOVED.wasDeleted = 1;
+ }
+
+ private transient Slot[] slots;
+ // If count >= 0, it gives number of keys or if count < 0,
+ // it indicates sealed object where ~count gives number of keys
+ private int count;
+
+ // cache; may be removed for smaller memory footprint
+ private transient Slot lastAccess = REMOVED;
+
+ // associated values are not serialized
+ private transient volatile Hashtable associatedValues;
+
+ private static final int SLOT_QUERY = 1;
+ private static final int SLOT_MODIFY = 2;
+ private static final int SLOT_REMOVE = 3;
+ private static final int SLOT_MODIFY_GETTER_SETTER = 4;
+ private static final int SLOT_MODIFY_CONST = 5;
+
+ private static class Slot implements Serializable
+ {
+ static final long serialVersionUID = -3539051633409902634L;
+
+ String name; // This can change due to caching
+ int indexOrHash;
+ private volatile short attributes;
+ transient volatile byte wasDeleted;
+ volatile Object value;
+ transient volatile Slot next;
+
+ Slot(String name, int indexOrHash, int attributes)
+ {
+ this.name = name;
+ this.indexOrHash = indexOrHash;
+ this.attributes = (short)attributes;
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ if (name != null) {
+ indexOrHash = name.hashCode();
+ }
+ }
+
+ final int getAttributes()
+ {
+ return attributes;
+ }
+
+ final synchronized void setAttributes(int value)
+ {
+ checkValidAttributes(value);
+ attributes = (short)value;
+ }
+
+ final void checkNotReadonly()
+ {
+ if ((attributes & READONLY) != 0) {
+ String str = (name != null ? name
+ : Integer.toString(indexOrHash));
+ throw Context.reportRuntimeError1("msg.modify.readonly", str);
+ }
+ }
+
+ }
+
+ private static final class GetterSlot extends Slot
+ {
+ static final long serialVersionUID = -4900574849788797588L;
+
+ Object getter;
+ Object setter;
+
+ GetterSlot(String name, int indexOrHash, int attributes)
+ {
+ super(name, indexOrHash, attributes);
+ }
+ }
+
+ static void checkValidAttributes(int attributes)
+ {
+ final int mask = READONLY | DONTENUM | PERMANENT | UNINITIALIZED_CONST;
+ if ((attributes & ~mask) != 0) {
+ throw new IllegalArgumentException(String.valueOf(attributes));
+ }
+ }
+
+ public ScriptableObject()
+ {
+ }
+
+ public ScriptableObject(Scriptable scope, Scriptable prototype)
+ {
+ if (scope == null)
+ throw new IllegalArgumentException();
+
+ parentScopeObject = scope;
+ prototypeObject = prototype;
+ }
+
+ /**
+ * Return the name of the class.
+ *
+ * This is typically the same name as the constructor.
+ * Classes extending ScriptableObject must implement this abstract
+ * method.
+ */
+ public abstract String getClassName();
+
+ /**
+ * Returns true if the named property is defined.
+ *
+ * @param name the name of the property
+ * @param start the object in which the lookup began
+ * @return true if and only if the property was found in the object
+ */
+ public boolean has(String name, Scriptable start)
+ {
+ return null != getSlot(name, 0, SLOT_QUERY);
+ }
+
+ /**
+ * Returns true if the property index is defined.
+ *
+ * @param index the numeric index for the property
+ * @param start the object in which the lookup began
+ * @return true if and only if the property was found in the object
+ */
+ public boolean has(int index, Scriptable start)
+ {
+ return null != getSlot(null, index, SLOT_QUERY);
+ }
+
+ /**
+ * Returns the value of the named property or NOT_FOUND.
+ *
+ * If the property was created using defineProperty, the
+ * appropriate getter method is called.
+ *
+ * @param name the name of the property
+ * @param start the object in which the lookup began
+ * @return the value of the property (may be null), or NOT_FOUND
+ */
+ public Object get(String name, Scriptable start)
+ {
+ return getImpl(name, 0, start);
+ }
+
+ /**
+ * Returns the value of the indexed property or NOT_FOUND.
+ *
+ * @param index the numeric index for the property
+ * @param start the object in which the lookup began
+ * @return the value of the property (may be null), or NOT_FOUND
+ */
+ public Object get(int index, Scriptable start)
+ {
+ return getImpl(null, index, start);
+ }
+
+ /**
+ * Sets the value of the named property, creating it if need be.
+ *
+ * If the property was created using defineProperty, the
+ * appropriate setter method is called. <p>
+ *
+ * If the property's attributes include READONLY, no action is
+ * taken.
+ * This method will actually set the property in the start
+ * object.
+ *
+ * @param name the name of the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ */
+ public void put(String name, Scriptable start, Object value)
+ {
+ if (putImpl(name, 0, start, value, EMPTY))
+ return;
+
+ if (start == this) throw Kit.codeBug();
+ start.put(name, start, value);
+ }
+
+ /**
+ * Sets the value of the indexed property, creating it if need be.
+ *
+ * @param index the numeric index for the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ */
+ public void put(int index, Scriptable start, Object value)
+ {
+ if (putImpl(null, index, start, value, EMPTY))
+ return;
+
+ if (start == this) throw Kit.codeBug();
+ start.put(index, start, value);
+ }
+
+ /**
+ * Removes a named property from the object.
+ *
+ * If the property is not found, or it has the PERMANENT attribute,
+ * no action is taken.
+ *
+ * @param name the name of the property
+ */
+ public void delete(String name)
+ {
+ checkNotSealed(name, 0);
+ accessSlot(name, 0, SLOT_REMOVE);
+ }
+
+ /**
+ * Removes the indexed property from the object.
+ *
+ * If the property is not found, or it has the PERMANENT attribute,
+ * no action is taken.
+ *
+ * @param index the numeric index for the property
+ */
+ public void delete(int index)
+ {
+ checkNotSealed(null, index);
+ accessSlot(null, index, SLOT_REMOVE);
+ }
+
+ /**
+ * Sets the value of the named const property, creating it if need be.
+ *
+ * If the property was created using defineProperty, the
+ * appropriate setter method is called. <p>
+ *
+ * If the property's attributes include READONLY, no action is
+ * taken.
+ * This method will actually set the property in the start
+ * object.
+ *
+ * @param name the name of the property
+ * @param start the object whose property is being set
+ * @param value value to set the property to
+ */
+ public void putConst(String name, Scriptable start, Object value)
+ {
+ if (putImpl(name, 0, start, value, READONLY))
+ return;
+
+ if (start == this) throw Kit.codeBug();
+ if (start instanceof ConstProperties)
+ ((ConstProperties)start).putConst(name, start, value);
+ else
+ start.put(name, start, value);
+ }
+
+ public void defineConst(String name, Scriptable start)
+ {
+ if (putImpl(name, 0, start, Undefined.instance, UNINITIALIZED_CONST))
+ return;
+
+ if (start == this) throw Kit.codeBug();
+ if (start instanceof ConstProperties)
+ ((ConstProperties)start).defineConst(name, start);
+ }
+ /**
+ * Returns true if the named property is defined as a const on this object.
+ * @param name
+ * @return true if the named property is defined as a const, false
+ * otherwise.
+ */
+ public boolean isConst(String name)
+ {
+ Slot slot = getSlot(name, 0, SLOT_QUERY);
+ if (slot == null) {
+ return false;
+ }
+ return (slot.getAttributes() & (PERMANENT|READONLY)) ==
+ (PERMANENT|READONLY);
+
+ }
+ /**
+ * @deprecated Use {@link #getAttributes(String name)}. The engine always
+ * ignored the start argument.
+ */
+ public final int getAttributes(String name, Scriptable start)
+ {
+ return getAttributes(name);
+ }
+
+ /**
+ * @deprecated Use {@link #getAttributes(int index)}. The engine always
+ * ignored the start argument.
+ */
+ public final int getAttributes(int index, Scriptable start)
+ {
+ return getAttributes(index);
+ }
+
+ /**
+ * @deprecated Use {@link #setAttributes(String name, int attributes)}.
+ * The engine always ignored the start argument.
+ */
+ public final void setAttributes(String name, Scriptable start,
+ int attributes)
+ {
+ setAttributes(name, attributes);
+ }
+
+ /**
+ * @deprecated Use {@link #setAttributes(int index, int attributes)}.
+ * The engine always ignored the start argument.
+ */
+ public void setAttributes(int index, Scriptable start,
+ int attributes)
+ {
+ setAttributes(index, attributes);
+ }
+
+ /**
+ * Get the attributes of a named property.
+ *
+ * The property is specified by <code>name</code>
+ * as defined for <code>has</code>.<p>
+ *
+ * @param name the identifier for the property
+ * @return the bitset of attributes
+ * @exception EvaluatorException if the named property is not found
+ * @see org.mozilla.javascript.ScriptableObject#has(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#READONLY
+ * @see org.mozilla.javascript.ScriptableObject#DONTENUM
+ * @see org.mozilla.javascript.ScriptableObject#PERMANENT
+ * @see org.mozilla.javascript.ScriptableObject#EMPTY
+ */
+ public int getAttributes(String name)
+ {
+ return findAttributeSlot(name, 0, SLOT_QUERY).getAttributes();
+ }
+
+ /**
+ * Get the attributes of an indexed property.
+ *
+ * @param index the numeric index for the property
+ * @exception EvaluatorException if the named property is not found
+ * is not found
+ * @return the bitset of attributes
+ * @see org.mozilla.javascript.ScriptableObject#has(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#READONLY
+ * @see org.mozilla.javascript.ScriptableObject#DONTENUM
+ * @see org.mozilla.javascript.ScriptableObject#PERMANENT
+ * @see org.mozilla.javascript.ScriptableObject#EMPTY
+ */
+ public int getAttributes(int index)
+ {
+ return findAttributeSlot(null, index, SLOT_QUERY).getAttributes();
+ }
+
+ /**
+ * Set the attributes of a named property.
+ *
+ * The property is specified by <code>name</code>
+ * as defined for <code>has</code>.<p>
+ *
+ * The possible attributes are READONLY, DONTENUM,
+ * and PERMANENT. Combinations of attributes
+ * are expressed by the bitwise OR of attributes.
+ * EMPTY is the state of no attributes set. Any unused
+ * bits are reserved for future use.
+ *
+ * @param name the name of the property
+ * @param attributes the bitset of attributes
+ * @exception EvaluatorException if the named property is not found
+ * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#READONLY
+ * @see org.mozilla.javascript.ScriptableObject#DONTENUM
+ * @see org.mozilla.javascript.ScriptableObject#PERMANENT
+ * @see org.mozilla.javascript.ScriptableObject#EMPTY
+ */
+ public void setAttributes(String name, int attributes)
+ {
+ checkNotSealed(name, 0);
+ findAttributeSlot(name, 0, SLOT_MODIFY).setAttributes(attributes);
+ }
+
+ /**
+ * Set the attributes of an indexed property.
+ *
+ * @param index the numeric index for the property
+ * @param attributes the bitset of attributes
+ * @exception EvaluatorException if the named property is not found
+ * @see org.mozilla.javascript.Scriptable#has(String, Scriptable)
+ * @see org.mozilla.javascript.ScriptableObject#READONLY
+ * @see org.mozilla.javascript.ScriptableObject#DONTENUM
+ * @see org.mozilla.javascript.ScriptableObject#PERMANENT
+ * @see org.mozilla.javascript.ScriptableObject#EMPTY
+ */
+ public void setAttributes(int index, int attributes)
+ {
+ checkNotSealed(null, index);
+ findAttributeSlot(null, index, SLOT_MODIFY).setAttributes(attributes);
+ }
+
+ /**
+ * XXX: write docs.
+ */
+ public void setGetterOrSetter(String name, int index,
+ Callable getterOrSeter, boolean isSetter)
+ {
+ if (name != null && index != 0)
+ throw new IllegalArgumentException(name);
+
+ checkNotSealed(name, index);
+ GetterSlot gslot = (GetterSlot)getSlot(name, index,
+ SLOT_MODIFY_GETTER_SETTER);
+ gslot.checkNotReadonly();
+ if (isSetter) {
+ gslot.setter = getterOrSeter;
+ } else {
+ gslot.getter = getterOrSeter;
+ }
+ gslot.value = Undefined.instance;
+ }
+
+ /**
+ * Get the getter or setter for a given property. Used by __lookupGetter__
+ * and __lookupSetter__.
+ *
+ * @param name Name of the object. If nonnull, index must be 0.
+ * @param index Index of the object. If nonzero, name must be null.
+ * @param isSetter If true, return the setter, otherwise return the getter.
+ * @exception IllegalArgumentException if both name and index are nonnull
+ * and nonzero respectively.
+ * @return Null if the property does not exist. Otherwise returns either
+ * the getter or the setter for the property, depending on
+ * the value of isSetter (may be undefined if unset).
+ */
+ public Object getGetterOrSetter(String name, int index, boolean isSetter)
+ {
+ if (name != null && index != 0)
+ throw new IllegalArgumentException(name);
+ Slot slot = getSlot(name, index, SLOT_QUERY);
+ if (slot == null)
+ return null;
+ if (slot instanceof GetterSlot) {
+ GetterSlot gslot = (GetterSlot)slot;
+ Object result = isSetter ? gslot.setter : gslot.getter;
+ return result != null ? result : Undefined.instance;
+ } else
+ return Undefined.instance;
+ }
+
+ /**
+ * Returns whether a property is a getter or a setter
+ * @param name property name
+ * @param index property index
+ * @param setter true to check for a setter, false for a getter
+ * @return whether the property is a getter or a setter
+ */
+ protected boolean isGetterOrSetter(String name, int index, boolean setter) {
+ Slot slot = getSlot(name, index, SLOT_QUERY);
+ if (slot instanceof GetterSlot) {
+ if (setter && ((GetterSlot)slot).setter != null) return true;
+ if (!setter && ((GetterSlot)slot).getter != null) return true;
+ }
+ return false;
+ }
+
+ void addLazilyInitializedValue(String name, int index,
+ LazilyLoadedCtor init, int attributes)
+ {
+ if (name != null && index != 0)
+ throw new IllegalArgumentException(name);
+ checkNotSealed(name, index);
+ GetterSlot gslot = (GetterSlot)getSlot(name, index,
+ SLOT_MODIFY_GETTER_SETTER);
+ gslot.setAttributes(attributes);
+ gslot.getter = null;
+ gslot.setter = null;
+ gslot.value = init;
+ }
+
+ /**
+ * Returns the prototype of the object.
+ */
+ public Scriptable getPrototype()
+ {
+ return prototypeObject;
+ }
+
+ /**
+ * Sets the prototype of the object.
+ */
+ public void setPrototype(Scriptable m)
+ {
+ prototypeObject = m;
+ }
+
+ /**
+ * Returns the parent (enclosing) scope of the object.
+ */
+ public Scriptable getParentScope()
+ {
+ return parentScopeObject;
+ }
+
+ /**
+ * Sets the parent (enclosing) scope of the object.
+ */
+ public void setParentScope(Scriptable m)
+ {
+ parentScopeObject = m;
+ }
+
+ /**
+ * Returns an array of ids for the properties of the object.
+ *
+ * <p>Any properties with the attribute DONTENUM are not listed. <p>
+ *
+ * @return an array of java.lang.Objects with an entry for every
+ * listed property. Properties accessed via an integer index will
+ * have a corresponding
+ * Integer entry in the returned array. Properties accessed by
+ * a String will have a String entry in the returned array.
+ */
+ public Object[] getIds() {
+ return getIds(false);
+ }
+
+ /**
+ * Returns an array of ids for the properties of the object.
+ *
+ * <p>All properties, even those with attribute DONTENUM, are listed. <p>
+ *
+ * @return an array of java.lang.Objects with an entry for every
+ * listed property. Properties accessed via an integer index will
+ * have a corresponding
+ * Integer entry in the returned array. Properties accessed by
+ * a String will have a String entry in the returned array.
+ */
+ public Object[] getAllIds() {
+ return getIds(true);
+ }
+
+ /**
+ * Implements the [[DefaultValue]] internal method.
+ *
+ * <p>Note that the toPrimitive conversion is a no-op for
+ * every type other than Object, for which [[DefaultValue]]
+ * is called. See ECMA 9.1.<p>
+ *
+ * A <code>hint</code> of null means "no hint".
+ *
+ * @param typeHint the type hint
+ * @return the default value for the object
+ *
+ * See ECMA 8.6.2.6.
+ */
+ public Object getDefaultValue(Class typeHint)
+ {
+ return getDefaultValue(this, typeHint);
+ }
+
+ public static Object getDefaultValue(Scriptable object, Class typeHint)
+ {
+ Context cx = null;
+ for (int i=0; i < 2; i++) {
+ boolean tryToString;
+ if (typeHint == ScriptRuntime.StringClass) {
+ tryToString = (i == 0);
+ } else {
+ tryToString = (i == 1);
+ }
+
+ String methodName;
+ Object[] args;
+ if (tryToString) {
+ methodName = "toString";
+ args = ScriptRuntime.emptyArgs;
+ } else {
+ methodName = "valueOf";
+ args = new Object[1];
+ String hint;
+ if (typeHint == null) {
+ hint = "undefined";
+ } else if (typeHint == ScriptRuntime.StringClass) {
+ hint = "string";
+ } else if (typeHint == ScriptRuntime.ScriptableClass) {
+ hint = "object";
+ } else if (typeHint == ScriptRuntime.FunctionClass) {
+ hint = "function";
+ } else if (typeHint == ScriptRuntime.BooleanClass
+ || typeHint == Boolean.TYPE)
+ {
+ hint = "boolean";
+ } else if (typeHint == ScriptRuntime.NumberClass ||
+ typeHint == ScriptRuntime.ByteClass ||
+ typeHint == Byte.TYPE ||
+ typeHint == ScriptRuntime.ShortClass ||
+ typeHint == Short.TYPE ||
+ typeHint == ScriptRuntime.IntegerClass ||
+ typeHint == Integer.TYPE ||
+ typeHint == ScriptRuntime.FloatClass ||
+ typeHint == Float.TYPE ||
+ typeHint == ScriptRuntime.DoubleClass ||
+ typeHint == Double.TYPE)
+ {
+ hint = "number";
+ } else {
+ throw Context.reportRuntimeError1(
+ "msg.invalid.type", typeHint.toString());
+ }
+ args[0] = hint;
+ }
+ Object v = getProperty(object, methodName);
+ if (!(v instanceof Function))
+ continue;
+ Function fun = (Function) v;
+ if (cx == null)
+ cx = Context.getContext();
+ v = fun.call(cx, fun.getParentScope(), object, args);
+ if (v != null) {
+ if (!(v instanceof Scriptable)) {
+ return v;
+ }
+ if (typeHint == ScriptRuntime.ScriptableClass
+ || typeHint == ScriptRuntime.FunctionClass)
+ {
+ return v;
+ }
+ if (tryToString && v instanceof Wrapper) {
+ // Let a wrapped java.lang.String pass for a primitive
+ // string.
+ Object u = ((Wrapper)v).unwrap();
+ if (u instanceof String)
+ return u;
+ }
+ }
+ }
+ // fall through to error
+ String arg = (typeHint == null) ? "undefined" : typeHint.getName();
+ throw ScriptRuntime.typeError1("msg.default.value", arg);
+ }
+
+ /**
+ * Implements the instanceof operator.
+ *
+ * <p>This operator has been proposed to ECMA.
+ *
+ * @param instance The value that appeared on the LHS of the instanceof
+ * operator
+ * @return true if "this" appears in value's prototype chain
+ *
+ */
+ public boolean hasInstance(Scriptable instance) {
+ // Default for JS objects (other than Function) is to do prototype
+ // chasing. This will be overridden in NativeFunction and non-JS
+ // objects.
+
+ return ScriptRuntime.jsDelegatesTo(instance, this);
+ }
+
+ /**
+ * Emulate the SpiderMonkey (and Firefox) feature of allowing
+ * custom objects to avoid detection by normal "object detection"
+ * code patterns. This is used to implement document.all.
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=412247.
+ * This is an analog to JOF_DETECTING from SpiderMonkey; see
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
+ * Other than this special case, embeddings should return false.
+ * @return true if this object should avoid object detection
+ * @since 1.7R1
+ */
+ public boolean avoidObjectDetection() {
+ return false;
+ }
+
+ /**
+ * Custom <tt>==</tt> operator.
+ * Must return {@link Scriptable#NOT_FOUND} if this object does not
+ * have custom equality operator for the given value,
+ * <tt>Boolean.TRUE</tt> if this object is equivalent to <tt>value</tt>,
+ * <tt>Boolean.FALSE</tt> if this object is not equivalent to
+ * <tt>value</tt>.
+ * <p>
+ * The default implementation returns Boolean.TRUE
+ * if <tt>this == value</tt> or {@link Scriptable#NOT_FOUND} otherwise.
+ * It indicates that by default custom equality is available only if
+ * <tt>value</tt> is <tt>this</tt> in which case true is returned.
+ */
+ protected Object equivalentValues(Object value)
+ {
+ return (this == value) ? Boolean.TRUE : Scriptable.NOT_FOUND;
+ }
+
+ /**
+ * Defines JavaScript objects from a Java class that implements Scriptable.
+ *
+ * If the given class has a method
+ * <pre>
+ * static void init(Context cx, Scriptable scope, boolean sealed);</pre>
+ *
+ * or its compatibility form
+ * <pre>
+ * static void init(Scriptable scope);</pre>
+ *
+ * then it is invoked and no further initialization is done.<p>
+ *
+ * However, if no such a method is found, then the class's constructors and
+ * methods are used to initialize a class in the following manner.<p>
+ *
+ * First, the zero-parameter constructor of the class is called to
+ * create the prototype. If no such constructor exists,
+ * a {@link EvaluatorException} is thrown. <p>
+ *
+ * Next, all methods are scanned for special prefixes that indicate that they
+ * have special meaning for defining JavaScript objects.
+ * These special prefixes are
+ * <ul>
+ * <li><code>jsFunction_</code> for a JavaScript function
+ * <li><code>jsStaticFunction_</code> for a JavaScript function that
+ * is a property of the constructor
+ * <li><code>jsGet_</code> for a getter of a JavaScript property
+ * <li><code>jsSet_</code> for a setter of a JavaScript property
+ * <li><code>jsConstructor</code> for a JavaScript function that
+ * is the constructor
+ * </ul><p>
+ *
+ * If the method's name begins with "jsFunction_", a JavaScript function
+ * is created with a name formed from the rest of the Java method name
+ * following "jsFunction_". So a Java method named "jsFunction_foo" will
+ * define a JavaScript method "foo". Calling this JavaScript function
+ * will cause the Java method to be called. The parameters of the method
+ * must be of number and types as defined by the FunctionObject class.
+ * The JavaScript function is then added as a property
+ * of the prototype. <p>
+ *
+ * If the method's name begins with "jsStaticFunction_", it is handled
+ * similarly except that the resulting JavaScript function is added as a
+ * property of the constructor object. The Java method must be static.
+ *
+ * If the method's name begins with "jsGet_" or "jsSet_", the method is
+ * considered to define a property. Accesses to the defined property
+ * will result in calls to these getter and setter methods. If no
+ * setter is defined, the property is defined as READONLY.<p>
+ *
+ * If the method's name is "jsConstructor", the method is
+ * considered to define the body of the constructor. Only one
+ * method of this name may be defined.
+ * If no method is found that can serve as constructor, a Java
+ * constructor will be selected to serve as the JavaScript
+ * constructor in the following manner. If the class has only one
+ * Java constructor, that constructor is used to define
+ * the JavaScript constructor. If the the class has two constructors,
+ * one must be the zero-argument constructor (otherwise an
+ * {@link EvaluatorException} would have already been thrown
+ * when the prototype was to be created). In this case
+ * the Java constructor with one or more parameters will be used
+ * to define the JavaScript constructor. If the class has three
+ * or more constructors, an {@link EvaluatorException}
+ * will be thrown.<p>
+ *
+ * Finally, if there is a method
+ * <pre>
+ * static void finishInit(Scriptable scope, FunctionObject constructor,
+ * Scriptable prototype)</pre>
+ *
+ * it will be called to finish any initialization. The <code>scope</code>
+ * argument will be passed, along with the newly created constructor and
+ * the newly created prototype.<p>
+ *
+ * @param scope The scope in which to define the constructor.
+ * @param clazz The Java class to use to define the JavaScript objects
+ * and properties.
+ * @exception IllegalAccessException if access is not available
+ * to a reflected class member
+ * @exception InstantiationException if unable to instantiate
+ * the named class
+ * @exception InvocationTargetException if an exception is thrown
+ * during execution of methods of the named class
+ * @see org.mozilla.javascript.Function
+ * @see org.mozilla.javascript.FunctionObject
+ * @see org.mozilla.javascript.ScriptableObject#READONLY
+ * @see org.mozilla.javascript.ScriptableObject
+ * #defineProperty(String, Class, int)
+ */
+ public static void defineClass(Scriptable scope, Class clazz)
+ throws IllegalAccessException, InstantiationException,
+ InvocationTargetException
+ {
+ defineClass(scope, clazz, false, false);
+ }
+
+ /**
+ * Defines JavaScript objects from a Java class, optionally
+ * allowing sealing.
+ *
+ * Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
+ * except that sealing is allowed. An object that is sealed cannot have
+ * properties added or removed. Note that sealing is not allowed in
+ * the current ECMA/ISO language specification, but is likely for
+ * the next version.
+ *
+ * @param scope The scope in which to define the constructor.
+ * @param clazz The Java class to use to define the JavaScript objects
+ * and properties. The class must implement Scriptable.
+ * @param sealed Whether or not to create sealed standard objects that
+ * cannot be modified.
+ * @exception IllegalAccessException if access is not available
+ * to a reflected class member
+ * @exception InstantiationException if unable to instantiate
+ * the named class
+ * @exception InvocationTargetException if an exception is thrown
+ * during execution of methods of the named class
+ * @since 1.4R3
+ */
+ public static void defineClass(Scriptable scope, Class clazz,
+ boolean sealed)
+ throws IllegalAccessException, InstantiationException,
+ InvocationTargetException
+ {
+ defineClass(scope, clazz, sealed, false);
+ }
+
+ /**
+ * Defines JavaScript objects from a Java class, optionally
+ * allowing sealing and mapping of Java inheritance to JavaScript
+ * prototype-based inheritance.
+ *
+ * Similar to <code>defineClass(Scriptable scope, Class clazz)</code>
+ * except that sealing and inheritance mapping are allowed. An object
+ * that is sealed cannot have properties added or removed. Note that
+ * sealing is not allowed in the current ECMA/ISO language specification,
+ * but is likely for the next version.
+ *
+ * @param scope The scope in which to define the constructor.
+ * @param clazz The Java class to use to define the JavaScript objects
+ * and properties. The class must implement Scriptable.
+ * @param sealed Whether or not to create sealed standard objects that
+ * cannot be modified.
+ * @param mapInheritance Whether or not to map Java inheritance to
+ * JavaScript prototype-based inheritance.
+ * @return the class name for the prototype of the specified class
+ * @exception IllegalAccessException if access is not available
+ * to a reflected class member
+ * @exception InstantiationException if unable to instantiate
+ * the named class
+ * @exception InvocationTargetException if an exception is thrown
+ * during execution of methods of the named class
+ * @since 1.6R2
+ */
+ public static String defineClass(Scriptable scope, Class clazz,
+ boolean sealed, boolean mapInheritance)
+ throws IllegalAccessException, InstantiationException,
+ InvocationTargetException
+ {
+ BaseFunction ctor = buildClassCtor(scope, clazz, sealed,
+ mapInheritance);
+ if (ctor == null)
+ return null;
+ String name = ctor.getClassPrototype().getClassName();
+ defineProperty(scope, name, ctor, ScriptableObject.DONTENUM);
+ return name;
+ }
+
+ static BaseFunction buildClassCtor(Scriptable scope, Class clazz,
+ boolean sealed,
+ boolean mapInheritance)
+ throws IllegalAccessException, InstantiationException,
+ InvocationTargetException
+ {
+ Method[] methods = FunctionObject.getMethodList(clazz);
+ for (int i=0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (!method.getName().equals("init"))
+ continue;
+ Class[] parmTypes = method.getParameterTypes();
+ if (parmTypes.length == 3 &&
+ parmTypes[0] == ScriptRuntime.ContextClass &&
+ parmTypes[1] == ScriptRuntime.ScriptableClass &&
+ parmTypes[2] == Boolean.TYPE &&
+ Modifier.isStatic(method.getModifiers()))
+ {
+ Object args[] = { Context.getContext(), scope,
+ sealed ? Boolean.TRUE : Boolean.FALSE };
+ method.invoke(null, args);
+ return null;
+ }
+ if (parmTypes.length == 1 &&
+ parmTypes[0] == ScriptRuntime.ScriptableClass &&
+ Modifier.isStatic(method.getModifiers()))
+ {
+ Object args[] = { scope };
+ method.invoke(null, args);
+ return null;
+ }
+
+ }
+
+ // If we got here, there isn't an "init" method with the right
+ // parameter types.
+
+ Constructor[] ctors = clazz.getConstructors();
+ Constructor protoCtor = null;
+ for (int i=0; i < ctors.length; i++) {
+ if (ctors[i].getParameterTypes().length == 0) {
+ protoCtor = ctors[i];
+ break;
+ }
+ }
+ if (protoCtor == null) {
+ throw Context.reportRuntimeError1(
+ "msg.zero.arg.ctor", clazz.getName());
+ }
+
+ Scriptable proto = (Scriptable) protoCtor.newInstance(ScriptRuntime.emptyArgs);
+ String className = proto.getClassName();
+
+ // Set the prototype's prototype, trying to map Java inheritance to JS
+ // prototype-based inheritance if requested to do so.
+ Scriptable superProto = null;
+ if (mapInheritance) {
+ Class superClass = clazz.getSuperclass();
+ if (ScriptRuntime.ScriptableClass.isAssignableFrom(superClass)
+ && !Modifier.isAbstract(superClass.getModifiers())) {
+ String name = ScriptableObject.defineClass(scope, superClass, sealed, mapInheritance);
+ if (name != null) {
+ superProto = ScriptableObject.getClassPrototype(scope, name);
+ }
+ }
+ }
+ if (superProto == null) {
+ superProto = ScriptableObject.getObjectPrototype(scope);
+ }
+ proto.setPrototype(superProto);
+
+ // Find out whether there are any methods that begin with
+ // "js". If so, then only methods that begin with special
+ // prefixes will be defined as JavaScript entities.
+ final String functionPrefix = "jsFunction_";
+ final String staticFunctionPrefix = "jsStaticFunction_";
+ final String getterPrefix = "jsGet_";
+ final String setterPrefix = "jsSet_";
+ final String ctorName = "jsConstructor";
+
+ Member ctorMember = FunctionObject.findSingleMethod(methods, ctorName);
+
+ if (ctorMember == null) {
+ if (ctors.length == 1) {
+ ctorMember = ctors[0];
+ } else if (ctors.length == 2) {
+ if (ctors[0].getParameterTypes().length == 0)
+ ctorMember = ctors[1];
+ else if (ctors[1].getParameterTypes().length == 0)
+ ctorMember = ctors[0];
+ }
+ if (ctorMember == null) {
+ throw Context.reportRuntimeError1(
+ "msg.ctor.multiple.parms", clazz.getName());
+ }
+ }
+
+ FunctionObject ctor = new FunctionObject(className, ctorMember, scope);
+ if (ctor.isVarArgsMethod()) {
+ throw Context.reportRuntimeError1
+ ("msg.varargs.ctor", ctorMember.getName());
+ }
+ ctor.initAsConstructor(scope, proto);
+
+ Method finishInit = null;
+ for (int i=0; i < methods.length; i++) {
+ if (methods[i] == ctorMember) {
+ continue;
+ }
+ String name = methods[i].getName();
+ if (name.equals("finishInit")) {
+ Class[] parmTypes = methods[i].getParameterTypes();
+ if (parmTypes.length == 3 &&
+ parmTypes[0] == ScriptRuntime.ScriptableClass &&
+ parmTypes[1] == FunctionObject.class &&
+ parmTypes[2] == ScriptRuntime.ScriptableClass &&
+ Modifier.isStatic(methods[i].getModifiers()))
+ {
+ finishInit = methods[i];
+ continue;
+ }
+ }
+ // ignore any compiler generated methods.
+ if (name.indexOf('$') != -1)
+ continue;
+ if (name.equals(ctorName))
+ continue;
+
+ String prefix = null;
+ if (name.startsWith(functionPrefix)) {
+ prefix = functionPrefix;
+ } else if (name.startsWith(staticFunctionPrefix)) {
+ prefix = staticFunctionPrefix;
+ if (!Modifier.isStatic(methods[i].getModifiers())) {
+ throw Context.reportRuntimeError(
+ "jsStaticFunction must be used with static method.");
+ }
+ } else if (name.startsWith(getterPrefix)) {
+ prefix = getterPrefix;
+ } else if (name.startsWith(setterPrefix)) {
+ prefix = setterPrefix;
+ } else {
+ continue;
+ }
+ name = name.substring(prefix.length());
+ if (prefix == setterPrefix)
+ continue; // deal with set when we see get
+ if (prefix == getterPrefix) {
+ if (!(proto instanceof ScriptableObject)) {
+ throw Context.reportRuntimeError2(
+ "msg.extend.scriptable",
+ proto.getClass().toString(), name);
+ }
+ Method setter = FunctionObject.findSingleMethod(
+ methods,
+ setterPrefix + name);
+ int attr = ScriptableObject.PERMANENT |
+ ScriptableObject.DONTENUM |
+ (setter != null ? 0
+ : ScriptableObject.READONLY);
+ ((ScriptableObject) proto).defineProperty(name, null,
+ methods[i], setter,
+ attr);
+ continue;
+ }
+
+ FunctionObject f = new FunctionObject(name, methods[i], proto);
+ if (f.isVarArgsConstructor()) {
+ throw Context.reportRuntimeError1
+ ("msg.varargs.fun", ctorMember.getName());
+ }
+ Scriptable dest = prefix == staticFunctionPrefix
+ ? ctor
+ : proto;
+ defineProperty(dest, name, f, DONTENUM);
+ if (sealed) {
+ f.sealObject();
+ }
+ }
+
+ // Call user code to complete initialization if necessary.
+ if (finishInit != null) {
+ Object[] finishArgs = { scope, ctor, proto };
+ finishInit.invoke(null, finishArgs);
+ }
+
+ // Seal the object if necessary.
+ if (sealed) {
+ ctor.sealObject();
+ if (proto instanceof ScriptableObject) {
+ ((ScriptableObject) proto).sealObject();
+ }
+ }
+
+ return ctor;
+ }
+
+ /**
+ * Define a JavaScript property.
+ *
+ * Creates the property with an initial value and sets its attributes.
+ *
+ * @param propertyName the name of the property to define.
+ * @param value the initial value of the property
+ * @param attributes the attributes of the JavaScript property
+ * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
+ */
+ public void defineProperty(String propertyName, Object value,
+ int attributes)
+ {
+ checkNotSealed(propertyName, 0);
+ put(propertyName, this, value);
+ setAttributes(propertyName, attributes);
+ }
+
+ /**
+ * Utility method to add properties to arbitrary Scriptable object.
+ * If destination is instance of ScriptableObject, calls
+ * defineProperty there, otherwise calls put in destination
+ * ignoring attributes
+ */
+ public static void defineProperty(Scriptable destination,
+ String propertyName, Object value,
+ int attributes)
+ {
+ if (!(destination instanceof ScriptableObject)) {
+ destination.put(propertyName, destination, value);
+ return;
+ }
+ ScriptableObject so = (ScriptableObject)destination;
+ so.defineProperty(propertyName, value, attributes);
+ }
+
+ /**
+ * Utility method to add properties to arbitrary Scriptable object.
+ * If destination is instance of ScriptableObject, calls
+ * defineProperty there, otherwise calls put in destination
+ * ignoring attributes
+ */
+ public static void defineConstProperty(Scriptable destination,
+ String propertyName)
+ {
+ if (destination instanceof ConstProperties) {
+ ConstProperties cp = (ConstProperties)destination;
+ cp.defineConst(propertyName, destination);
+ } else
+ defineProperty(destination, propertyName, Undefined.instance, CONST);
+ }
+
+ /**
+ * Define a JavaScript property with getter and setter side effects.
+ *
+ * If the setter is not found, the attribute READONLY is added to
+ * the given attributes. <p>
+ *
+ * The getter must be a method with zero parameters, and the setter, if
+ * found, must be a method with one parameter.<p>
+ *
+ * @param propertyName the name of the property to define. This name
+ * also affects the name of the setter and getter
+ * to search for. If the propertyId is "foo", then
+ * <code>clazz</code> will be searched for "getFoo"
+ * and "setFoo" methods.
+ * @param clazz the Java class to search for the getter and setter
+ * @param attributes the attributes of the JavaScript property
+ * @see org.mozilla.javascript.Scriptable#put(String, Scriptable, Object)
+ */
+ public void defineProperty(String propertyName, Class clazz,
+ int attributes)
+ {
+ int length = propertyName.length();
+ if (length == 0) throw new IllegalArgumentException();
+ char[] buf = new char[3 + length];
+ propertyName.getChars(0, length, buf, 3);
+ buf[3] = Character.toUpperCase(buf[3]);
+ buf[0] = 'g';
+ buf[1] = 'e';
+ buf[2] = 't';
+ String getterName = new String(buf);
+ buf[0] = 's';
+ String setterName = new String(buf);
+
+ Method[] methods = FunctionObject.getMethodList(clazz);
+ Method getter = FunctionObject.findSingleMethod(methods, getterName);
+ Method setter = FunctionObject.findSingleMethod(methods, setterName);
+ if (setter == null)
+ attributes |= ScriptableObject.READONLY;
+ defineProperty(propertyName, null, getter,
+ setter == null ? null : setter, attributes);
+ }
+
+ /**
+ * Define a JavaScript property.
+ *
+ * Use this method only if you wish to define getters and setters for
+ * a given property in a ScriptableObject. To create a property without
+ * special getter or setter side effects, use
+ * <code>defineProperty(String,int)</code>.
+ *
+ * If <code>setter</code> is null, the attribute READONLY is added to
+ * the given attributes.<p>
+ *
+ * Several forms of getters or setters are allowed. In all cases the
+ * type of the value parameter can be any one of the following types:
+ * Object, String, boolean, Scriptable, byte, short, int, long, float,
+ * or double. The runtime will perform appropriate conversions based
+ * upon the type of the parameter (see description in FunctionObject).
+ * The first forms are nonstatic methods of the class referred to
+ * by 'this':
+ * <pre>
+ * Object getFoo();
+ * void setFoo(SomeType value);</pre>
+ * Next are static methods that may be of any class; the object whose
+ * property is being accessed is passed in as an extra argument:
+ * <pre>
+ * static Object getFoo(Scriptable obj);
+ * static void setFoo(Scriptable obj, SomeType value);</pre>
+ * Finally, it is possible to delegate to another object entirely using
+ * the <code>delegateTo</code> parameter. In this case the methods are
+ * nonstatic methods of the class delegated to, and the object whose
+ * property is being accessed is passed in as an extra argument:
+ * <pre>
+ * Object getFoo(Scriptable obj);
+ * void setFoo(Scriptable obj, SomeType value);</pre>
+ *
+ * @param propertyName the name of the property to define.
+ * @param delegateTo an object to call the getter and setter methods on,
+ * or null, depending on the form used above.
+ * @param getter the method to invoke to get the value of the property
+ * @param setter the method to invoke to set the value of the property
+ * @param attributes the attributes of the JavaScript property
+ */
+ public void defineProperty(String propertyName, Object delegateTo,
+ Method getter, Method setter, int attributes)
+ {
+ MemberBox getterBox = null;
+ if (getter != null) {
+ getterBox = new MemberBox(getter);
+
+ boolean delegatedForm;
+ if (!Modifier.isStatic(getter.getModifiers())) {
+ delegatedForm = (delegateTo != null);
+ getterBox.delegateTo = delegateTo;
+ } else {
+ delegatedForm = true;
+ // Ignore delegateTo for static getter but store
+ // non-null delegateTo indicator.
+ getterBox.delegateTo = Void.TYPE;
+ }
+
+ String errorId = null;
+ Class[] parmTypes = getter.getParameterTypes();
+ if (parmTypes.length == 0) {
+ if (delegatedForm) {
+ errorId = "msg.obj.getter.parms";
+ }
+ } else if (parmTypes.length == 1) {
+ Object argType = parmTypes[0];
+ // Allow ScriptableObject for compatibility
+ if (!(argType == ScriptRuntime.ScriptableClass ||
+ argType == ScriptRuntime.ScriptableObjectClass))
+ {
+ errorId = "msg.bad.getter.parms";
+ } else if (!delegatedForm) {
+ errorId = "msg.bad.getter.parms";
+ }
+ } else {
+ errorId = "msg.bad.getter.parms";
+ }
+ if (errorId != null) {
+ throw Context.reportRuntimeError1(errorId, getter.toString());
+ }
+ }
+
+ MemberBox setterBox = null;
+ if (setter != null) {
+ if (setter.getReturnType() != Void.TYPE)
+ throw Context.reportRuntimeError1("msg.setter.return",
+ setter.toString());
+
+ setterBox = new MemberBox(setter);
+
+ boolean delegatedForm;
+ if (!Modifier.isStatic(setter.getModifiers())) {
+ delegatedForm = (delegateTo != null);
+ setterBox.delegateTo = delegateTo;
+ } else {
+ delegatedForm = true;
+ // Ignore delegateTo for static setter but store
+ // non-null delegateTo indicator.
+ setterBox.delegateTo = Void.TYPE;
+ }
+
+ String errorId = null;
+ Class[] parmTypes = setter.getParameterTypes();
+ if (parmTypes.length == 1) {
+ if (delegatedForm) {
+ errorId = "msg.setter2.expected";
+ }
+ } else if (parmTypes.length == 2) {
+ Object argType = parmTypes[0];
+ // Allow ScriptableObject for compatibility
+ if (!(argType == ScriptRuntime.ScriptableClass ||
+ argType == ScriptRuntime.ScriptableObjectClass))
+ {
+ errorId = "msg.setter2.parms";
+ } else if (!delegatedForm) {
+ errorId = "msg.setter1.parms";
+ }
+ } else {
+ errorId = "msg.setter.parms";
+ }
+ if (errorId != null) {
+ throw Context.reportRuntimeError1(errorId, setter.toString());
+ }
+ }
+
+ GetterSlot gslot = (GetterSlot)getSlot(propertyName, 0,
+ SLOT_MODIFY_GETTER_SETTER);
+ gslot.setAttributes(attributes);
+ gslot.getter = getterBox;
+ gslot.setter = setterBox;
+ }
+
+ /**
+ * Search for names in a class, adding the resulting methods
+ * as properties.
+ *
+ * <p> Uses reflection to find the methods of the given names. Then
+ * FunctionObjects are constructed from the methods found, and
+ * are added to this object as properties with the given names.
+ *
+ * @param names the names of the Methods to add as function properties
+ * @param clazz the class to search for the Methods
+ * @param attributes the attributes of the new properties
+ * @see org.mozilla.javascript.FunctionObject
+ */
+ public void defineFunctionProperties(String[] names, Class clazz,
+ int attributes)
+ {
+ Method[] methods = FunctionObject.getMethodList(clazz);
+ for (int i=0; i < names.length; i++) {
+ String name = names[i];
+ Method m = FunctionObject.findSingleMethod(methods, name);
+ if (m == null) {
+ throw Context.reportRuntimeError2(
+ "msg.method.not.found", name, clazz.getName());
+ }
+ FunctionObject f = new FunctionObject(name, m, this);
+ defineProperty(name, f, attributes);
+ }
+ }
+
+ /**
+ * Get the Object.prototype property.
+ * See ECMA 15.2.4.
+ */
+ public static Scriptable getObjectPrototype(Scriptable scope) {
+ return getClassPrototype(scope, "Object");
+ }
+
+ /**
+ * Get the Function.prototype property.
+ * See ECMA 15.3.4.
+ */
+ public static Scriptable getFunctionPrototype(Scriptable scope) {
+ return getClassPrototype(scope, "Function");
+ }
+
+ /**
+ * Get the prototype for the named class.
+ *
+ * For example, <code>getClassPrototype(s, "Date")</code> will first
+ * walk up the parent chain to find the outermost scope, then will
+ * search that scope for the Date constructor, and then will
+ * return Date.prototype. If any of the lookups fail, or
+ * the prototype is not a JavaScript object, then null will
+ * be returned.
+ *
+ * @param scope an object in the scope chain
+ * @param className the name of the constructor
+ * @return the prototype for the named class, or null if it
+ * cannot be found.
+ */
+ public static Scriptable getClassPrototype(Scriptable scope,
+ String className)
+ {
+ scope = getTopLevelScope(scope);
+ Object ctor = getProperty(scope, className);
+ Object proto;
+ if (ctor instanceof BaseFunction) {
+ proto = ((BaseFunction)ctor).getPrototypeProperty();
+ } else if (ctor instanceof Scriptable) {
+ Scriptable ctorObj = (Scriptable)ctor;
+ proto = ctorObj.get("prototype", ctorObj);
+ } else {
+ return null;
+ }
+ if (proto instanceof Scriptable) {
+ return (Scriptable)proto;
+ }
+ return null;
+ }
+
+ /**
+ * Get the global scope.
+ *
+ * <p>Walks the parent scope chain to find an object with a null
+ * parent scope (the global object).
+ *
+ * @param obj a JavaScript object
+ * @return the corresponding global scope
+ */
+ public static Scriptable getTopLevelScope(Scriptable obj)
+ {
+ for (;;) {
+ Scriptable parent = obj.getParentScope();
+ if (parent == null) {
+ return obj;
+ }
+ obj = parent;
+ }
+ }
+
+ // APPJET
+ public static Scriptable getVeryTopLevelScope(Scriptable obj) {
+ return ScriptRuntime.getLibraryScopeOrNull(obj);
+ }
+
+ /**
+ * Seal this object.
+ *
+ * A sealed object may not have properties added or removed. Once
+ * an object is sealed it may not be unsealed.
+ *
+ * @since 1.4R3
+ */
+ public synchronized void sealObject() {
+ if (count >= 0) {
+ count = ~count;
+ }
+ }
+
+ /**
+ * Return true if this object is sealed.
+ *
+ * It is an error to attempt to add or remove properties to
+ * a sealed object.
+ *
+ * @return true if sealed, false otherwise.
+ * @since 1.4R3
+ */
+ public final boolean isSealed() {
+ return count < 0;
+ }
+
+ private void checkNotSealed(String name, int index)
+ {
+ if (!isSealed())
+ return;
+
+ String str = (name != null) ? name : Integer.toString(index);
+ throw Context.reportRuntimeError1("msg.modify.sealed", str);
+ }
+
+ /**
+ * Gets a named property from an object or any object in its prototype chain.
+ * <p>
+ * Searches the prototype chain for a property named <code>name</code>.
+ * <p>
+ * @param obj a JavaScript object
+ * @param name a property name
+ * @return the value of a property with name <code>name</code> found in
+ * <code>obj</code> or any object in its prototype chain, or
+ * <code>Scriptable.NOT_FOUND</code> if not found
+ * @since 1.5R2
+ */
+ public static Object getProperty(Scriptable obj, String name)
+ {
+ Scriptable start = obj;
+ Object result;
+ do {
+ result = obj.get(name, start);
+ if (result != Scriptable.NOT_FOUND)
+ break;
+ obj = obj.getPrototype();
+ } while (obj != null);
+ return result;
+ }
+
+ /**
+ * Gets an indexed property from an object or any object in its prototype chain.
+ * <p>
+ * Searches the prototype chain for a property with integral index
+ * <code>index</code>. Note that if you wish to look for properties with numerical
+ * but non-integral indicies, you should use getProperty(Scriptable,String) with
+ * the string value of the index.
+ * <p>
+ * @param obj a JavaScript object
+ * @param index an integral index
+ * @return the value of a property with index <code>index</code> found in
+ * <code>obj</code> or any object in its prototype chain, or
+ * <code>Scriptable.NOT_FOUND</code> if not found
+ * @since 1.5R2
+ */
+ public static Object getProperty(Scriptable obj, int index)
+ {
+ Scriptable start = obj;
+ Object result;
+ do {
+ result = obj.get(index, start);
+ if (result != Scriptable.NOT_FOUND)
+ break;
+ obj = obj.getPrototype();
+ } while (obj != null);
+ return result;
+ }
+
+ /**
+ * Returns whether a named property is defined in an object or any object
+ * in its prototype chain.
+ * <p>
+ * Searches the prototype chain for a property named <code>name</code>.
+ * <p>
+ * @param obj a JavaScript object
+ * @param name a property name
+ * @return the true if property was found
+ * @since 1.5R2
+ */
+ public static boolean hasProperty(Scriptable obj, String name)
+ {
+ return null != getBase(obj, name);
+ }
+
+ /**
+ * If hasProperty(obj, name) would return true, then if the property that
+ * was found is compatible with the new property, this method just returns.
+ * If the property is not compatible, then an exception is thrown.
+ *
+ * A property redefinition is incompatible if the first definition was a
+ * const declaration or if this one is. They are compatible only if neither
+ * was const.
+ */
+ public static void redefineProperty(Scriptable obj, String name,
+ boolean isConst)
+ {
+ Scriptable base = getBase(obj, name);
+ if (base == null)
+ return;
+ if (base instanceof ConstProperties) {
+ ConstProperties cp = (ConstProperties)base;
+
+ if (cp.isConst(name))
+ throw Context.reportRuntimeError1("msg.const.redecl", name);
+ }
+ if (isConst)
+ throw Context.reportRuntimeError1("msg.var.redecl", name);
+ }
+ /**
+ * Returns whether an indexed property is defined in an object or any object
+ * in its prototype chain.
+ * <p>
+ * Searches the prototype chain for a property with index <code>index</code>.
+ * <p>
+ * @param obj a JavaScript object
+ * @param index a property index
+ * @return the true if property was found
+ * @since 1.5R2
+ */
+ public static boolean hasProperty(Scriptable obj, int index)
+ {
+ return null != getBase(obj, index);
+ }
+
+ /**
+ * Puts a named property in an object or in an object in its prototype chain.
+ * <p>
+ * Searches for the named property in the prototype chain. If it is found,
+ * the value of the property in <code>obj</code> is changed through a call
+ * to {@link Scriptable#put(String, Scriptable, Object)} on the
+ * prototype passing <code>obj</code> as the <code>start</code> argument.
+ * This allows the prototype to veto the property setting in case the
+ * prototype defines the property with [[ReadOnly]] attribute. If the
+ * property is not found, it is added in <code>obj</code>.
+ * @param obj a JavaScript object
+ * @param name a property name
+ * @param value any JavaScript value accepted by Scriptable.put
+ * @since 1.5R2
+ */
+ public static void putProperty(Scriptable obj, String name, Object value)
+ {
+ Scriptable base = getBase(obj, name);
+ if (base == null)
+ base = obj;
+ base.put(name, obj, value);
+ }
+
+ /**
+ * Puts a named property in an object or in an object in its prototype chain.
+ * <p>
+ * Searches for the named property in the prototype chain. If it is found,
+ * the value of the property in <code>obj</code> is changed through a call
+ * to {@link Scriptable#put(String, Scriptable, Object)} on the
+ * prototype passing <code>obj</code> as the <code>start</code> argument.
+ * This allows the prototype to veto the property setting in case the
+ * prototype defines the property with [[ReadOnly]] attribute. If the
+ * property is not found, it is added in <code>obj</code>.
+ * @param obj a JavaScript object
+ * @param name a property name
+ * @param value any JavaScript value accepted by Scriptable.put
+ * @since 1.5R2
+ */
+ public static void putConstProperty(Scriptable obj, String name, Object value)
+ {
+ Scriptable base = getBase(obj, name);
+ if (base == null)
+ base = obj;
+ if (base instanceof ConstProperties)
+ ((ConstProperties)base).putConst(name, obj, value);
+ }
+
+ /**
+ * Puts an indexed property in an object or in an object in its prototype chain.
+ * <p>
+ * Searches for the indexed property in the prototype chain. If it is found,
+ * the value of the property in <code>obj</code> is changed through a call
+ * to {@link Scriptable#put(int, Scriptable, Object)} on the prototype
+ * passing <code>obj</code> as the <code>start</code> argument. This allows
+ * the prototype to veto the property setting in case the prototype defines
+ * the property with [[ReadOnly]] attribute. If the property is not found,
+ * it is added in <code>obj</code>.
+ * @param obj a JavaScript object
+ * @param index a property index
+ * @param value any JavaScript value accepted by Scriptable.put
+ * @since 1.5R2
+ */
+ public static void putProperty(Scriptable obj, int index, Object value)
+ {
+ Scriptable base = getBase(obj, index);
+ if (base == null)
+ base = obj;
+ base.put(index, obj, value);
+ }
+
+ /**
+ * Removes the property from an object or its prototype chain.
+ * <p>
+ * Searches for a property with <code>name</code> in obj or
+ * its prototype chain. If it is found, the object's delete
+ * method is called.
+ * @param obj a JavaScript object
+ * @param name a property name
+ * @return true if the property doesn't exist or was successfully removed
+ * @since 1.5R2
+ */
+ public static boolean deleteProperty(Scriptable obj, String name)
+ {
+ Scriptable base = getBase(obj, name);
+ if (base == null)
+ return true;
+ base.delete(name);
+ return !base.has(name, obj);
+ }
+
+ /**
+ * Removes the property from an object or its prototype chain.
+ * <p>
+ * Searches for a property with <code>index</code> in obj or
+ * its prototype chain. If it is found, the object's delete
+ * method is called.
+ * @param obj a JavaScript object
+ * @param index a property index
+ * @return true if the property doesn't exist or was successfully removed
+ * @since 1.5R2
+ */
+ public static boolean deleteProperty(Scriptable obj, int index)
+ {
+ Scriptable base = getBase(obj, index);
+ if (base == null)
+ return true;
+ base.delete(index);
+ return !base.has(index, obj);
+ }
+
+ /**
+ * Returns an array of all ids from an object and its prototypes.
+ * <p>
+ * @param obj a JavaScript object
+ * @return an array of all ids from all object in the prototype chain.
+ * If a given id occurs multiple times in the prototype chain,
+ * it will occur only once in this list.
+ * @since 1.5R2
+ */
+ public static Object[] getPropertyIds(Scriptable obj)
+ {
+ if (obj == null) {
+ return ScriptRuntime.emptyArgs;
+ }
+ Object[] result = obj.getIds();
+ ObjToIntMap map = null;
+ for (;;) {
+ obj = obj.getPrototype();
+ if (obj == null) {
+ break;
+ }
+ Object[] ids = obj.getIds();
+ if (ids.length == 0) {
+ continue;
+ }
+ if (map == null) {
+ if (result.length == 0) {
+ result = ids;
+ continue;
+ }
+ map = new ObjToIntMap(result.length + ids.length);
+ for (int i = 0; i != result.length; ++i) {
+ map.intern(result[i]);
+ }
+ result = null; // Allow to GC the result
+ }
+ for (int i = 0; i != ids.length; ++i) {
+ map.intern(ids[i]);
+ }
+ }
+ if (map != null) {
+ result = map.getKeys();
+ }
+ return result;
+ }
+
+ /**
+ * Call a method of an object.
+ * @param obj the JavaScript object
+ * @param methodName the name of the function property
+ * @param args the arguments for the call
+ *
+ * @see Context#getCurrentContext()
+ */
+ public static Object callMethod(Scriptable obj, String methodName,
+ Object[] args)
+ {
+ return callMethod(null, obj, methodName, args);
+ }
+
+ /**
+ * Call a method of an object.
+ * @param cx the Context object associated with the current thread.
+ * @param obj the JavaScript object
+ * @param methodName the name of the function property
+ * @param args the arguments for the call
+ */
+ public static Object callMethod(Context cx, Scriptable obj,
+ String methodName,
+ Object[] args)
+ {
+ Object funObj = getProperty(obj, methodName);
+ if (!(funObj instanceof Function)) {
+ throw ScriptRuntime.notFunctionError(obj, methodName);
+ }
+ Function fun = (Function)funObj;
+ // XXX: What should be the scope when calling funObj?
+ // The following favor scope stored in the object on the assumption
+ // that is more useful especially under dynamic scope setup.
+ // An alternative is to check for dynamic scope flag
+ // and use ScriptableObject.getTopLevelScope(fun) if the flag is not
+ // set. But that require access to Context and messy code
+ // so for now it is not checked.
+ Scriptable scope = ScriptableObject.getTopLevelScope(obj);
+ if (cx != null) {
+ return fun.call(cx, scope, obj, args);
+ } else {
+ return Context.call(null, fun, scope, obj, args);
+ }
+ }
+
+ private static Scriptable getBase(Scriptable obj, String name)
+ {
+ do {
+ if (obj.has(name, obj))
+ break;
+ obj = obj.getPrototype();
+ } while(obj != null);
+ return obj;
+ }
+
+ private static Scriptable getBase(Scriptable obj, int index)
+ {
+ do {
+ if (obj.has(index, obj))
+ break;
+ obj = obj.getPrototype();
+ } while(obj != null);
+ return obj;
+ }
+
+ /**
+ * Get arbitrary application-specific value associated with this object.
+ * @param key key object to select particular value.
+ * @see #associateValue(Object key, Object value)
+ */
+ public final Object getAssociatedValue(Object key)
+ {
+ Hashtable h = associatedValues;
+ if (h == null)
+ return null;
+ return h.get(key);
+ }
+
+ /**
+ * Get arbitrary application-specific value associated with the top scope
+ * of the given scope.
+ * The method first calls {@link #getTopLevelScope(Scriptable scope)}
+ * and then searches the prototype chain of the top scope for the first
+ * object containing the associated value with the given key.
+ *
+ * @param scope the starting scope.
+ * @param key key object to select particular value.
+ * @see #getAssociatedValue(Object key)
+ */
+ public static Object getTopScopeValue(Scriptable scope, Object key)
+ {
+ scope = ScriptableObject.getTopLevelScope(scope);
+ for (;;) {
+ if (scope instanceof ScriptableObject) {
+ ScriptableObject so = (ScriptableObject)scope;
+ Object value = so.getAssociatedValue(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ scope = scope.getPrototype();
+ if (scope == null) {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Associate arbitrary application-specific value with this object.
+ * Value can only be associated with the given object and key only once.
+ * The method ignores any subsequent attempts to change the already
+ * associated value.
+ * <p> The associated values are not serialized.
+ * @param key key object to select particular value.
+ * @param value the value to associate
+ * @return the passed value if the method is called first time for the
+ * given key or old value for any subsequent calls.
+ * @see #getAssociatedValue(Object key)
+ */
+ public final Object associateValue(Object key, Object value)
+ {
+ if (value == null) throw new IllegalArgumentException();
+ Hashtable h = associatedValues;
+ if (h == null) {
+ synchronized (this) {
+ h = associatedValues;
+ if (h == null) {
+ h = new Hashtable();
+ associatedValues = h;
+ }
+ }
+ }
+ return Kit.initHash(h, key, value);
+ }
+
+ private Object getImpl(String name, int index, Scriptable start)
+ {
+ Slot slot = getSlot(name, index, SLOT_QUERY);
+ if (slot == null) {
+ return Scriptable.NOT_FOUND;
+ }
+ if (!(slot instanceof GetterSlot)) {
+ return slot.value;
+ }
+ Object getterObj = ((GetterSlot)slot).getter;
+ if (getterObj != null) {
+ if (getterObj instanceof MemberBox) {
+ MemberBox nativeGetter = (MemberBox)getterObj;
+ Object getterThis;
+ Object[] args;
+ if (nativeGetter.delegateTo == null) {
+ getterThis = start;
+ args = ScriptRuntime.emptyArgs;
+ } else {
+ getterThis = nativeGetter.delegateTo;
+ args = new Object[] { start };
+ }
+ return nativeGetter.invoke(getterThis, args);
+ } else {
+ Function f = (Function)getterObj;
+ Context cx = Context.getContext();
+ return f.call(cx, f.getParentScope(), start,
+ ScriptRuntime.emptyArgs);
+ }
+ }
+ Object value = slot.value;
+ if (value instanceof LazilyLoadedCtor) {
+ LazilyLoadedCtor initializer = (LazilyLoadedCtor)value;
+ try {
+ initializer.init();
+ } finally {
+ value = initializer.getValue();
+ slot.value = value;
+ }
+ }
+ return value;
+ }
+
+ /**
+ *
+ * @param name
+ * @param index
+ * @param start
+ * @param value
+ * @param constFlag EMPTY means normal put. UNINITIALIZED_CONST means
+ * defineConstProperty. READONLY means const initialization expression.
+ * @return false if this != start and no slot was found. true if this == start
+ * or this != start and a READONLY slot was found.
+ */
+ private boolean putImpl(String name, int index, Scriptable start,
+ Object value, int constFlag)
+ {
+ Slot slot;
+ if (this != start) {
+ slot = getSlot(name, index, SLOT_QUERY);
+ if (slot == null) {
+ return false;
+ }
+ } else {
+ checkNotSealed(name, index);
+ // either const hoisted declaration or initialization
+ if (constFlag != EMPTY) {
+ slot = getSlot(name, index, SLOT_MODIFY_CONST);
+ int attr = slot.getAttributes();
+ if ((attr & READONLY) == 0)
+ throw Context.reportRuntimeError1("msg.var.redecl", name);
+ if ((attr & UNINITIALIZED_CONST) != 0) {
+ slot.value = value;
+ // clear the bit on const initialization
+ if (constFlag != UNINITIALIZED_CONST)
+ slot.setAttributes(attr & ~UNINITIALIZED_CONST);
+ }
+ return true;
+ }
+ slot = getSlot(name, index, SLOT_MODIFY);
+ }
+ if ((slot.getAttributes() & READONLY) != 0)
+ return true;
+ if (slot instanceof GetterSlot) {
+ Object setterObj = ((GetterSlot)slot).setter;
+ if (setterObj != null) {
+ Context cx = Context.getContext();
+ if (setterObj instanceof MemberBox) {
+ MemberBox nativeSetter = (MemberBox)setterObj;
+ Class pTypes[] = nativeSetter.argTypes;
+ // XXX: cache tag since it is already calculated in
+ // defineProperty ?
+ Class valueType = pTypes[pTypes.length - 1];
+ int tag = FunctionObject.getTypeTag(valueType);
+ Object actualArg = FunctionObject.convertArg(cx, start,
+ value, tag);
+ Object setterThis;
+ Object[] args;
+ if (nativeSetter.delegateTo == null) {
+ setterThis = start;
+ args = new Object[] { actualArg };
+ } else {
+ setterThis = nativeSetter.delegateTo;
+ args = new Object[] { start, actualArg };
+ }
+ nativeSetter.invoke(setterThis, args);
+ } else {
+ Function f = (Function)setterObj;
+ f.call(cx, f.getParentScope(), start,
+ new Object[] { value });
+ }
+ return true;
+ }
+ }
+ if (this == start) {
+ slot.value = value;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private Slot findAttributeSlot(String name, int index, int accessType)
+ {
+ Slot slot = getSlot(name, index, accessType);
+ if (slot == null) {
+ String str = (name != null ? name : Integer.toString(index));
+ throw Context.reportRuntimeError1("msg.prop.not.found", str);
+ }
+ return slot;
+ }
+
+ /**
+ * Locate the slot with given name or index.
+ *
+ * @param name property name or null if slot holds spare array index.
+ * @param index index or 0 if slot holds property name.
+ */
+ private Slot getSlot(String name, int index, int accessType)
+ {
+ Slot slot;
+
+ // Query last access cache and check that it was not deleted.
+ lastAccessCheck:
+ {
+ slot = lastAccess;
+ if (name != null) {
+ if (name != slot.name)
+ break lastAccessCheck;
+ // No String.equals here as successful slot search update
+ // name object with fresh reference of the same string.
+ } else {
+ if (slot.name != null || index != slot.indexOrHash)
+ break lastAccessCheck;
+ }
+
+ if (slot.wasDeleted != 0)
+ break lastAccessCheck;
+
+ if (accessType == SLOT_MODIFY_GETTER_SETTER &&
+ !(slot instanceof GetterSlot))
+ break lastAccessCheck;
+
+ return slot;
+ }
+
+ slot = accessSlot(name, index, accessType);
+ if (slot != null) {
+ // Update the cache
+ lastAccess = slot;
+ }
+ return slot;
+ }
+
+ private Slot accessSlot(String name, int index, int accessType)
+ {
+ int indexOrHash = (name != null ? name.hashCode() : index);
+
+ if (accessType == SLOT_QUERY ||
+ accessType == SLOT_MODIFY ||
+ accessType == SLOT_MODIFY_CONST ||
+ accessType == SLOT_MODIFY_GETTER_SETTER)
+ {
+ // Check the hashtable without using synchronization
+
+ Slot[] slotsLocalRef = slots; // Get stable local reference
+ if (slotsLocalRef == null) {
+ if (accessType == SLOT_QUERY)
+ return null;
+ } else {
+ int tableSize = slotsLocalRef.length;
+ int slotIndex = getSlotIndex(tableSize, indexOrHash);
+ Slot slot = slotsLocalRef[slotIndex];
+ while (slot != null) {
+ String sname = slot.name;
+ if (sname != null) {
+ if (sname == name)
+ break;
+ if (name != null && indexOrHash == slot.indexOrHash) {
+ if (name.equals(sname)) {
+ // This will avoid calling String.equals when
+ // slot is accessed with same string object
+ // next time.
+ slot.name = name;
+ break;
+ }
+ }
+ } else if (name == null &&
+ indexOrHash == slot.indexOrHash) {
+ break;
+ }
+ slot = slot.next;
+ }
+ if (accessType == SLOT_QUERY) {
+ return slot;
+ } else if (accessType == SLOT_MODIFY) {
+ if (slot != null)
+ return slot;
+ } else if (accessType == SLOT_MODIFY_GETTER_SETTER) {
+ if (slot instanceof GetterSlot)
+ return slot;
+ } else if (accessType == SLOT_MODIFY_CONST) {
+ if (slot != null)
+ return slot;
+ }
+ }
+
+ // A new slot has to be inserted or the old has to be replaced
+ // by GetterSlot. Time to synchronize.
+
+ synchronized (this) {
+ // Refresh local ref if another thread triggered grow
+ slotsLocalRef = slots;
+ int insertPos;
+ if (count == 0) {
+ // Always throw away old slots if any on empty insert
+ slotsLocalRef = new Slot[5];
+ slots = slotsLocalRef;
+ insertPos = getSlotIndex(slotsLocalRef.length, indexOrHash);
+ } else {
+ int tableSize = slotsLocalRef.length;
+ insertPos = getSlotIndex(tableSize, indexOrHash);
+ Slot prev = slotsLocalRef[insertPos];
+ Slot slot = prev;
+ while (slot != null) {
+ if (slot.indexOrHash == indexOrHash &&
+ (slot.name == name ||
+ (name != null && name.equals(slot.name))))
+ {
+ break;
+ }
+ prev = slot;
+ slot = slot.next;
+ }
+
+ if (slot != null) {
+ // Another thread just added a slot with same
+ // name/index before this one entered synchronized
+ // block. This is a race in application code and
+ // probably indicates bug there. But for the hashtable
+ // implementation it is harmless with the only
+ // complication is the need to replace the added slot
+ // if we need GetterSlot and the old one is not.
+ if (accessType == SLOT_MODIFY_GETTER_SETTER &&
+ !(slot instanceof GetterSlot))
+ {
+ GetterSlot newSlot = new GetterSlot(name, indexOrHash,
+ slot.getAttributes());
+ newSlot.value = slot.value;
+ newSlot.next = slot.next;
+ if (prev == slot) {
+ slotsLocalRef[insertPos] = newSlot;
+ } else {
+ prev.next = newSlot;
+ }
+ slot.wasDeleted = (byte)1;
+ if (slot == lastAccess) {
+ lastAccess = REMOVED;
+ }
+ slot = newSlot;
+ } else if (accessType == SLOT_MODIFY_CONST) {
+ return null;
+ }
+ return slot;
+ }
+
+ // Check if the table is not too full before inserting.
+ if (4 * (count + 1) > 3 * slotsLocalRef.length) {
+ slotsLocalRef = new Slot[slotsLocalRef.length * 2 + 1];
+ copyTable(slots, slotsLocalRef, count);
+ slots = slotsLocalRef;
+ insertPos = getSlotIndex(slotsLocalRef.length,
+ indexOrHash);
+ }
+ }
+
+ Slot newSlot = (accessType == SLOT_MODIFY_GETTER_SETTER
+ ? new GetterSlot(name, indexOrHash, 0)
+ : new Slot(name, indexOrHash, 0));
+ if (accessType == SLOT_MODIFY_CONST)
+ newSlot.setAttributes(CONST);
+ ++count;
+ addKnownAbsentSlot(slotsLocalRef, newSlot, insertPos);
+ return newSlot;
+ }
+
+ } else if (accessType == SLOT_REMOVE) {
+ synchronized (this) {
+ Slot[] slotsLocalRef = slots;
+ if (count != 0) {
+ int tableSize = slots.length;
+ int slotIndex = getSlotIndex(tableSize, indexOrHash);
+ Slot prev = slotsLocalRef[slotIndex];
+ Slot slot = prev;
+ while (slot != null) {
+ if (slot.indexOrHash == indexOrHash &&
+ (slot.name == name ||
+ (name != null && name.equals(slot.name))))
+ {
+ break;
+ }
+ prev = slot;
+ slot = slot.next;
+ }
+ if (slot != null && (slot.getAttributes() & PERMANENT) == 0) {
+ count--;
+ if (prev == slot) {
+ slotsLocalRef[slotIndex] = slot.next;
+ } else {
+ prev.next = slot.next;
+ }
+ // Mark the slot as removed to handle a case when
+ // another thread manages to put just removed slot
+ // into lastAccess cache.
+ slot.wasDeleted = (byte)1;
+ if (slot == lastAccess) {
+ lastAccess = REMOVED;
+ }
+ }
+ }
+ }
+ return null;
+
+ } else {
+ throw Kit.codeBug();
+ }
+ }
+
+ private static int getSlotIndex(int tableSize, int indexOrHash)
+ {
+ return (indexOrHash & 0x7fffffff) % tableSize;
+ }
+
+ // Must be inside synchronized (this)
+ private static void copyTable(Slot[] slots, Slot[] newSlots, int count)
+ {
+ if (count == 0) throw Kit.codeBug();
+
+ int tableSize = newSlots.length;
+ int i = slots.length;
+ for (;;) {
+ --i;
+ Slot slot = slots[i];
+ while (slot != null) {
+ int insertPos = getSlotIndex(tableSize, slot.indexOrHash);
+ Slot next = slot.next;
+ addKnownAbsentSlot(newSlots, slot, insertPos);
+ slot.next = null;
+ slot = next;
+ if (--count == 0)
+ return;
+ }
+ }
+ }
+
+ /**
+ * Add slot with keys that are known to absent from the table.
+ * This is an optimization to use when inserting into empty table,
+ * after table growth or during deserialization.
+ */
+ private static void addKnownAbsentSlot(Slot[] slots, Slot slot, int insertPos)
+ {
+ if (slots[insertPos] == null) {
+ slots[insertPos] = slot;
+ } else {
+ Slot prev = slots[insertPos];
+ while (prev.next != null) {
+ prev = prev.next;
+ }
+ prev.next = slot;
+ }
+ }
+
+ Object[] getIds(boolean getAll) {
+ Slot[] s = slots;
+ Object[] a = ScriptRuntime.emptyArgs;
+ if (s == null)
+ return a;
+ int c = 0;
+ for (int i=0; i < s.length; i++) {
+ Slot slot = s[i];
+ while (slot != null) {
+ if (getAll || (slot.getAttributes() & DONTENUM) == 0) {
+ if (c == 0)
+ a = new Object[s.length];
+ a[c++] = (slot.name != null ? (Object) slot.name
+ : new Integer(slot.indexOrHash));
+ }
+ slot = slot.next;
+ }
+ }
+ if (c == a.length)
+ return a;
+ Object[] result = new Object[c];
+ System.arraycopy(a, 0, result, 0, c);
+ return result;
+ }
+
+ private synchronized void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+ int objectsCount = count;
+ if (objectsCount < 0) {
+ // "this" was sealed
+ objectsCount = ~objectsCount;
+ }
+ if (objectsCount == 0) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(slots.length);
+ for (int i = 0; i < slots.length; ++i) {
+ Slot slot = slots[i];
+ while (slot != null) {
+ out.writeObject(slot);
+ slot = slot.next;
+ if (--objectsCount == 0)
+ return;
+ }
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ lastAccess = REMOVED;
+
+ int tableSize = in.readInt();
+ if (tableSize != 0) {
+ slots = new Slot[tableSize];
+ int objectsCount = count;
+ if (objectsCount < 0) {
+ // "this" was sealed
+ objectsCount = ~objectsCount;
+ }
+ for (int i = 0; i != objectsCount; ++i) {
+ Slot slot = (Slot)in.readObject();
+ int slotIndex = getSlotIndex(tableSize, slot.indexOrHash);
+ addKnownAbsentSlot(slots, slot, slotIndex);
+ }
+ }
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java
new file mode 100644
index 0000000..bc8ed86
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecureCaller.java
@@ -0,0 +1,198 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * @author Attila Szegedi
+ */
+public abstract class SecureCaller
+{
+ private static final byte[] secureCallerImplBytecode = loadBytecode();
+
+ // We're storing a CodeSource -> (ClassLoader -> SecureRenderer), since we
+ // need to have one renderer per class loader. We're using weak hash maps
+ // and soft references all the way, since we don't want to interfere with
+ // cleanup of either CodeSource or ClassLoader objects.
+ private static final Map callers = new WeakHashMap();
+
+ public abstract Object call(Callable callable, Context cx,
+ Scriptable scope, Scriptable thisObj, Object[] args);
+
+ /**
+ * Call the specified callable using a protection domain belonging to the
+ * specified code source.
+ */
+ static Object callSecurely(final CodeSource codeSource, Callable callable,
+ Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
+ {
+ final Thread thread = Thread.currentThread();
+ // Run in doPrivileged as we might be checked for "getClassLoader"
+ // runtime permission
+ final ClassLoader classLoader = (ClassLoader)AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return thread.getContextClassLoader();
+ }
+ });
+ Map classLoaderMap;
+ synchronized(callers)
+ {
+ classLoaderMap = (Map)callers.get(codeSource);
+ if(classLoaderMap == null)
+ {
+ classLoaderMap = new WeakHashMap();
+ callers.put(codeSource, classLoaderMap);
+ }
+ }
+ SecureCaller caller;
+ synchronized(classLoaderMap)
+ {
+ SoftReference ref = (SoftReference)classLoaderMap.get(classLoader);
+ if(ref != null)
+ {
+ caller = (SecureCaller)ref.get();
+ }
+ else
+ {
+ caller = null;
+ }
+ if(caller == null)
+ {
+ try
+ {
+ // Run in doPrivileged as we'll be checked for
+ // "createClassLoader" runtime permission
+ caller = (SecureCaller)AccessController.doPrivileged(
+ new PrivilegedExceptionAction()
+ {
+ public Object run() throws Exception
+ {
+ ClassLoader effectiveClassLoader;
+ Class thisClass = getClass();
+ if(classLoader.loadClass(thisClass.getName()) != thisClass) {
+ effectiveClassLoader = thisClass.getClassLoader();
+ } else {
+ effectiveClassLoader = classLoader;
+ }
+ SecureClassLoaderImpl secCl =
+ new SecureClassLoaderImpl(effectiveClassLoader);
+ Class c = secCl.defineAndLinkClass(
+ SecureCaller.class.getName() + "Impl",
+ secureCallerImplBytecode, codeSource);
+ return c.newInstance();
+ }
+ });
+ classLoaderMap.put(classLoader, new SoftReference(caller));
+ }
+ catch(PrivilegedActionException ex)
+ {
+ throw new UndeclaredThrowableException(ex.getCause());
+ }
+ }
+ }
+ return caller.call(callable, cx, scope, thisObj, args);
+ }
+
+ private static class SecureClassLoaderImpl extends SecureClassLoader
+ {
+ SecureClassLoaderImpl(ClassLoader parent)
+ {
+ super(parent);
+ }
+
+ Class defineAndLinkClass(String name, byte[] bytes, CodeSource cs)
+ {
+ Class cl = defineClass(name, bytes, 0, bytes.length, cs);
+ resolveClass(cl);
+ return cl;
+ }
+ }
+
+ private static byte[] loadBytecode()
+ {
+ return (byte[])AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return loadBytecodePrivileged();
+ }
+ });
+ }
+
+ private static byte[] loadBytecodePrivileged()
+ {
+ URL url = SecureCaller.class.getResource("SecureCallerImpl.clazz");
+ try
+ {
+ InputStream in = url.openStream();
+ try
+ {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ for(;;)
+ {
+ int r = in.read();
+ if(r == -1)
+ {
+ return bout.toByteArray();
+ }
+ bout.write(r);
+ }
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+ catch(IOException e)
+ {
+ throw new UndeclaredThrowableException(e);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java
new file mode 100644
index 0000000..ed85dbf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java
@@ -0,0 +1,211 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This class describes the support needed to implement security.
+ * <p>
+ * Three main pieces of functionality are required to implement
+ * security for JavaScript. First, it must be possible to define
+ * classes with an associated security domain. (This security
+ * domain may be any object incorporating notion of access
+ * restrictions that has meaning to an embedding; for a client-side
+ * JavaScript embedding this would typically be
+ * java.security.ProtectionDomain or similar object depending on an
+ * origin URL and/or a digital certificate.)
+ * Next it must be possible to get a security domain object that
+ * allows a particular action only if all security domains
+ * associated with code on the current Java stack allows it. And
+ * finally, it must be possible to execute script code with
+ * associated security domain injected into Java stack.
+ * <p>
+ * These three pieces of functionality are encapsulated in the
+ * SecurityController class.
+ *
+ * @see org.mozilla.javascript.Context#setSecurityController(SecurityController)
+ * @see java.lang.ClassLoader
+ * @since 1.5 Release 4
+ */
+public abstract class SecurityController
+{
+ private static SecurityController global;
+
+// The method must NOT be public or protected
+ static SecurityController global()
+ {
+ return global;
+ }
+
+ /**
+ * Check if global {@link SecurityController} was already installed.
+ * @see #initGlobal(SecurityController controller)
+ */
+ public static boolean hasGlobal()
+ {
+ return global != null;
+ }
+
+ /**
+ * Initialize global controller that will be used for all
+ * security-related operations. The global controller takes precedence
+ * over already installed {@link Context}-specific controllers and cause
+ * any subsequent call to
+ * {@link Context#setSecurityController(SecurityController)}
+ * to throw an exception.
+ * <p>
+ * The method can only be called once.
+ *
+ * @see #hasGlobal()
+ */
+ public static void initGlobal(SecurityController controller)
+ {
+ if (controller == null) throw new IllegalArgumentException();
+ if (global != null) {
+ throw new SecurityException("Cannot overwrite already installed global SecurityController");
+ }
+ global = controller;
+ }
+
+ /**
+ * Get class loader-like object that can be used
+ * to define classes with the given security context.
+ * @param parentLoader parent class loader to delegate search for classes
+ * not defined by the class loader itself
+ * @param securityDomain some object specifying the security
+ * context of the code that is defined by the returned class loader.
+ */
+ public abstract GeneratedClassLoader createClassLoader(
+ ClassLoader parentLoader, Object securityDomain);
+
+ /**
+ * Create {@link GeneratedClassLoader} with restrictions imposed by
+ * staticDomain and all current stack frames.
+ * The method uses the SecurityController instance associated with the
+ * current {@link Context} to construct proper dynamic domain and create
+ * corresponding class loader.
+ * <par>
+ * If no SecurityController is associated with the current {@link Context} ,
+ * the method calls {@link Context#createClassLoader(ClassLoader parent)}.
+ *
+ * @param parent parent class loader. If null,
+ * {@link Context#getApplicationClassLoader()} will be used.
+ * @param staticDomain static security domain.
+ */
+ public static GeneratedClassLoader createLoader(
+ ClassLoader parent, Object staticDomain)
+ {
+ Context cx = Context.getContext();
+ if (parent == null) {
+ parent = cx.getApplicationClassLoader();
+ }
+ SecurityController sc = cx.getSecurityController();
+ GeneratedClassLoader loader;
+ if (sc == null) {
+ loader = cx.createClassLoader(parent);
+ } else {
+ Object dynamicDomain = sc.getDynamicSecurityDomain(staticDomain);
+ loader = sc.createClassLoader(parent, dynamicDomain);
+ }
+ return loader;
+ }
+
+ public static Class getStaticSecurityDomainClass() {
+ SecurityController sc = Context.getContext().getSecurityController();
+ return sc == null ? null : sc.getStaticSecurityDomainClassInternal();
+ }
+
+ public Class getStaticSecurityDomainClassInternal()
+ {
+ return null;
+ }
+
+ /**
+ * Get dynamic security domain that allows an action only if it is allowed
+ * by the current Java stack and <i>securityDomain</i>. If
+ * <i>securityDomain</i> is null, return domain representing permissions
+ * allowed by the current stack.
+ */
+ public abstract Object getDynamicSecurityDomain(Object securityDomain);
+
+ /**
+ * Call {@link
+ * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,
+ * Object[] args)}
+ * of <i>callable</i> under restricted security domain where an action is
+ * allowed only if it is allowed according to the Java stack on the
+ * moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.
+ * Any call to {@link #getDynamicSecurityDomain(Object)} during
+ * execution of <tt>callable.call(cx, scope, thisObj, args)</tt>
+ * should return a domain incorporate restrictions imposed by
+ * <i>securityDomain</i> and Java stack on the moment of callWithDomain
+ * invocation.
+ * <p>
+ * The method should always be overridden, it is not declared abstract
+ * for compatibility reasons.
+ */
+ public Object callWithDomain(Object securityDomain, Context cx,
+ final Callable callable, Scriptable scope,
+ final Scriptable thisObj, final Object[] args)
+ {
+ return execWithDomain(cx, scope, new Script()
+ {
+ public Object exec(Context cx, Scriptable scope)
+ {
+ return callable.call(cx, scope, thisObj, args);
+ }
+
+ }, securityDomain);
+ }
+
+ /**
+ * @deprecated The application should not override this method and instead
+ * override
+ * {@link #callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)}.
+ */
+ public Object execWithDomain(Context cx, Scriptable scope,
+ Script script, Object securityDomain)
+ {
+ throw new IllegalStateException("callWithDomain should be overridden");
+ }
+
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java
new file mode 100644
index 0000000..275ad92
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityUtilities.java
@@ -0,0 +1,80 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+
+/**
+ * @author Attila Szegedi
+ */
+public class SecurityUtilities
+{
+ /**
+ * Retrieves a system property within a privileged block. Use it only when
+ * the property is used from within Rhino code and is not passed out of it.
+ * @param name the name of the system property
+ * @return the value of the system property
+ */
+ public static String getSystemProperty(final String name)
+ {
+ return (String)AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return System.getProperty(name);
+ }
+ });
+ }
+
+ public static ProtectionDomain getProtectionDomain(final Class clazz)
+ {
+ return (ProtectionDomain)AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return clazz.getProtectionDomain();
+ }
+ });
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java
new file mode 100644
index 0000000..b037eaf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/SpecialRef.java
@@ -0,0 +1,151 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+class SpecialRef extends Ref
+{
+ static final long serialVersionUID = -7521596632456797847L;
+
+ private static final int SPECIAL_NONE = 0;
+ private static final int SPECIAL_PROTO = 1;
+ private static final int SPECIAL_PARENT = 2;
+
+ private Scriptable target;
+ private int type;
+ private String name;
+
+ private SpecialRef(Scriptable target, int type, String name)
+ {
+ this.target = target;
+ this.type = type;
+ this.name = name;
+ }
+
+ static Ref createSpecial(Context cx, Object object, String name)
+ {
+ Scriptable target = ScriptRuntime.toObjectOrNull(cx, object);
+ if (target == null) {
+ throw ScriptRuntime.undefReadError(object, name);
+ }
+
+ int type;
+ if (name.equals("__proto__")) {
+ type = SPECIAL_PROTO;
+ } else if (name.equals("__parent__")) {
+ type = SPECIAL_PARENT;
+ } else {
+ throw new IllegalArgumentException(name);
+ }
+
+ if (!cx.hasFeature(Context.FEATURE_PARENT_PROTO_PROPERTIES)) {
+ // Clear special after checking for valid name!
+ type = SPECIAL_NONE;
+ }
+
+ return new SpecialRef(target, type, name);
+ }
+
+ public Object get(Context cx)
+ {
+ switch (type) {
+ case SPECIAL_NONE:
+ return ScriptRuntime.getObjectProp(target, name, cx);
+ case SPECIAL_PROTO:
+ return target.getPrototype();
+ case SPECIAL_PARENT:
+ return target.getParentScope();
+ default:
+ throw Kit.codeBug();
+ }
+ }
+
+ public Object set(Context cx, Object value)
+ {
+ switch (type) {
+ case SPECIAL_NONE:
+ return ScriptRuntime.setObjectProp(target, name, value, cx);
+ case SPECIAL_PROTO:
+ case SPECIAL_PARENT:
+ {
+ Scriptable obj = ScriptRuntime.toObjectOrNull(cx, value);
+ if (obj != null) {
+ // Check that obj does not contain on its prototype/scope
+ // chain to prevent cycles
+ Scriptable search = obj;
+ do {
+ if (search == target) {
+ throw Context.reportRuntimeError1(
+ "msg.cyclic.value", name);
+ }
+ if (type == SPECIAL_PROTO) {
+ search = search.getPrototype();
+ } else {
+ search = search.getParentScope();
+ }
+ } while (search != null);
+ }
+ if (type == SPECIAL_PROTO) {
+ target.setPrototype(obj);
+ } else {
+ target.setParentScope(obj);
+ }
+ return obj;
+ }
+ default:
+ throw Kit.codeBug();
+ }
+ }
+
+ public boolean has(Context cx)
+ {
+ if (type == SPECIAL_NONE) {
+ return ScriptRuntime.hasObjectElem(target, name, cx);
+ }
+ return true;
+ }
+
+ public boolean delete(Context cx)
+ {
+ if (type == SPECIAL_NONE) {
+ return ScriptRuntime.deleteObjectElem(target, name, cx);
+ }
+ return false;
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java
new file mode 100644
index 0000000..f2fca52
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Synchronizer.java
@@ -0,0 +1,81 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Delegator.java, released
+ * Sep 27, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * Matthias Radestock. <matthias@sorted.org>.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * This class provides support for implementing Java-style synchronized
+ * methods in Javascript.
+ *
+ * Synchronized functions are created from ordinary Javascript
+ * functions by the <code>Synchronizer</code> constructor, e.g.
+ * <code>new Packages.org.mozilla.javascript.Synchronizer(fun)</code>.
+ * The resulting object is a function that establishes an exclusive
+ * lock on the <code>this</code> object of its invocation.
+ *
+ * The Rhino shell provides a short-cut for the creation of
+ * synchronized methods: <code>sync(fun)</code> has the same effect as
+ * calling the above constructor.
+ *
+ * @see org.mozilla.javascript.Delegator
+ * @author Matthias Radestock
+ */
+
+public class Synchronizer extends Delegator {
+
+ /**
+ * Create a new synchronized function from an existing one.
+ *
+ * @param obj the existing function
+ */
+ public Synchronizer(Scriptable obj) {
+ super(obj);
+ }
+
+ /**
+ * @see org.mozilla.javascript.Function#call
+ */
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ synchronized(thisObj instanceof Wrapper ? ((Wrapper)thisObj).unwrap() : thisObj) {
+ return ((Function)obj).call(cx,scope,thisObj,args);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java
new file mode 100644
index 0000000..be96487
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Token.java
@@ -0,0 +1,436 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees =
+ /*APPJET: some info not generated with this off; we disable
+ actual printing in Interpreter and CodeGen */true;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ GETPROPNOWARN = 34,
+ SETPROP = 35,
+ GETELEM = 36,
+ SETELEM = 37,
+ CALL = 38,
+ NAME = 39,
+ NUMBER = 40,
+ STRING = 41,
+ NULL = 42,
+ THIS = 43,
+ FALSE = 44,
+ TRUE = 45,
+ SHEQ = 46, // shallow equality (===)
+ SHNE = 47, // shallow inequality (!==)
+ REGEXP = 48,
+ BINDNAME = 49,
+ THROW = 50,
+ RETHROW = 51, // rethrow caught exception: catch (e if ) use it
+ IN = 52,
+ INSTANCEOF = 53,
+ LOCAL_LOAD = 54,
+ GETVAR = 55,
+ SETVAR = 56,
+ CATCH_SCOPE = 57,
+ ENUM_INIT_KEYS = 58,
+ ENUM_INIT_VALUES = 59,
+ ENUM_INIT_ARRAY= 60,
+ ENUM_NEXT = 61,
+ ENUM_ID = 62,
+ THISFN = 63,
+ RETURN_RESULT = 64, // to return previously stored return result
+ ARRAYLIT = 65, // array literal
+ OBJECTLIT = 66, // object literal
+ GET_REF = 67, // *reference
+ SET_REF = 68, // *reference = something
+ DEL_REF = 69, // delete reference
+ REF_CALL = 70, // f(args) = something or f(args)++
+ REF_SPECIAL = 71, // reference for special properties like __proto
+ YIELD = 72, // JS 1.7 yield pseudo keyword
+
+ // For XML support:
+ DEFAULTNAMESPACE = 73, // default xml namespace =
+ ESCXMLATTR = 74,
+ ESCXMLTEXT = 75,
+ REF_MEMBER = 76, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 77, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 78, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 79; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 80,
+ SEMI = 81, // semicolon
+ LB = 82, // left and right brackets
+ RB = 83,
+ LC = 84, // left and right curlies (braces)
+ RC = 85,
+ LP = 86, // left and right parentheses
+ RP = 87,
+ COMMA = 88, // comma operator
+
+ ASSIGN = 89, // simple assignment (=)
+ ASSIGN_BITOR = 90, // |=
+ ASSIGN_BITXOR = 91, // ^=
+ ASSIGN_BITAND = 92, // |=
+ ASSIGN_LSH = 93, // <<=
+ ASSIGN_RSH = 94, // >>=
+ ASSIGN_URSH = 95, // >>>=
+ ASSIGN_ADD = 96, // +=
+ ASSIGN_SUB = 97, // -=
+ ASSIGN_MUL = 98, // *=
+ ASSIGN_DIV = 99, // /=
+ ASSIGN_MOD = 100; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 101, // conditional (?:)
+ COLON = 102,
+ OR = 103, // logical or (||)
+ AND = 104, // logical and (&&)
+ INC = 105, // increment/decrement (++ --)
+ DEC = 106,
+ DOT = 107, // member operator (.)
+ FUNCTION = 108, // function keyword
+ EXPORT = 109, // export keyword
+ IMPORT = 110, // import keyword
+ IF = 111, // if keyword
+ ELSE = 112, // else keyword
+ SWITCH = 113, // switch keyword
+ CASE = 114, // case keyword
+ DEFAULT = 115, // default keyword
+ WHILE = 116, // while keyword
+ DO = 117, // do keyword
+ FOR = 118, // for keyword
+ BREAK = 119, // break keyword
+ CONTINUE = 120, // continue keyword
+ VAR = 121, // var keyword
+ WITH = 122, // with keyword
+ CATCH = 123, // catch keyword
+ FINALLY = 124, // finally keyword
+ VOID = 125, // void keyword
+ RESERVED = 126, // reserved keywords
+
+ EMPTY = 127,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 128, // statement block
+ LABEL = 129, // label
+ TARGET = 130,
+ LOOP = 131,
+ EXPR_VOID = 132, // expression statement in functions
+ EXPR_RESULT = 133, // expression statement in scripts
+ JSR = 134,
+ SCRIPT = 135, // top-level node for entire script
+ TYPEOFNAME = 136, // for typeof(simple-name)
+ USE_STACK = 137,
+ SETPROP_OP = 138, // x.y op= something
+ SETELEM_OP = 139, // x[y] op= something
+ LOCAL_BLOCK = 140,
+ SET_REF_OP = 141, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 142, // member operator (..)
+ COLONCOLON = 143, // namespace::name
+ XML = 144, // XML type
+ DOTQUERY = 145, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 146, // @
+ XMLEND = 147,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 148,
+ TO_DOUBLE = 149,
+
+ GET = 150, // JS 1.5 get pseudo keyword
+ SET = 151, // JS 1.5 set pseudo keyword
+ LET = 152, // JS 1.7 let pseudo keyword
+ CONST = 153,
+ SETCONST = 154,
+ SETCONSTVAR = 155,
+ ARRAYCOMP = 156, // array comprehension
+ LETEXPR = 157,
+ WITHEXPR = 158,
+ DEBUGGER = 159,
+ LAST_TOKEN = 159;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case GETPROPNOWARN: return "GETPROPNOWARN";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES:return "ENUM_INIT_VALUES";
+ case ENUM_INIT_ARRAY: return "ENUM_INIT_ARRAY";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case VOID: return "VOID";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case LET: return "LET";
+ case YIELD: return "YIELD";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ case ARRAYCOMP: return "ARRAYCOMP";
+ case WITHEXPR: return "WITHEXPR";
+ case LETEXPR: return "LETEXPR";
+ case DEBUGGER: return "DEBUGGER";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java
new file mode 100644
index 0000000..c8c3045
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/TokenStream.java
@@ -0,0 +1,1500 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_let = Token.LET,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+ Id_yield = Token.YIELD,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.DEBUGGER,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2007-04-18 13:53:30 PDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'l': if (s.charAt(2)=='t' && s.charAt(1)=='e') {id=Id_let; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='b') { X="break";id=Id_break; }
+ else if (c=='y') { X="yield";id=Id_yield; }
+ break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ /*APPJET*//* case 'm': X="import";id=Id_import; break L;*/
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a <backslash>
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the <backslash>uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ /*APPJET*/
+ parser.addError("msg.illegal.character.appjet",
+ "\\"+Character.toString((char)c));
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ /*APPJET*//*MOVED*/this.string = (String)allStrings.intern(str);
+ /*APPJET this move lets the names of RESERVED tokens and other
+ tokens be determined, and also fixes broken yield/let parsing
+ under pre-1.7 JS */
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if ((result == Token.LET || result == Token.YIELD) &&
+ parser.compilerEnv.getLanguageVersion()
+ < Context.VERSION_1_7)
+ {
+ // LET and YIELD are tokens only in 1.7 and later
+ result = Token.NAME;
+ }
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ /*APPJET*/
+ if (c == '"' && tryReadTripleQuotedString()) {
+ return Token.STRING;
+ }
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ strLoop: while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ /*APPJET*/
+ parser.addError("msg.unterminated.string.lit",
+ Character.toString((char)quoteChar));
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+ int escapeVal;
+
+ c = getChar();
+ switch (c) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+
+ // \v a late addition to the ECMA spec,
+ // it is not in Java, so use 0xb
+ case 'v': c = 0xb; break;
+
+ case 'u':
+ // Get 4 hex digits; if the u escape is not
+ // followed by 4 hex digits, use 'u' + the
+ // literal character sequence that follows.
+ int escapeStart = stringBufferTop;
+ addToString('u');
+ escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ continue strLoop;
+ }
+ addToString(c);
+ }
+ // prepare for replace of stored 'u' sequence
+ // by escape value
+ stringBufferTop = escapeStart;
+ c = escapeVal;
+ break;
+ case 'x':
+ // Get 2 hex digits, defaulting to 'x'+literal
+ // sequence, as above.
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, 0);
+ if (escapeVal < 0) {
+ addToString('x');
+ continue strLoop;
+ } else {
+ int c1 = c;
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ addToString('x');
+ addToString(c1);
+ continue strLoop;
+ } else {
+ // got 2 hex digits
+ c = escapeVal;
+ }
+ }
+ break;
+
+ case '\n':
+ // Remove line terminator after escape to follow
+ // SpiderMonkey and C/C++
+ c = getChar();
+ continue strLoop;
+
+ default:
+ if ('0' <= c && c < '8') {
+ int val = c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8') {
+ val = 8 * val + c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8' && val <= 037) {
+ // c is 3rd char of octal sequence only
+ // if the resulting val <= 0377
+ val = 8 * val + c - '0';
+ c = getChar();
+ }
+ }
+ ungetChar(c);
+ c = val;
+ }
+ }
+ }
+ addToString(c);
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ } else if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ continue retry;
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ /*APPJET*/
+ parser.addError("msg.illegal.character.appjet",
+ Character.toString((char)c));
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ while ((c = getChar()) != '/') {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in <!--
+ private final int[] ungetBuffer = new int[3];
+ private int ungetCursor;
+
+ private boolean hitEOF = false;
+
+ private int lineStart = 0;
+ private int lineno;
+ private int lineEndChar = -1;
+
+ private String sourceString;
+ private Reader sourceReader;
+ private char[] sourceBuffer;
+ private int sourceEnd;
+ private int sourceCursor;
+
+ // for xml tokenizer
+ private boolean xmlIsAttribute;
+ private boolean xmlIsTagContent;
+ private int xmlOpenTagsCount;
+
+ private Parser parser;
+
+ /*APPJET*//* added method */
+ private boolean tryReadTripleQuotedString() throws IOException {
+ // have to be kind of clever, because we don't want to
+ // add to the overhead of tokenizing, but there are constraints
+ // like "once you've gotten a newline and put it back (ungotten it),
+ // you can't put anything else back"
+
+ // have seen one quote
+ int c = getChar();
+ if (c != '"') { ungetChar(c); return false; }
+ // have seen two quotes
+ c = getChar();
+ if (c != '"') {
+ ungetChar(c);
+ this.string = (String)allStrings.intern("");
+ return true;
+ }
+ // have seen three quotes
+
+ final boolean newPolicy = false;
+
+ stringBufferTop = 0;
+
+ boolean afterBackslash = false;
+ boolean done = false;
+ while (! done) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.mstring.appjet");
+ }
+ if (c == '"') {
+ int quoteCount = 0;
+ int quoteLimit = 3;
+ if (newPolicy && ! afterBackslash)
+ quoteLimit = 5;
+ while (c == '"' && quoteCount < quoteLimit) {
+ quoteCount++;
+ c = getChar();
+ }
+ ungetChar(c);
+
+ if (afterBackslash) {
+ if (quoteCount < 3) addToString('\\');
+ }
+ else if (quoteCount >= 3) {
+ quoteCount -= 3;
+ done = true;
+ }
+
+ while (quoteCount > 0) {
+ addToString('"'); quoteCount--;
+ }
+ afterBackslash = false;
+ }
+ else {
+ if (afterBackslash) {
+ addToString('\\');
+ afterBackslash = false;
+ }
+ if (c == '\\') {
+ afterBackslash = true;
+ }
+ else {
+ addToString(c);
+ }
+ }
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+
+ return true;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java
new file mode 100644
index 0000000..0027819
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UintMap.java
@@ -0,0 +1,659 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Map to associate non-negative integers to objects or integers.
+ * The map does not synchronize any of its operation, so either use
+ * it from a single thread or do own synchronization or perform all mutation
+ * operations on one thread before passing the map to others.
+ *
+ * @author Igor Bukanov
+ *
+ */
+
+public class UintMap implements Serializable
+{
+ static final long serialVersionUID = 4242698212885848444L;
+
+// Map implementation via hashtable,
+// follows "The Art of Computer Programming" by Donald E. Knuth
+
+ public UintMap() {
+ this(4);
+ }
+
+ public UintMap(int initialCapacity) {
+ if (initialCapacity < 0) Kit.codeBug();
+ // Table grow when number of stored keys >= 3/4 of max capacity
+ int minimalCapacity = initialCapacity * 4 / 3;
+ int i;
+ for (i = 2; (1 << i) < minimalCapacity; ++i) { }
+ power = i;
+ if (check && power < 2) Kit.codeBug();
+ }
+
+ public boolean isEmpty() {
+ return keyCount == 0;
+ }
+
+ public int size() {
+ return keyCount;
+ }
+
+ public boolean has(int key) {
+ if (key < 0) Kit.codeBug();
+ return 0 <= findIndex(key);
+ }
+
+ /**
+ * Get object value assigned with key.
+ * @return key object value or null if key is absent
+ */
+ public Object getObject(int key) {
+ if (key < 0) Kit.codeBug();
+ if (values != null) {
+ int index = findIndex(key);
+ if (0 <= index) {
+ return values[index];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get integer value assigned with key.
+ * @return key integer value or defaultValue if key is absent
+ */
+ public int getInt(int key, int defaultValue) {
+ if (key < 0) Kit.codeBug();
+ int index = findIndex(key);
+ if (0 <= index) {
+ if (ivaluesShift != 0) {
+ return keys[ivaluesShift + index];
+ }
+ return 0;
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Get integer value assigned with key.
+ * @return key integer value or defaultValue if key does not exist or does
+ * not have int value
+ * @throws RuntimeException if key does not exist
+ */
+ public int getExistingInt(int key) {
+ if (key < 0) Kit.codeBug();
+ int index = findIndex(key);
+ if (0 <= index) {
+ if (ivaluesShift != 0) {
+ return keys[ivaluesShift + index];
+ }
+ return 0;
+ }
+ // Key must exist
+ Kit.codeBug();
+ return 0;
+ }
+
+ /**
+ * Set object value of the key.
+ * If key does not exist, also set its int value to 0.
+ */
+ public void put(int key, Object value) {
+ if (key < 0) Kit.codeBug();
+ int index = ensureIndex(key, false);
+ if (values == null) {
+ values = new Object[1 << power];
+ }
+ values[index] = value;
+ }
+
+ /**
+ * Set int value of the key.
+ * If key does not exist, also set its object value to null.
+ */
+ public void put(int key, int value) {
+ if (key < 0) Kit.codeBug();
+ int index = ensureIndex(key, true);
+ if (ivaluesShift == 0) {
+ int N = 1 << power;
+ // keys.length can be N * 2 after clear which set ivaluesShift to 0
+ if (keys.length != N * 2) {
+ int[] tmp = new int[N * 2];
+ System.arraycopy(keys, 0, tmp, 0, N);
+ keys = tmp;
+ }
+ ivaluesShift = N;
+ }
+ keys[ivaluesShift + index] = value;
+ }
+
+ public void remove(int key) {
+ if (key < 0) Kit.codeBug();
+ int index = findIndex(key);
+ if (0 <= index) {
+ keys[index] = DELETED;
+ --keyCount;
+ // Allow to GC value and make sure that new key with the deleted
+ // slot shall get proper default values
+ if (values != null) { values[index] = null; }
+ if (ivaluesShift != 0) { keys[ivaluesShift + index] = 0; }
+ }
+ }
+
+ public void clear() {
+ int N = 1 << power;
+ if (keys != null) {
+ for (int i = 0; i != N; ++i) {
+ keys[i] = EMPTY;
+ }
+ if (values != null) {
+ for (int i = 0; i != N; ++i) {
+ values[i] = null;
+ }
+ }
+ }
+ ivaluesShift = 0;
+ keyCount = 0;
+ occupiedCount = 0;
+ }
+
+ /** Return array of present keys */
+ public int[] getKeys() {
+ int[] keys = this.keys;
+ int n = keyCount;
+ int[] result = new int[n];
+ for (int i = 0; n != 0; ++i) {
+ int entry = keys[i];
+ if (entry != EMPTY && entry != DELETED) {
+ result[--n] = entry;
+ }
+ }
+ return result;
+ }
+
+ private static int tableLookupStep(int fraction, int mask, int power) {
+ int shift = 32 - 2 * power;
+ if (shift >= 0) {
+ return ((fraction >>> shift) & mask) | 1;
+ }
+ else {
+ return (fraction & (mask >>> -shift)) | 1;
+ }
+ }
+
+ private int findIndex(int key) {
+ int[] keys = this.keys;
+ if (keys != null) {
+ int fraction = key * A;
+ int index = fraction >>> (32 - power);
+ int entry = keys[index];
+ if (entry == key) { return index; }
+ if (entry != EMPTY) {
+ // Search in table after first failed attempt
+ int mask = (1 << power) - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int n = 0;
+ do {
+ if (check) {
+ if (n >= occupiedCount) Kit.codeBug();
+ ++n;
+ }
+ index = (index + step) & mask;
+ entry = keys[index];
+ if (entry == key) { return index; }
+ } while (entry != EMPTY);
+ }
+ }
+ return -1;
+ }
+
+// Insert key that is not present to table without deleted entries
+// and enough free space
+ private int insertNewKey(int key) {
+ if (check && occupiedCount != keyCount) Kit.codeBug();
+ if (check && keyCount == 1 << power) Kit.codeBug();
+ int[] keys = this.keys;
+ int fraction = key * A;
+ int index = fraction >>> (32 - power);
+ if (keys[index] != EMPTY) {
+ int mask = (1 << power) - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int firstIndex = index;
+ do {
+ if (check && keys[index] == DELETED) Kit.codeBug();
+ index = (index + step) & mask;
+ if (check && firstIndex == index) Kit.codeBug();
+ } while (keys[index] != EMPTY);
+ }
+ keys[index] = key;
+ ++occupiedCount;
+ ++keyCount;
+ return index;
+ }
+
+ private void rehashTable(boolean ensureIntSpace) {
+ if (keys != null) {
+ // Check if removing deleted entries would free enough space
+ if (keyCount * 2 >= occupiedCount) {
+ // Need to grow: less then half of deleted entries
+ ++power;
+ }
+ }
+ int N = 1 << power;
+ int[] old = keys;
+ int oldShift = ivaluesShift;
+ if (oldShift == 0 && !ensureIntSpace) {
+ keys = new int[N];
+ }
+ else {
+ ivaluesShift = N; keys = new int[N * 2];
+ }
+ for (int i = 0; i != N; ++i) { keys[i] = EMPTY; }
+
+ Object[] oldValues = values;
+ if (oldValues != null) { values = new Object[N]; }
+
+ int oldCount = keyCount;
+ occupiedCount = 0;
+ if (oldCount != 0) {
+ keyCount = 0;
+ for (int i = 0, remaining = oldCount; remaining != 0; ++i) {
+ int key = old[i];
+ if (key != EMPTY && key != DELETED) {
+ int index = insertNewKey(key);
+ if (oldValues != null) {
+ values[index] = oldValues[i];
+ }
+ if (oldShift != 0) {
+ keys[ivaluesShift + index] = old[oldShift + i];
+ }
+ --remaining;
+ }
+ }
+ }
+ }
+
+// Ensure key index creating one if necessary
+ private int ensureIndex(int key, boolean intType) {
+ int index = -1;
+ int firstDeleted = -1;
+ int[] keys = this.keys;
+ if (keys != null) {
+ int fraction = key * A;
+ index = fraction >>> (32 - power);
+ int entry = keys[index];
+ if (entry == key) { return index; }
+ if (entry != EMPTY) {
+ if (entry == DELETED) { firstDeleted = index; }
+ // Search in table after first failed attempt
+ int mask = (1 << power) - 1;
+ int step = tableLookupStep(fraction, mask, power);
+ int n = 0;
+ do {
+ if (check) {
+ if (n >= occupiedCount) Kit.codeBug();
+ ++n;
+ }
+ index = (index + step) & mask;
+ entry = keys[index];
+ if (entry == key) { return index; }
+ if (entry == DELETED && firstDeleted < 0) {
+ firstDeleted = index;
+ }
+ } while (entry != EMPTY);
+ }
+ }
+ // Inserting of new key
+ if (check && keys != null && keys[index] != EMPTY)
+ Kit.codeBug();
+ if (firstDeleted >= 0) {
+ index = firstDeleted;
+ }
+ else {
+ // Need to consume empty entry: check occupation level
+ if (keys == null || occupiedCount * 4 >= (1 << power) * 3) {
+ // Too litle unused entries: rehash
+ rehashTable(intType);
+ keys = this.keys;
+ return insertNewKey(key);
+ }
+ ++occupiedCount;
+ }
+ keys[index] = key;
+ ++keyCount;
+ return index;
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ out.defaultWriteObject();
+
+ int count = keyCount;
+ if (count != 0) {
+ boolean hasIntValues = (ivaluesShift != 0);
+ boolean hasObjectValues = (values != null);
+ out.writeBoolean(hasIntValues);
+ out.writeBoolean(hasObjectValues);
+
+ for (int i = 0; count != 0; ++i) {
+ int key = keys[i];
+ if (key != EMPTY && key != DELETED) {
+ --count;
+ out.writeInt(key);
+ if (hasIntValues) {
+ out.writeInt(keys[ivaluesShift + i]);
+ }
+ if (hasObjectValues) {
+ out.writeObject(values[i]);
+ }
+ }
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+
+ int writtenKeyCount = keyCount;
+ if (writtenKeyCount != 0) {
+ keyCount = 0;
+ boolean hasIntValues = in.readBoolean();
+ boolean hasObjectValues = in.readBoolean();
+
+ int N = 1 << power;
+ if (hasIntValues) {
+ keys = new int[2 * N];
+ ivaluesShift = N;
+ }else {
+ keys = new int[N];
+ }
+ for (int i = 0; i != N; ++i) {
+ keys[i] = EMPTY;
+ }
+ if (hasObjectValues) {
+ values = new Object[N];
+ }
+ for (int i = 0; i != writtenKeyCount; ++i) {
+ int key = in.readInt();
+ int index = insertNewKey(key);
+ if (hasIntValues) {
+ int ivalue = in.readInt();
+ keys[ivaluesShift + index] = ivalue;
+ }
+ if (hasObjectValues) {
+ values[index] = in.readObject();
+ }
+ }
+ }
+ }
+
+// A == golden_ratio * (1 << 32) = ((sqrt(5) - 1) / 2) * (1 << 32)
+// See Knuth etc.
+ private static final int A = 0x9e3779b9;
+
+ private static final int EMPTY = -1;
+ private static final int DELETED = -2;
+
+// Structure of kyes and values arrays (N == 1 << power):
+// keys[0 <= i < N]: key value or EMPTY or DELETED mark
+// values[0 <= i < N]: value of key at keys[i]
+// keys[N <= i < 2N]: int values of keys at keys[i - N]
+
+ private transient int[] keys;
+ private transient Object[] values;
+
+ private int power;
+ private int keyCount;
+ private transient int occupiedCount; // == keyCount + deleted_count
+
+ // If ivaluesShift != 0, keys[ivaluesShift + index] contains integer
+ // values associated with keys
+ private transient int ivaluesShift;
+
+// If true, enables consitency checks
+ private static final boolean check = false;
+
+/* TEST START
+
+ public static void main(String[] args) {
+ if (!check) {
+ System.err.println("Set check to true and re-run");
+ throw new RuntimeException("Set check to true and re-run");
+ }
+
+ UintMap map;
+ map = new UintMap();
+ testHash(map, 2);
+ map = new UintMap();
+ testHash(map, 10 * 1000);
+ map = new UintMap(30 * 1000);
+ testHash(map, 10 * 100);
+ map.clear();
+ testHash(map, 4);
+ map = new UintMap(0);
+ testHash(map, 10 * 100);
+ }
+
+ private static void testHash(UintMap map, int N) {
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ map.put(i, i);
+ check(i == map.getInt(i, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ map.put(i, i);
+ check(i == map.getInt(i, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ map.put(i, new Integer(i));
+ check(-1 == map.getInt(i, -1));
+ Integer obj = (Integer)map.getObject(i);
+ check(obj != null && i == obj.intValue());
+ }
+
+ check(map.size() == N);
+
+ System.out.print("."); System.out.flush();
+ int[] keys = map.getKeys();
+ check(keys.length == N);
+ for (int i = 0; i != N; ++i) {
+ int key = keys[i];
+ check(map.has(key));
+ check(!map.isIntType(key));
+ check(map.isObjectType(key));
+ Integer obj = (Integer) map.getObject(key);
+ check(obj != null && key == obj.intValue());
+ }
+
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ check(-1 == map.getInt(i, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ map.put(i * i, i);
+ check(i == map.getInt(i * i, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ check(i == map.getInt(i * i, -1));
+ }
+
+ System.out.print("."); System.out.flush();
+ for (int i = 0; i != N; ++i) {
+ map.put(i * i, new Integer(i));
+ check(-1 == map.getInt(i * i, -1));
+ map.remove(i * i);
+ check(!map.has(i * i));
+ map.put(i * i, i);
+ check(map.isIntType(i * i));
+ check(null == map.getObject(i * i));
+ map.remove(i * i);
+ check(!map.isObjectType(i * i));
+ check(!map.isIntType(i * i));
+ }
+
+ int old_size = map.size();
+ for (int i = 0; i != N; ++i) {
+ map.remove(i * i);
+ check(map.size() == old_size);
+ }
+
+ System.out.print("."); System.out.flush();
+ map.clear();
+ check(map.size() == 0);
+ for (int i = 0; i != N; ++i) {
+ map.put(i * i, i);
+ map.put(i * i + 1, new Double(i+0.5));
+ }
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+
+ System.out.print("."); System.out.flush();
+ map = new UintMap(0);
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+ map = new UintMap(1);
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+ map = new UintMap(1000);
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+
+ System.out.print("."); System.out.flush();
+ map = new UintMap(N / 10);
+ for (int i = 0; i != N; ++i) {
+ map.put(2*i+1, i);
+ }
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+
+ System.out.print("."); System.out.flush();
+ map = new UintMap(N / 10);
+ for (int i = 0; i != N; ++i) {
+ map.put(2*i+1, i);
+ }
+ for (int i = 0; i != N / 2; ++i) {
+ map.remove(2*i+1);
+ }
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+
+ System.out.print("."); System.out.flush();
+ map = new UintMap();
+ for (int i = 0; i != N; ++i) {
+ map.put(2*i+1, new Double(i + 10));
+ }
+ for (int i = 0; i != N / 2; ++i) {
+ map.remove(2*i+1);
+ }
+ checkSameMaps(map, (UintMap)writeAndRead(map));
+
+ System.out.println(); System.out.flush();
+
+ }
+
+ private static void checkSameMaps(UintMap map1, UintMap map2) {
+ check(map1.size() == map2.size());
+ int[] keys = map1.getKeys();
+ check(keys.length == map1.size());
+ for (int i = 0; i != keys.length; ++i) {
+ int key = keys[i];
+ check(map2.has(key));
+ check(map1.isObjectType(key) == map2.isObjectType(key));
+ check(map1.isIntType(key) == map2.isIntType(key));
+ Object o1 = map1.getObject(key);
+ Object o2 = map2.getObject(key);
+ if (map1.isObjectType(key)) {
+ check(o1.equals(o2));
+ }else {
+ check(map1.getObject(key) == null);
+ check(map2.getObject(key) == null);
+ }
+ if (map1.isIntType(key)) {
+ check(map1.getExistingInt(key) == map2.getExistingInt(key));
+ }else {
+ check(map1.getInt(key, -10) == -10);
+ check(map1.getInt(key, -11) == -11);
+ check(map2.getInt(key, -10) == -10);
+ check(map2.getInt(key, -11) == -11);
+ }
+ }
+ }
+
+ private static void check(boolean condition) {
+ if (!condition) Kit.codeBug();
+ }
+
+ private static Object writeAndRead(Object obj) {
+ try {
+ java.io.ByteArrayOutputStream
+ bos = new java.io.ByteArrayOutputStream();
+ java.io.ObjectOutputStream
+ out = new java.io.ObjectOutputStream(bos);
+ out.writeObject(obj);
+ out.close();
+ byte[] data = bos.toByteArray();
+ java.io.ByteArrayInputStream
+ bis = new java.io.ByteArrayInputStream(data);
+ java.io.ObjectInputStream
+ in = new java.io.ObjectInputStream(bis);
+ Object result = in.readObject();
+ in.close();
+ return result;
+ }catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException("Unexpected");
+ }
+ }
+
+// TEST END */
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java
new file mode 100644
index 0000000..472f26c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Undefined.java
@@ -0,0 +1,60 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+/**
+ * This class implements the Undefined value in JavaScript.
+ */
+public class Undefined implements Serializable
+{
+ static final long serialVersionUID = 9195680630202616767L;
+
+ public static final Object instance = new Undefined();
+
+ private Undefined()
+ {
+ }
+
+ public Object readResolve()
+ {
+ return instance;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java
new file mode 100644
index 0000000..33f96eb
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/UniqueTag.java
@@ -0,0 +1,120 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Serializable;
+
+/**
+ * Class instances represent serializable tags to mark special Object values.
+ * <p>
+ * Compatibility note: under jdk 1.1 use
+ * org.mozilla.javascript.serialize.ScriptableInputStream to read serialized
+ * instances of UniqueTag as under this JDK version the default
+ * ObjectInputStream would not restore them correctly as it lacks support
+ * for readResolve method
+ */
+public final class UniqueTag implements Serializable
+{
+ static final long serialVersionUID = -4320556826714577259L;
+
+ private static final int ID_NOT_FOUND = 1;
+ private static final int ID_NULL_VALUE = 2;
+ private static final int ID_DOUBLE_MARK = 3;
+
+ /**
+ * Tag to mark non-existing values.
+ */
+ public static final UniqueTag
+ NOT_FOUND = new UniqueTag(ID_NOT_FOUND);
+
+ /**
+ * Tag to distinguish between uninitialized and null values.
+ */
+ public static final UniqueTag
+ NULL_VALUE = new UniqueTag(ID_NULL_VALUE);
+
+ /**
+ * Tag to indicate that a object represents "double" with the real value
+ * stored somewhere else.
+ */
+ public static final UniqueTag
+ DOUBLE_MARK = new UniqueTag(ID_DOUBLE_MARK);
+
+ private final int tagId;
+
+ private UniqueTag(int tagId)
+ {
+ this.tagId = tagId;
+ }
+
+ public Object readResolve()
+ {
+ switch (tagId) {
+ case ID_NOT_FOUND:
+ return NOT_FOUND;
+ case ID_NULL_VALUE:
+ return NULL_VALUE;
+ case ID_DOUBLE_MARK:
+ return DOUBLE_MARK;
+ }
+ throw new IllegalStateException(String.valueOf(tagId));
+ }
+
+// Overridden for better debug printouts
+ public String toString()
+ {
+ String name;
+ switch (tagId) {
+ case ID_NOT_FOUND:
+ name = "NOT_FOUND";
+ break;
+ case ID_NULL_VALUE:
+ name = "NULL_VALUE";
+ break;
+ case ID_DOUBLE_MARK:
+ name = "DOUBLE_MARK";
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ return super.toString()+": "+name;
+ }
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java
new file mode 100644
index 0000000..5fba4a5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/VMBridge.java
@@ -0,0 +1,183 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.util.Iterator;
+
+public abstract class VMBridge
+{
+
+ static final VMBridge instance = makeInstance();
+
+ private static VMBridge makeInstance()
+ {
+ String[] classNames = {
+ "org.mozilla.javascript.VMBridge_custom",
+ "org.mozilla.javascript.jdk15.VMBridge_jdk15",
+ "org.mozilla.javascript.jdk13.VMBridge_jdk13",
+ "org.mozilla.javascript.jdk11.VMBridge_jdk11",
+ };
+ for (int i = 0; i != classNames.length; ++i) {
+ String className = classNames[i];
+ Class cl = Kit.classOrNull(className);
+ if (cl != null) {
+ VMBridge bridge = (VMBridge)Kit.newInstanceOrNull(cl);
+ if (bridge != null) {
+ return bridge;
+ }
+ }
+ }
+ throw new IllegalStateException("Failed to create VMBridge instance");
+ }
+
+ /**
+ * Return a helper object to optimize {@link Context} access.
+ * <p>
+ * The runtime will pass the resulting helper object to the subsequent
+ * calls to {@link #getContext(Object contextHelper)} and
+ * {@link #setContext(Object contextHelper, Context cx)} methods.
+ * In this way the implementation can use the helper to cache
+ * information about current thread to make {@link Context} access faster.
+ */
+ protected abstract Object getThreadContextHelper();
+
+ /**
+ * Get {@link Context} instance associated with the current thread
+ * or null if none.
+ *
+ * @param contextHelper The result of {@link #getThreadContextHelper()}
+ * called from the current thread.
+ */
+ protected abstract Context getContext(Object contextHelper);
+
+ /**
+ * Associate {@link Context} instance with the current thread or remove
+ * the current association if <tt>cx</tt> is null.
+ *
+ * @param contextHelper The result of {@link #getThreadContextHelper()}
+ * called from the current thread.
+ */
+ protected abstract void setContext(Object contextHelper, Context cx);
+
+ /**
+ * Return the ClassLoader instance associated with the current thread.
+ */
+ protected abstract ClassLoader getCurrentThreadClassLoader();
+
+ /**
+ * In many JVMSs, public methods in private
+ * classes are not accessible by default (Sun Bug #4071593).
+ * VMBridge instance should try to workaround that via, for example,
+ * calling method.setAccessible(true) when it is available.
+ * The implementation is responsible to catch all possible exceptions
+ * like SecurityException if the workaround is not available.
+ *
+ * @return true if it was possible to make method accessible
+ * or false otherwise.
+ */
+ protected abstract boolean tryToMakeAccessible(Object accessibleObject);
+
+ /**
+ * Create helper object to create later proxies implementing the specified
+ * interfaces later. Under JDK 1.3 the implementation can look like:
+ * <pre>
+ * return java.lang.reflect.Proxy.getProxyClass(..., interfaces).
+ * getConstructor(new Class[] {
+ * java.lang.reflect.InvocationHandler.class });
+ * </pre>
+ *
+ * @param interfaces Array with one or more interface class objects.
+ */
+ protected Object getInterfaceProxyHelper(ContextFactory cf,
+ Class[] interfaces)
+ {
+ throw Context.reportRuntimeError(
+ "VMBridge.getInterfaceProxyHelper is not supported");
+ }
+
+ /**
+ * Create proxy object for {@link InterfaceAdapter}. The proxy should call
+ * {@link InterfaceAdapter#invoke(ContextFactory cf,
+ * Object target,
+ * Scriptable topScope,
+ * Method method,
+ * Object[] args)}
+ * as implementation of interface methods associated with
+ * <tt>proxyHelper</tt>.
+ *
+ * @param proxyHelper The result of the previous call to
+ * {@link #getInterfaceProxyHelper(ContextFactory, Class[])}.
+ */
+ protected Object newInterfaceProxy(Object proxyHelper,
+ ContextFactory cf,
+ InterfaceAdapter adapter,
+ Object target,
+ Scriptable topScope)
+ {
+ throw Context.reportRuntimeError(
+ "VMBridge.newInterfaceProxy is not supported");
+ }
+
+ /**
+ * Returns whether or not a given member (method or constructor)
+ * has variable arguments.
+ * Variable argument methods have only been supported in Java since
+ * JDK 1.5.
+ */
+ protected abstract boolean isVarArgs(Member member);
+
+ /**
+ * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a
+ * wrapping as a JavaScript Iterator. Otherwise, return null.
+ * This method is in VMBridge since Iterable is a JDK 1.5 addition.
+ */
+ public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) {
+ if (obj instanceof Wrapper) {
+ Object unwrapped = ((Wrapper) obj).unwrap();
+ Iterator iterator = null;
+ if (unwrapped instanceof Iterator)
+ iterator = (Iterator) unwrapped;
+ return iterator;
+ }
+ return null;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java
new file mode 100644
index 0000000..3edc203
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrapFactory.java
@@ -0,0 +1,183 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Embeddings that wish to provide their own custom wrappings for Java
+ * objects may extend this class and call
+ * {@link Context#setWrapFactory(WrapFactory)}
+ * Once an instance of this class or an extension of this class is enabled
+ * for a given context (by calling setWrapFactory on that context), Rhino
+ * will call the methods of this class whenever it needs to wrap a value
+ * resulting from a call to a Java method or an access to a Java field.
+ *
+ * @see org.mozilla.javascript.Context#setWrapFactory(WrapFactory)
+ * @since 1.5 Release 4
+ */
+public class WrapFactory
+{
+ /**
+ * Wrap the object.
+ * <p>
+ * The value returned must be one of
+ * <UL>
+ * <LI>java.lang.Boolean</LI>
+ * <LI>java.lang.String</LI>
+ * <LI>java.lang.Number</LI>
+ * <LI>org.mozilla.javascript.Scriptable objects</LI>
+ * <LI>The value returned by Context.getUndefinedValue()</LI>
+ * <LI>null</LI>
+ * </UL>
+ * @param cx the current Context for this thread
+ * @param scope the scope of the executing script
+ * @param obj the object to be wrapped. Note it can be null.
+ * @param staticType type hint. If security restrictions prevent to wrap
+ object based on its class, staticType will be used instead.
+ * @return the wrapped value.
+ */
+ public Object wrap(Context cx, Scriptable scope,
+ Object obj, Class staticType)
+ {
+ if (obj == null || obj == Undefined.instance
+ || obj instanceof Scriptable)
+ {
+ return obj;
+ }
+ if (staticType != null && staticType.isPrimitive()) {
+ if (staticType == Void.TYPE)
+ return Undefined.instance;
+ if (staticType == Character.TYPE)
+ return new Integer(((Character) obj).charValue());
+ return obj;
+ }
+ if (!isJavaPrimitiveWrap()) {
+ if (obj instanceof String || obj instanceof Number
+ || obj instanceof Boolean)
+ {
+ return obj;
+ } else if (obj instanceof Character) {
+ return String.valueOf(((Character)obj).charValue());
+ }
+ }
+ Class cls = obj.getClass();
+ if (cls.isArray()) {
+ return NativeJavaArray.wrap(scope, obj);
+ }
+ return wrapAsJavaObject(cx, scope, obj, staticType);
+ }
+
+ /**
+ * Wrap an object newly created by a constructor call.
+ * @param cx the current Context for this thread
+ * @param scope the scope of the executing script
+ * @param obj the object to be wrapped
+ * @return the wrapped value.
+ */
+ public Scriptable wrapNewObject(Context cx, Scriptable scope, Object obj)
+ {
+ if (obj instanceof Scriptable) {
+ return (Scriptable)obj;
+ }
+ Class cls = obj.getClass();
+ if (cls.isArray()) {
+ return NativeJavaArray.wrap(scope, obj);
+ }
+ return wrapAsJavaObject(cx, scope, obj, null);
+ }
+
+ /**
+ * Wrap Java object as Scriptable instance to allow full access to its
+ * methods and fields from JavaScript.
+ * <p>
+ * {@link #wrap(Context, Scriptable, Object, Class)} and
+ * {@link #wrapNewObject(Context, Scriptable, Object)} call this method
+ * when they can not convert <tt>javaObject</tt> to JavaScript primitive
+ * value or JavaScript array.
+ * <p>
+ * Subclasses can override the method to provide custom wrappers
+ * for Java objects.
+ * @param cx the current Context for this thread
+ * @param scope the scope of the executing script
+ * @param javaObject the object to be wrapped
+ * @param staticType type hint. If security restrictions prevent to wrap
+ object based on its class, staticType will be used instead.
+ * @return the wrapped value which shall not be null
+ */
+ public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
+ Object javaObject, Class staticType)
+ {
+ Scriptable wrap;
+ wrap = new NativeJavaObject(scope, javaObject, staticType);
+ return wrap;
+ }
+
+ /**
+ * Return <code>false</code> if result of Java method, which is instance of
+ * <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ * <code>Character</code>, should be used directly as JavaScript primitive
+ * type.
+ * By default the method returns true to indicate that instances of
+ * <code>String</code>, <code>Number</code>, <code>Boolean</code> and
+ * <code>Character</code> should be wrapped as any other Java object and
+ * scripts can access any Java method available in these objects.
+ * Use {@link #setJavaPrimitiveWrap(boolean)} to change this.
+ */
+ public final boolean isJavaPrimitiveWrap()
+ {
+ return javaPrimitiveWrap;
+ }
+
+ /**
+ * @see #isJavaPrimitiveWrap()
+ */
+ public final void setJavaPrimitiveWrap(boolean value)
+ {
+ Context cx = Context.getCurrentContext();
+ if (cx != null && cx.isSealed()) {
+ Context.onSealedMutation();
+ }
+ javaPrimitiveWrap = value;
+ }
+
+ private boolean javaPrimitiveWrap = true;
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java
new file mode 100644
index 0000000..c749f74
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/WrappedException.java
@@ -0,0 +1,93 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * A wrapper for runtime exceptions.
+ *
+ * Used by the JavaScript runtime to wrap and propagate exceptions that occur
+ * during runtime.
+ *
+ * @author Norris Boyd
+ */
+public class WrappedException extends EvaluatorException
+{
+ static final long serialVersionUID = -1551979216966520648L;
+
+ /**
+ * @see Context#throwAsScriptRuntimeEx(Throwable e)
+ */
+ public WrappedException(Throwable exception)
+ {
+ super("Wrapped "+exception.toString());
+ this.exception = exception;
+ Kit.initCause(this, exception);
+
+ int[] linep = { 0 };
+ String sourceName = Context.getSourcePositionFromStack(linep);
+ int lineNumber = linep[0];
+ if (sourceName != null) {
+ initSourceName(sourceName);
+ }
+ if (lineNumber != 0) {
+ initLineNumber(lineNumber);
+ }
+ }
+
+ /**
+ * Get the wrapped exception.
+ *
+ * @return the exception that was presented as a argument to the
+ * constructor when this object was created
+ */
+ public Throwable getWrappedException()
+ {
+ return exception;
+ }
+
+ /**
+ * @deprecated Use {@link #getWrappedException()} instead.
+ */
+ public Object unwrap()
+ {
+ return getWrappedException();
+ }
+
+ private Throwable exception;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java
new file mode 100644
index 0000000..cb2d2f5
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/Wrapper.java
@@ -0,0 +1,58 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript;
+
+/**
+ * Objects that can wrap other values for reflection in the JS environment
+ * will implement Wrapper.
+ *
+ * Wrapper defines a single method that can be called to unwrap the object.
+ */
+
+public interface Wrapper {
+
+ /**
+ * Unwrap the object by returning the wrapped value.
+ *
+ * @return a wrapped value
+ */
+ public Object unwrap();
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java
new file mode 100644
index 0000000..c6d3966
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/continuations/Continuation.java
@@ -0,0 +1,136 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.continuations;
+
+import org.mozilla.javascript.*;
+
+public final class Continuation extends IdScriptableObject implements Function
+{
+ static final long serialVersionUID = 1794167133757605367L;
+
+ private static final Object FTAG = new Object();
+
+ private Object implementation;
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+ Continuation obj = new Continuation();
+ obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed);
+ }
+
+ public Object getImplementation()
+ {
+ return implementation;
+ }
+
+ public void initImplementation(Object implementation)
+ {
+ this.implementation = implementation;
+ }
+
+ public String getClassName()
+ {
+ return "Continuation";
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ throw Context.reportRuntimeError("Direct call is not supported");
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return Interpreter.restartContinuation(this, cx, scope, args);
+ }
+
+ public static boolean isContinuationConstructor(IdFunctionObject f)
+ {
+ if (f.hasTag(FTAG) && f.methodId() == Id_constructor) {
+ return true;
+ }
+ return false;
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=0; s="constructor"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(FTAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(FTAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ throw Context.reportRuntimeError("Direct call is not supported");
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+// #string_id_map#
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:16:40 EDT
+ L0: { id = 0; String X = null;
+ if (s.length()==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_constructor = 1,
+ MAX_PROTOTYPE_ID = 1;
+
+// #/string_id_map#
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java
new file mode 100644
index 0000000..ef15710
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebugFrame.java
@@ -0,0 +1,91 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript.debug;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+
+/**
+Interface to implement if the application is interested in receiving debug
+information during execution of a particular script or function.
+*/
+public interface DebugFrame {
+
+/**
+Called when execution is ready to start bytecode interpretation for entered a particular function or script.
+
+@param cx current Context for this thread
+@param activation the activation scope for the function or script.
+@param thisObj value of the JavaScript <code>this</code> object
+@param args the array of arguments
+*/
+ public void onEnter(Context cx, Scriptable activation,
+ Scriptable thisObj, Object[] args);
+/**
+Called when executed code reaches new line in the source.
+@param cx current Context for this thread
+@param lineNumber current line number in the script source
+*/
+ public void onLineChange(Context cx, int lineNumber);
+
+/**
+Called when thrown exception is handled by the function or script.
+@param cx current Context for this thread
+@param ex exception object
+*/
+ public void onExceptionThrown(Context cx, Throwable ex);
+
+/**
+Called when the function or script for this frame is about to return.
+@param cx current Context for this thread
+@param byThrow if true function will leave by throwing exception, otherwise it
+ will execute normal return
+@param resultOrException function result in case of normal return or
+ exception object if about to throw exception
+*/
+ public void onExit(Context cx, boolean byThrow, Object resultOrException);
+
+/**
+Called when the function or script executes a 'debugger' statement.
+@param cx current Context for this thread
+*/
+ public void onDebuggerStatement(Context cx);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java
new file mode 100644
index 0000000..23e7421
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableObject.java
@@ -0,0 +1,61 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript.debug;
+
+/**
+ * This interface exposes debugging information from objects.
+ */
+public interface DebuggableObject {
+
+ /**
+ * Returns an array of ids for the properties of the object.
+ *
+ * <p>All properties, even those with attribute {DontEnum}, are listed.
+ * This allows the debugger to display all properties of the object.<p>
+ *
+ * @return an array of java.lang.Objects with an entry for every
+ * listed property. Properties accessed via an integer index will
+ * have a corresponding
+ * Integer entry in the returned array. Properties accessed by
+ * a String will have a String entry in the returned array.
+ */
+ public Object[] getAllIds();
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java
new file mode 100644
index 0000000..705e442
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/DebuggableScript.java
@@ -0,0 +1,119 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript.debug;
+
+/**
+ * This interface exposes debugging information from executable
+ * code (either functions or top-level scripts).
+ */
+public interface DebuggableScript
+{
+ public boolean isTopLevel();
+
+ /**
+ * Returns true if this is a function, false if it is a script.
+ */
+ public boolean isFunction();
+
+ /**
+ * Get name of the function described by this script.
+ * Return null or an empty string if this script is not a function.
+ */
+ public String getFunctionName();
+
+ /**
+ * Get number of declared parameters in the function.
+ * Return 0 if this script is not a function.
+ *
+ * @see #getParamAndVarCount()
+ * @see #getParamOrVarName(int index)
+ */
+ public int getParamCount();
+
+ /**
+ * Get number of declared parameters and local variables.
+ * Return number of declared global variables if this script is not a
+ * function.
+ *
+ * @see #getParamCount()
+ * @see #getParamOrVarName(int index)
+ */
+ public int getParamAndVarCount();
+
+ /**
+ * Get name of a declared parameter or local variable.
+ * <tt>index</tt> should be less then {@link #getParamAndVarCount()}.
+ * If <tt>index&nbsp;&lt;&nbsp;{@link #getParamCount()}</tt>, return
+ * the name of the corresponding parameter, otherwise return the name
+ * of variable.
+ * If this script is not function, return the name of the declared
+ * global variable.
+ */
+ public String getParamOrVarName(int index);
+
+ /**
+ * Get the name of the source (usually filename or URL)
+ * of the script.
+ */
+ public String getSourceName();
+
+ /**
+ * Returns true if this script or function were runtime-generated
+ * from JavaScript using <tt>eval</tt> function or <tt>Function</tt>
+ * or <tt>Script</tt> constructors.
+ */
+ public boolean isGeneratedScript();
+
+ /**
+ * Get array containing the line numbers that
+ * that can be passed to <code>DebugFrame.onLineChange()<code>.
+ * Note that line order in the resulting array is arbitrary
+ */
+ public int[] getLineNumbers();
+
+ public int getFunctionCount();
+
+ public DebuggableScript getFunction(int index);
+
+ public DebuggableScript getParent();
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java
new file mode 100644
index 0000000..bfac153
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/debug/Debugger.java
@@ -0,0 +1,69 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript.debug;
+
+import org.mozilla.javascript.Context;
+
+/**
+Interface to implement if the application is interested in receiving debug
+information.
+*/
+public interface Debugger {
+
+/**
+Called when compilation of a particular function or script into internal
+bytecode is done.
+
+@param cx current Context for this thread
+@param fnOrScript object describing the function or script
+@param source the function or script source
+*/
+ void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
+ String source);
+
+/**
+Called when execution entered a particular function or script.
+
+@return implementation of DebugFrame which receives debug information during
+ the function or script execution or null otherwise
+*/
+ DebugFrame getFrame(Context cx, DebuggableScript fnOrScript);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java
new file mode 100644
index 0000000..f5d1522
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk11/VMBridge_jdk11.java
@@ -0,0 +1,84 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.jdk11;
+
+import java.lang.reflect.Member;
+import java.util.Hashtable;
+
+import org.mozilla.javascript.*;
+
+public class VMBridge_jdk11 extends VMBridge
+{
+ private Hashtable threadsWithContext = new Hashtable();
+
+ protected Object getThreadContextHelper()
+ {
+ return Thread.currentThread();
+ }
+
+ protected Context getContext(Object contextHelper)
+ {
+ Thread t = (Thread)contextHelper;
+ return (Context)threadsWithContext.get(t);
+ }
+
+ protected void setContext(Object contextHelper, Context cx)
+ {
+ Thread t = (Thread)contextHelper;
+ if (cx == null) {
+ // Allow to garbage collect thread reference
+ threadsWithContext.remove(t);
+ } else {
+ threadsWithContext.put(t, cx);
+ }
+ }
+
+ protected ClassLoader getCurrentThreadClassLoader()
+ {
+ return null;
+ }
+
+ protected boolean tryToMakeAccessible(Object accessibleObject)
+ {
+ return false;
+ }
+
+ protected boolean isVarArgs(Member member) {
+ return false;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java
new file mode 100644
index 0000000..c33e9b4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk13/VMBridge_jdk13.java
@@ -0,0 +1,157 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.jdk13;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.lang.reflect.Proxy;
+
+import org.mozilla.javascript.*;
+
+public class VMBridge_jdk13 extends VMBridge
+{
+ private ThreadLocal contextLocal = new ThreadLocal();
+
+ protected Object getThreadContextHelper()
+ {
+ // To make subsequent batch calls to getContext/setContext faster
+ // associate permanently one element array with contextLocal
+ // so getContext/setContext would need just to read/write the first
+ // array element.
+ // Note that it is necessary to use Object[], not Context[] to allow
+ // garbage collection of Rhino classes. For details see comments
+ // by Attila Szegedi in
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=281067#c5
+
+ Object[] storage = (Object[])contextLocal.get();
+ if (storage == null) {
+ storage = new Object[1];
+ contextLocal.set(storage);
+ }
+ return storage;
+ }
+
+ protected Context getContext(Object contextHelper)
+ {
+ Object[] storage = (Object[])contextHelper;
+ return (Context)storage[0];
+ }
+
+ protected void setContext(Object contextHelper, Context cx)
+ {
+ Object[] storage = (Object[])contextHelper;
+ storage[0] = cx;
+ }
+
+ protected ClassLoader getCurrentThreadClassLoader()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ protected boolean tryToMakeAccessible(Object accessibleObject)
+ {
+ if (!(accessibleObject instanceof AccessibleObject)) {
+ return false;
+ }
+ AccessibleObject accessible = (AccessibleObject)accessibleObject;
+ if (accessible.isAccessible()) {
+ return true;
+ }
+ try {
+ accessible.setAccessible(true);
+ } catch (Exception ex) { }
+
+ return accessible.isAccessible();
+ }
+
+ protected Object getInterfaceProxyHelper(ContextFactory cf,
+ Class[] interfaces)
+ {
+ // XXX: How to handle interfaces array withclasses from different
+ // class loaders? Using cf.getApplicationClassLoader() ?
+ ClassLoader loader = interfaces[0].getClassLoader();
+ Class cl = Proxy.getProxyClass(loader, interfaces);
+ Constructor c;
+ try {
+ c = cl.getConstructor(new Class[] { InvocationHandler.class });
+ } catch (NoSuchMethodException ex) {
+ // Should not happen
+ throw Kit.initCause(new IllegalStateException(), ex);
+ }
+ return c;
+ }
+
+ protected Object newInterfaceProxy(Object proxyHelper,
+ final ContextFactory cf,
+ final InterfaceAdapter adapter,
+ final Object target,
+ final Scriptable topScope)
+ {
+ Constructor c = (Constructor)proxyHelper;
+
+ InvocationHandler handler = new InvocationHandler() {
+ public Object invoke(Object proxy,
+ Method method,
+ Object[] args)
+ {
+ return adapter.invoke(cf, target, topScope, method, args);
+ }
+ };
+ Object proxy;
+ try {
+ proxy = c.newInstance(new Object[] { handler });
+ } catch (InvocationTargetException ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ } catch (IllegalAccessException ex) {
+ // Shouls not happen
+ throw Kit.initCause(new IllegalStateException(), ex);
+ } catch (InstantiationException ex) {
+ // Shouls not happen
+ throw Kit.initCause(new IllegalStateException(), ex);
+ }
+ return proxy;
+ }
+
+ protected boolean isVarArgs(Member member) {
+ return false;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java
new file mode 100644
index 0000000..0ffaf9d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/jdk15/VMBridge_jdk15.java
@@ -0,0 +1,87 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.jdk15;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.util.Iterator;
+import org.mozilla.javascript.*;
+
+public class VMBridge_jdk15 extends org.mozilla.javascript.jdk13.VMBridge_jdk13
+{
+ public VMBridge_jdk15() throws SecurityException, InstantiationException {
+ try {
+ // Just try and see if we can access the isVarArgs method.
+ // We want to fail loading if the method does not exist
+ // so that we can load a bridge to an older JDK instead.
+ Method.class.getMethod("isVarArgs", (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ // Throw a fitting exception that is handled by
+ // org.mozilla.javascript.Kit.newInstanceOrNull:
+ throw new InstantiationException(e.getMessage());
+ }
+ }
+
+ public boolean isVarArgs(Member member) {
+ if (member instanceof Method)
+ return ((Method) member).isVarArgs();
+ else if (member instanceof Constructor)
+ return ((Constructor) member).isVarArgs();
+ else
+ return false;
+ }
+
+ /**
+ * If "obj" is a java.util.Iterator or a java.lang.Iterable, return a
+ * wrapping as a JavaScript Iterator. Otherwise, return null.
+ * This method is in VMBridge since Iterable is a JDK 1.5 addition.
+ */
+ public Iterator getJavaIterator(Context cx, Scriptable scope, Object obj) {
+ if (obj instanceof Wrapper) {
+ Object unwrapped = ((Wrapper) obj).unwrap();
+ Iterator iterator = null;
+ if (unwrapped instanceof Iterator)
+ iterator = (Iterator) unwrapped;
+ if (unwrapped instanceof Iterable)
+ iterator = ((Iterable)unwrapped).iterator();
+ return iterator;
+ }
+ return null;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java
new file mode 100644
index 0000000..bd56714
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Block.java
@@ -0,0 +1,615 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+
+import java.util.Hashtable;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+class Block
+{
+
+ private static class FatBlock
+ {
+
+ private static Block[] reduceToArray(ObjToIntMap map)
+ {
+ Block[] result = null;
+ if (!map.isEmpty()) {
+ result = new Block[map.size()];
+ int i = 0;
+ ObjToIntMap.Iterator iter = map.newIterator();
+ for (iter.start(); !iter.done(); iter.next()) {
+ FatBlock fb = (FatBlock)(iter.getKey());
+ result[i++] = fb.realBlock;
+ }
+ }
+ return result;
+ }
+
+ void addSuccessor(FatBlock b) { successors.put(b, 0); }
+ void addPredecessor(FatBlock b) { predecessors.put(b, 0); }
+
+ Block[] getSuccessors() { return reduceToArray(successors); }
+ Block[] getPredecessors() { return reduceToArray(predecessors); }
+
+ // all the Blocks that come immediately after this
+ private ObjToIntMap successors = new ObjToIntMap();
+ // all the Blocks that come immediately before this
+ private ObjToIntMap predecessors = new ObjToIntMap();
+
+ Block realBlock;
+ }
+
+ Block(int startNodeIndex, int endNodeIndex)
+ {
+ itsStartNodeIndex = startNodeIndex;
+ itsEndNodeIndex = endNodeIndex;
+ }
+
+ static void runFlowAnalyzes(OptFunctionNode fn, Node[] statementNodes)
+ {
+ int paramCount = fn.fnode.getParamCount();
+ int varCount = fn.fnode.getParamAndVarCount();
+ int[] varTypes = new int[varCount];
+ // If the variable is a parameter, it could have any type.
+ for (int i = 0; i != paramCount; ++i) {
+ varTypes[i] = Optimizer.AnyType;
+ }
+ // If the variable is from a "var" statement, its typeEvent will be set
+ // when we see the setVar node.
+ for (int i = paramCount; i != varCount; ++i) {
+ varTypes[i] = Optimizer.NoType;
+ }
+
+ Block[] theBlocks = buildBlocks(statementNodes);
+
+ if (DEBUG) {
+ ++debug_blockCount;
+ System.out.println("-------------------"+fn.fnode.getFunctionName()+" "+debug_blockCount+"--------");
+ System.out.println(toString(theBlocks, statementNodes));
+ }
+
+ reachingDefDataFlow(fn, statementNodes, theBlocks, varTypes);
+ typeFlow(fn, statementNodes, theBlocks, varTypes);
+
+ if (DEBUG) {
+ for (int i = 0; i < theBlocks.length; i++) {
+ System.out.println("For block " + theBlocks[i].itsBlockID);
+ theBlocks[i].printLiveOnEntrySet(fn);
+ }
+ System.out.println("Variable Table, size = " + varCount);
+ for (int i = 0; i != varCount; i++) {
+ System.out.println("["+i+"] type: "+varTypes[i]);
+ }
+ }
+
+ for (int i = paramCount; i != varCount; i++) {
+ if (varTypes[i] == Optimizer.NumberType) {
+ fn.setIsNumberVar(i);
+ }
+ }
+
+ }
+
+ private static Block[] buildBlocks(Node[] statementNodes)
+ {
+ // a mapping from each target node to the block it begins
+ Hashtable theTargetBlocks = new Hashtable();
+ ObjArray theBlocks = new ObjArray();
+
+ // there's a block that starts at index 0
+ int beginNodeIndex = 0;
+
+ for (int i = 0; i < statementNodes.length; i++) {
+ switch (statementNodes[i].getType()) {
+ case Token.TARGET :
+ {
+ if (i != beginNodeIndex) {
+ FatBlock fb = newFatBlock(beginNodeIndex, i - 1);
+ if (statementNodes[beginNodeIndex].getType()
+ == Token.TARGET)
+ theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
+ theBlocks.add(fb);
+ // start the next block at this node
+ beginNodeIndex = i;
+ }
+ }
+ break;
+ case Token.IFNE :
+ case Token.IFEQ :
+ case Token.GOTO :
+ {
+ FatBlock fb = newFatBlock(beginNodeIndex, i);
+ if (statementNodes[beginNodeIndex].getType()
+ == Token.TARGET)
+ theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
+ theBlocks.add(fb);
+ // start the next block at the next node
+ beginNodeIndex = i + 1;
+ }
+ break;
+ }
+ }
+
+ if (beginNodeIndex != statementNodes.length) {
+ FatBlock fb = newFatBlock(beginNodeIndex, statementNodes.length - 1);
+ if (statementNodes[beginNodeIndex].getType() == Token.TARGET)
+ theTargetBlocks.put(statementNodes[beginNodeIndex], fb);
+ theBlocks.add(fb);
+ }
+
+ // build successor and predecessor links
+
+ for (int i = 0; i < theBlocks.size(); i++) {
+ FatBlock fb = (FatBlock)(theBlocks.get(i));
+
+ Node blockEndNode = statementNodes[fb.realBlock.itsEndNodeIndex];
+ int blockEndNodeType = blockEndNode.getType();
+
+ if ((blockEndNodeType != Token.GOTO)
+ && (i < (theBlocks.size() - 1))) {
+ FatBlock fallThruTarget = (FatBlock)(theBlocks.get(i + 1));
+ fb.addSuccessor(fallThruTarget);
+ fallThruTarget.addPredecessor(fb);
+ }
+
+
+ if ( (blockEndNodeType == Token.IFNE)
+ || (blockEndNodeType == Token.IFEQ)
+ || (blockEndNodeType == Token.GOTO) ) {
+ Node target = ((Node.Jump)blockEndNode).target;
+ FatBlock branchTargetBlock
+ = (FatBlock)(theTargetBlocks.get(target));
+ target.putProp(Node.TARGETBLOCK_PROP,
+ branchTargetBlock.realBlock);
+ fb.addSuccessor(branchTargetBlock);
+ branchTargetBlock.addPredecessor(fb);
+ }
+ }
+
+ Block[] result = new Block[theBlocks.size()];
+
+ for (int i = 0; i < theBlocks.size(); i++) {
+ FatBlock fb = (FatBlock)(theBlocks.get(i));
+ Block b = fb.realBlock;
+ b.itsSuccessors = fb.getSuccessors();
+ b.itsPredecessors = fb.getPredecessors();
+ b.itsBlockID = i;
+ result[i] = b;
+ }
+
+ return result;
+ }
+
+ private static FatBlock newFatBlock(int startNodeIndex, int endNodeIndex)
+ {
+ FatBlock fb = new FatBlock();
+ fb.realBlock = new Block(startNodeIndex, endNodeIndex);
+ return fb;
+ }
+
+ private static String toString(Block[] blockList, Node[] statementNodes)
+ {
+ if (!DEBUG) return null;
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ pw.println(blockList.length + " Blocks");
+ for (int i = 0; i < blockList.length; i++) {
+ Block b = blockList[i];
+ pw.println("#" + b.itsBlockID);
+ pw.println("from " + b.itsStartNodeIndex
+ + " "
+ + statementNodes[b.itsStartNodeIndex].toString());
+ pw.println("thru " + b.itsEndNodeIndex
+ + " "
+ + statementNodes[b.itsEndNodeIndex].toString());
+ pw.print("Predecessors ");
+ if (b.itsPredecessors != null) {
+ for (int j = 0; j < b.itsPredecessors.length; j++)
+ pw.print(b.itsPredecessors[j].itsBlockID + " ");
+ pw.println();
+ }
+ else
+ pw.println("none");
+ pw.print("Successors ");
+ if (b.itsSuccessors != null) {
+ for (int j = 0; j < b.itsSuccessors.length; j++)
+ pw.print(b.itsSuccessors[j].itsBlockID + " ");
+ pw.println();
+ }
+ else
+ pw.println("none");
+ }
+ return sw.toString();
+ }
+
+ private static void reachingDefDataFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
+ {
+/*
+ initialize the liveOnEntry and liveOnExit sets, then discover the variables
+ that are def'd by each function, and those that are used before being def'd
+ (hence liveOnEntry)
+*/
+ for (int i = 0; i < theBlocks.length; i++) {
+ theBlocks[i].initLiveOnEntrySets(fn, statementNodes);
+ }
+/*
+ this visits every block starting at the last, re-adding the predecessors of
+ any block whose inputs change as a result of the dataflow.
+ REMIND, better would be to visit in CFG postorder
+*/
+ boolean visit[] = new boolean[theBlocks.length];
+ boolean doneOnce[] = new boolean[theBlocks.length];
+ int vIndex = theBlocks.length - 1;
+ boolean needRescan = false;
+ visit[vIndex] = true;
+ while (true) {
+ if (visit[vIndex] || !doneOnce[vIndex]) {
+ doneOnce[vIndex] = true;
+ visit[vIndex] = false;
+ if (theBlocks[vIndex].doReachedUseDataFlow()) {
+ Block pred[] = theBlocks[vIndex].itsPredecessors;
+ if (pred != null) {
+ for (int i = 0; i < pred.length; i++) {
+ int index = pred[i].itsBlockID;
+ visit[index] = true;
+ needRescan |= (index > vIndex);
+ }
+ }
+ }
+ }
+ if (vIndex == 0) {
+ if (needRescan) {
+ vIndex = theBlocks.length - 1;
+ needRescan = false;
+ }
+ else
+ break;
+ }
+ else
+ vIndex--;
+ }
+/*
+ if any variable is live on entry to block 0, we have to mark it as
+ not jRegable - since it means that someone is trying to access the
+ 'undefined'-ness of that variable.
+*/
+
+ theBlocks[0].markAnyTypeVariables(varTypes);
+ }
+
+ private static void typeFlow(OptFunctionNode fn, Node[] statementNodes, Block theBlocks[], int[] varTypes)
+ {
+ boolean visit[] = new boolean[theBlocks.length];
+ boolean doneOnce[] = new boolean[theBlocks.length];
+ int vIndex = 0;
+ boolean needRescan = false;
+ visit[vIndex] = true;
+ while (true) {
+ if (visit[vIndex] || !doneOnce[vIndex]) {
+ doneOnce[vIndex] = true;
+ visit[vIndex] = false;
+ if (theBlocks[vIndex].doTypeFlow(fn, statementNodes, varTypes))
+ {
+ Block succ[] = theBlocks[vIndex].itsSuccessors;
+ if (succ != null) {
+ for (int i = 0; i < succ.length; i++) {
+ int index = succ[i].itsBlockID;
+ visit[index] = true;
+ needRescan |= (index < vIndex);
+ }
+ }
+ }
+ }
+ if (vIndex == (theBlocks.length - 1)) {
+ if (needRescan) {
+ vIndex = 0;
+ needRescan = false;
+ }
+ else
+ break;
+ }
+ else
+ vIndex++;
+ }
+ }
+
+ private static boolean assignType(int[] varTypes, int index, int type)
+ {
+ return type != (varTypes[index] |= type);
+ }
+
+ private void markAnyTypeVariables(int[] varTypes)
+ {
+ for (int i = 0; i != varTypes.length; i++) {
+ if (itsLiveOnEntrySet.test(i)) {
+ assignType(varTypes, i, Optimizer.AnyType);
+ }
+ }
+
+ }
+
+ /*
+ We're tracking uses and defs - in order to
+ build the def set and to identify the last use
+ nodes.
+
+ The itsNotDefSet is built reversed then flipped later.
+
+ */
+ private void lookForVariableAccess(OptFunctionNode fn, Node n)
+ {
+ switch (n.getType()) {
+ case Token.DEC :
+ case Token.INC :
+ {
+ Node child = n.getFirstChild();
+ if (child.getType() == Token.GETVAR) {
+ int varIndex = fn.getVarIndex(child);
+ if (!itsNotDefSet.test(varIndex))
+ itsUseBeforeDefSet.set(varIndex);
+ itsNotDefSet.set(varIndex);
+ }
+ }
+ break;
+ case Token.SETVAR :
+ {
+ Node lhs = n.getFirstChild();
+ Node rhs = lhs.getNext();
+ lookForVariableAccess(fn, rhs);
+ itsNotDefSet.set(fn.getVarIndex(n));
+ }
+ break;
+ case Token.GETVAR :
+ {
+ int varIndex = fn.getVarIndex(n);
+ if (!itsNotDefSet.test(varIndex))
+ itsUseBeforeDefSet.set(varIndex);
+ }
+ break;
+ default :
+ Node child = n.getFirstChild();
+ while (child != null) {
+ lookForVariableAccess(fn, child);
+ child = child.getNext();
+ }
+ break;
+ }
+ }
+
+ /*
+ build the live on entry/exit sets.
+ Then walk the trees looking for defs/uses of variables
+ and build the def and useBeforeDef sets.
+ */
+ private void initLiveOnEntrySets(OptFunctionNode fn, Node[] statementNodes)
+ {
+ int listLength = fn.getVarCount();
+ itsUseBeforeDefSet = new DataFlowBitSet(listLength);
+ itsNotDefSet = new DataFlowBitSet(listLength);
+ itsLiveOnEntrySet = new DataFlowBitSet(listLength);
+ itsLiveOnExitSet = new DataFlowBitSet(listLength);
+ for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
+ Node n = statementNodes[i];
+ lookForVariableAccess(fn, n);
+ }
+ itsNotDefSet.not(); // truth in advertising
+ }
+
+ /*
+ the liveOnEntry of each successor is the liveOnExit for this block.
+ The liveOnEntry for this block is -
+ liveOnEntry = liveOnExit - defsInThisBlock + useBeforeDefsInThisBlock
+
+ */
+ private boolean doReachedUseDataFlow()
+ {
+ itsLiveOnExitSet.clear();
+ if (itsSuccessors != null)
+ for (int i = 0; i < itsSuccessors.length; i++)
+ itsLiveOnExitSet.or(itsSuccessors[i].itsLiveOnEntrySet);
+ return itsLiveOnEntrySet.df2(itsLiveOnExitSet,
+ itsUseBeforeDefSet, itsNotDefSet);
+ }
+
+ /*
+ the type of an expression is relatively unknown. Cases we can be sure
+ about are -
+ Literals,
+ Arithmetic operations - always return a Number
+ */
+ private static int findExpressionType(OptFunctionNode fn, Node n,
+ int[] varTypes)
+ {
+ switch (n.getType()) {
+ case Token.NUMBER :
+ return Optimizer.NumberType;
+
+ case Token.CALL :
+ case Token.NEW :
+ case Token.REF_CALL :
+ return Optimizer.AnyType;
+
+ case Token.GETELEM :
+ return Optimizer.AnyType;
+
+ case Token.GETVAR :
+ return varTypes[fn.getVarIndex(n)];
+
+ case Token.INC :
+ case Token.DEC :
+ case Token.DIV:
+ case Token.MOD:
+ case Token.BITOR:
+ case Token.BITXOR:
+ case Token.BITAND:
+ case Token.LSH:
+ case Token.RSH:
+ case Token.URSH:
+ case Token.SUB :
+ return Optimizer.NumberType;
+
+ case Token.ARRAYLIT:
+ case Token.OBJECTLIT:
+ return Optimizer.AnyType; // XXX: actually, we know it's not
+ // number, but no type yet for that
+
+ case Token.ADD : {
+ // if the lhs & rhs are known to be numbers, we can be sure that's
+ // the result, otherwise it could be a string.
+ Node child = n.getFirstChild();
+ int lType = findExpressionType(fn, child, varTypes);
+ int rType = findExpressionType(fn, child.getNext(), varTypes);
+ return lType | rType; // we're not distinguishing strings yet
+ }
+ }
+
+ Node child = n.getFirstChild();
+ if (child == null) {
+ return Optimizer.AnyType;
+ } else {
+ int result = Optimizer.NoType;
+ while (child != null) {
+ result |= findExpressionType(fn, child, varTypes);
+ child = child.getNext();
+ }
+ return result;
+ }
+ }
+
+ private static boolean findDefPoints(OptFunctionNode fn, Node n,
+ int[] varTypes)
+ {
+ boolean result = false;
+ Node child = n.getFirstChild();
+ switch (n.getType()) {
+ default :
+ while (child != null) {
+ result |= findDefPoints(fn, child, varTypes);
+ child = child.getNext();
+ }
+ break;
+ case Token.DEC :
+ case Token.INC :
+ if (child.getType() == Token.GETVAR) {
+ // theVar is a Number now
+ int i = fn.getVarIndex(child);
+ result |= assignType(varTypes, i, Optimizer.NumberType);
+ }
+ break;
+ case Token.SETPROP :
+ case Token.SETPROP_OP :
+ if (child.getType() == Token.GETVAR) {
+ int i = fn.getVarIndex(child);
+ assignType(varTypes, i, Optimizer.AnyType);
+ }
+ while (child != null) {
+ result |= findDefPoints(fn, child, varTypes);
+ child = child.getNext();
+ }
+ break;
+ case Token.SETVAR : {
+ Node rValue = child.getNext();
+ int theType = findExpressionType(fn, rValue, varTypes);
+ int i = fn.getVarIndex(n);
+ result |= assignType(varTypes, i, theType);
+ break;
+ }
+ }
+ return result;
+ }
+
+ private boolean doTypeFlow(OptFunctionNode fn, Node[] statementNodes,
+ int[] varTypes)
+ {
+ boolean changed = false;
+
+ for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) {
+ Node n = statementNodes[i];
+ if (n != null)
+ changed |= findDefPoints(fn, n, varTypes);
+ }
+
+ return changed;
+ }
+
+ private void printLiveOnEntrySet(OptFunctionNode fn)
+ {
+ if (DEBUG) {
+ for (int i = 0; i < fn.getVarCount(); i++) {
+ String name = fn.fnode.getParamOrVarName(i);
+ if (itsUseBeforeDefSet.test(i))
+ System.out.println(name + " is used before def'd");
+ if (itsNotDefSet.test(i))
+ System.out.println(name + " is not def'd");
+ if (itsLiveOnEntrySet.test(i))
+ System.out.println(name + " is live on entry");
+ if (itsLiveOnExitSet.test(i))
+ System.out.println(name + " is live on exit");
+ }
+ }
+ }
+
+ // all the Blocks that come immediately after this
+ private Block[] itsSuccessors;
+ // all the Blocks that come immediately before this
+ private Block[] itsPredecessors;
+
+ private int itsStartNodeIndex; // the Node at the start of the block
+ private int itsEndNodeIndex; // the Node at the end of the block
+
+ private int itsBlockID; // a unique index for each block
+
+// reaching def bit sets -
+ private DataFlowBitSet itsLiveOnEntrySet;
+ private DataFlowBitSet itsLiveOnExitSet;
+ private DataFlowBitSet itsUseBeforeDefSet;
+ private DataFlowBitSet itsNotDefSet;
+
+ static final boolean DEBUG = false;
+ private static int debug_blockCount;
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java
new file mode 100644
index 0000000..4a69c6a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/ClassCompiler.java
@@ -0,0 +1,214 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Generates class files from script sources.
+ *
+ * since 1.5 Release 5
+ * @author Igor Bukanov
+ */
+
+public class ClassCompiler
+{
+ /**
+ * Construct ClassCompiler that uses the specified compiler environment
+ * when generating classes.
+ */
+ public ClassCompiler(CompilerEnvirons compilerEnv)
+ {
+ if (compilerEnv == null) throw new IllegalArgumentException();
+ this.compilerEnv = compilerEnv;
+ this.mainMethodClassName = Codegen.DEFAULT_MAIN_METHOD_CLASS;
+ }
+
+ /**
+ * Set the class name to use for main method implementation.
+ * The class must have a method matching
+ * <tt>public static void main(Script sc, String[] args)</tt>, it will be
+ * called when <tt>main(String[] args)</tt> is called in the generated
+ * class. The class name should be fully qulified name and include the
+ * package name like in <tt>org.foo.Bar<tt>.
+ */
+ public void setMainMethodClass(String className)
+ {
+ // XXX Should this check for a valid class name?
+ mainMethodClassName = className;
+ }
+
+ /**
+ * Get the name of the class for main method implementation.
+ * @see #setMainMethodClass(String)
+ */
+ public String getMainMethodClass()
+ {
+ return mainMethodClassName;
+ }
+
+ /**
+ * Get the compiler environment the compiler uses.
+ */
+ public CompilerEnvirons getCompilerEnv()
+ {
+ return compilerEnv;
+ }
+
+ /**
+ * Get the class that the generated target will extend.
+ */
+ public Class getTargetExtends()
+ {
+ return targetExtends;
+ }
+
+ /**
+ * Set the class that the generated target will extend.
+ *
+ * @param extendsClass the class it extends
+ */
+ public void setTargetExtends(Class extendsClass)
+ {
+ targetExtends = extendsClass;
+ }
+
+ /**
+ * Get the interfaces that the generated target will implement.
+ */
+ public Class[] getTargetImplements()
+ {
+ return targetImplements == null ? null : (Class[])targetImplements.clone();
+ }
+
+ /**
+ * Set the interfaces that the generated target will implement.
+ *
+ * @param implementsClasses an array of Class objects, one for each
+ * interface the target will extend
+ */
+ public void setTargetImplements(Class[] implementsClasses)
+ {
+ targetImplements = implementsClasses == null ? null : (Class[])implementsClasses.clone();
+ }
+
+ /**
+ * Build class name for a auxiliary class generated by compiler.
+ * If the compiler needs to generate extra classes beyond the main class,
+ * it will call this function to build the auxiliary class name.
+ * The default implementation simply appends auxMarker to mainClassName
+ * but this can be overridden.
+ */
+ protected String makeAuxiliaryClassName(String mainClassName,
+ String auxMarker)
+ {
+ return mainClassName+auxMarker;
+ }
+
+ /**
+ * Compile JavaScript source into one or more Java class files.
+ * The first compiled class will have name mainClassName.
+ * If the results of {@link #getTargetExtends()} or
+ * {@link #getTargetImplements()} are not null, then the first compiled
+ * class will extend the specified super class and implement
+ * specified interfaces.
+ *
+ * @return array where elements with even indexes specifies class name
+ * and the following odd index gives class file body as byte[]
+ * array. The initial element of the array always holds
+ * mainClassName and array[1] holds its byte code.
+ */
+ public Object[] compileToClassFiles(String source,
+ String sourceLocation,
+ int lineno,
+ String mainClassName)
+ {
+ /*APPJET*/
+ Parser p =
+ InformativeParser.makeParser(compilerEnv,
+ compilerEnv.getErrorReporter());
+ ScriptOrFnNode tree = p.parse(source, sourceLocation, lineno);
+ String encodedSource = p.getEncodedSource();
+
+ Class superClass = getTargetExtends();
+ Class[] interfaces = getTargetImplements();
+ String scriptClassName;
+ boolean isPrimary = (interfaces == null && superClass == null);
+ if (isPrimary) {
+ scriptClassName = mainClassName;
+ } else {
+ scriptClassName = makeAuxiliaryClassName(mainClassName, "1");
+ }
+
+ Codegen codegen = new Codegen();
+ codegen.setMainMethodClass(mainMethodClassName);
+ byte[] scriptClassBytes
+ = codegen.compileToClassFile(compilerEnv, scriptClassName,
+ tree, encodedSource,
+ false);
+
+ if (isPrimary) {
+ return new Object[] { scriptClassName, scriptClassBytes };
+ }
+ int functionCount = tree.getFunctionCount();
+ ObjToIntMap functionNames = new ObjToIntMap(functionCount);
+ for (int i = 0; i != functionCount; ++i) {
+ FunctionNode ofn = tree.getFunctionNode(i);
+ String name = ofn.getFunctionName();
+ if (name != null && name.length() != 0) {
+ functionNames.put(name, ofn.getParamCount());
+ }
+ }
+ if (superClass == null) {
+ superClass = ScriptRuntime.ObjectClass;
+ }
+ byte[] mainClassBytes
+ = JavaAdapter.createAdapterCode(
+ functionNames, mainClassName,
+ superClass, interfaces, scriptClassName);
+
+ return new Object[] { mainClassName, mainClassBytes,
+ scriptClassName, scriptClassBytes };
+ }
+
+ private String mainMethodClassName;
+ private CompilerEnvirons compilerEnv;
+ private Class targetExtends;
+ private Class[] targetImplements;
+
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java
new file mode 100644
index 0000000..64952bf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Codegen.java
@@ -0,0 +1,5031 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Kemal Bayram
+ * Igor Bukanov
+ * Bob Jervis
+ * Roger Lawrence
+ * Andi Vajda
+ * Hannes Wallnoefer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+import org.mozilla.classfile.*;
+import java.util.*;
+import java.lang.reflect.Constructor;
+import java.util.Hashtable;
+
+/**
+ * This class generates code for a given IR tree.
+ *
+ * @author Norris Boyd
+ * @author Roger Lawrence
+ */
+
+public class Codegen implements Evaluator
+{
+ public void captureStackInfo(RhinoException ex) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getSourcePositionFromStack(Context cx, int[] linep) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPatchedStack(RhinoException ex, String nativeStackTrace) {
+ throw new UnsupportedOperationException();
+ }
+
+ public List getScriptStack(RhinoException ex) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setEvalScriptFlag(Script script) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object compile(CompilerEnvirons compilerEnv,
+ ScriptOrFnNode tree,
+ String encodedSource,
+ boolean returnFunction)
+ {
+ int serial;
+ synchronized (globalLock) {
+ serial = ++globalSerialClassCounter;
+ }
+ String mainClassName = "org.mozilla.javascript.gen.c"+serial;
+
+ byte[] mainClassBytes = compileToClassFile(compilerEnv, mainClassName,
+ tree, encodedSource,
+ returnFunction);
+
+ return new Object[] { mainClassName, mainClassBytes };
+ }
+
+ public Script createScriptObject(Object bytecode,
+ Object staticSecurityDomain)
+ {
+ Class cl = defineClass(bytecode, staticSecurityDomain);
+
+ Script script;
+ try {
+ script = (Script)cl.newInstance();
+ } catch (Exception ex) {
+ throw new RuntimeException
+ ("Unable to instantiate compiled class:"+ex.toString());
+ }
+ return script;
+ }
+
+ public Function createFunctionObject(Context cx, Scriptable scope,
+ Object bytecode,
+ Object staticSecurityDomain)
+ {
+ Class cl = defineClass(bytecode, staticSecurityDomain);
+
+ NativeFunction f;
+ try {
+ Constructor ctor = cl.getConstructors()[0];
+ Object[] initArgs = { scope, cx, new Integer(0) };
+ f = (NativeFunction)ctor.newInstance(initArgs);
+ } catch (Exception ex) {
+ throw new RuntimeException
+ ("Unable to instantiate compiled class:"+ex.toString());
+ }
+ return f;
+ }
+
+ private Class defineClass(Object bytecode,
+ Object staticSecurityDomain)
+ {
+ Object[] nameBytesPair = (Object[])bytecode;
+ String className = (String)nameBytesPair[0];
+ byte[] classBytes = (byte[])nameBytesPair[1];
+
+ // The generated classes in this case refer only to Rhino classes
+ // which must be accessible through this class loader
+ ClassLoader rhinoLoader = getClass().getClassLoader();
+ GeneratedClassLoader loader;
+ loader = SecurityController.createLoader(rhinoLoader,
+ staticSecurityDomain);
+ Exception e;
+ try {
+ Class cl = loader.defineClass(className, classBytes);
+ loader.linkClass(cl);
+ return cl;
+ } catch (SecurityException x) {
+ e = x;
+ } catch (IllegalArgumentException x) {
+ e = x;
+ }
+ throw new RuntimeException("Malformed optimizer package " + e);
+ }
+
+ byte[] compileToClassFile(CompilerEnvirons compilerEnv,
+ String mainClassName,
+ ScriptOrFnNode scriptOrFn,
+ String encodedSource,
+ boolean returnFunction)
+ {
+ this.compilerEnv = compilerEnv;
+
+ transform(scriptOrFn);
+
+ if (Token.printTrees) {
+ /*APPJET*///System.out.println(scriptOrFn.toStringTree(scriptOrFn));
+ }
+
+ if (returnFunction) {
+ scriptOrFn = scriptOrFn.getFunctionNode(0);
+ }
+
+ initScriptOrFnNodesData(scriptOrFn);
+
+ this.mainClassName = mainClassName;
+ this.mainClassSignature
+ = ClassFileWriter.classNameToSignature(mainClassName);
+
+ try {
+ return generateCode(encodedSource);
+ } catch (ClassFileWriter.ClassFileFormatException e) {
+ throw reportClassFileFormatException(scriptOrFn, e.getMessage());
+ }
+ }
+
+ private RuntimeException reportClassFileFormatException(
+ ScriptOrFnNode scriptOrFn,
+ String message)
+ {
+ String msg = scriptOrFn instanceof FunctionNode
+ ? ScriptRuntime.getMessage2("msg.while.compiling.fn",
+ ((FunctionNode)scriptOrFn).getFunctionName(), message)
+ : ScriptRuntime.getMessage1("msg.while.compiling.script", message);
+ return Context.reportRuntimeError(msg, scriptOrFn.getSourceName(),
+ scriptOrFn.getLineno(), null, 0);
+ }
+
+ private void transform(ScriptOrFnNode tree)
+ {
+ initOptFunctions_r(tree);
+
+ int optLevel = compilerEnv.getOptimizationLevel();
+
+ Hashtable possibleDirectCalls = null;
+ if (optLevel > 0) {
+ /*
+ * Collect all of the contained functions into a hashtable
+ * so that the call optimizer can access the class name & parameter
+ * count for any call it encounters
+ */
+ if (tree.getType() == Token.SCRIPT) {
+ int functionCount = tree.getFunctionCount();
+ for (int i = 0; i != functionCount; ++i) {
+ OptFunctionNode ofn = OptFunctionNode.get(tree, i);
+ if (ofn.fnode.getFunctionType()
+ == FunctionNode.FUNCTION_STATEMENT)
+ {
+ String name = ofn.fnode.getFunctionName();
+ if (name.length() != 0) {
+ if (possibleDirectCalls == null) {
+ possibleDirectCalls = new Hashtable();
+ }
+ possibleDirectCalls.put(name, ofn);
+ }
+ }
+ }
+ }
+ }
+
+ if (possibleDirectCalls != null) {
+ directCallTargets = new ObjArray();
+ }
+
+ OptTransformer ot = new OptTransformer(possibleDirectCalls,
+ directCallTargets);
+ ot.transform(tree);
+
+ if (optLevel > 0) {
+ (new Optimizer()).optimize(tree);
+ }
+ }
+
+ private static void initOptFunctions_r(ScriptOrFnNode scriptOrFn)
+ {
+ for (int i = 0, N = scriptOrFn.getFunctionCount(); i != N; ++i) {
+ FunctionNode fn = scriptOrFn.getFunctionNode(i);
+ new OptFunctionNode(fn);
+ initOptFunctions_r(fn);
+ }
+ }
+
+ private void initScriptOrFnNodesData(ScriptOrFnNode scriptOrFn)
+ {
+ ObjArray x = new ObjArray();
+ collectScriptOrFnNodes_r(scriptOrFn, x);
+
+ int count = x.size();
+ scriptOrFnNodes = new ScriptOrFnNode[count];
+ x.toArray(scriptOrFnNodes);
+
+ scriptOrFnIndexes = new ObjToIntMap(count);
+ for (int i = 0; i != count; ++i) {
+ scriptOrFnIndexes.put(scriptOrFnNodes[i], i);
+ }
+ }
+
+ private static void collectScriptOrFnNodes_r(ScriptOrFnNode n,
+ ObjArray x)
+ {
+ x.add(n);
+ int nestedCount = n.getFunctionCount();
+ for (int i = 0; i != nestedCount; ++i) {
+ collectScriptOrFnNodes_r(n.getFunctionNode(i), x);
+ }
+ }
+
+ private byte[] generateCode(String encodedSource)
+ {
+ boolean hasScript = (scriptOrFnNodes[0].getType() == Token.SCRIPT);
+ boolean hasFunctions = (scriptOrFnNodes.length > 1 || !hasScript);
+
+ String sourceFile = null;
+ if (compilerEnv.isGenerateDebugInfo()) {
+ sourceFile = scriptOrFnNodes[0].getSourceName();
+ }
+
+ ClassFileWriter cfw = new ClassFileWriter(mainClassName,
+ SUPER_CLASS_NAME,
+ sourceFile);
+ cfw.addField(ID_FIELD_NAME, "I",
+ ClassFileWriter.ACC_PRIVATE);
+ cfw.addField(DIRECT_CALL_PARENT_FIELD, mainClassSignature,
+ ClassFileWriter.ACC_PRIVATE);
+ cfw.addField(REGEXP_ARRAY_FIELD_NAME, REGEXP_ARRAY_FIELD_TYPE,
+ ClassFileWriter.ACC_PRIVATE);
+
+ if (hasFunctions) {
+ generateFunctionConstructor(cfw);
+ }
+
+ if (hasScript) {
+ cfw.addInterface("org/mozilla/javascript/Script");
+ generateScriptCtor(cfw);
+ generateMain(cfw);
+ generateExecute(cfw);
+ }
+
+ generateCallMethod(cfw);
+ generateResumeGenerator(cfw);
+
+ generateNativeFunctionOverrides(cfw, encodedSource);
+
+ int count = scriptOrFnNodes.length;
+ for (int i = 0; i != count; ++i) {
+ ScriptOrFnNode n = scriptOrFnNodes[i];
+
+ BodyCodegen bodygen = new BodyCodegen();
+ bodygen.cfw = cfw;
+ bodygen.codegen = this;
+ bodygen.compilerEnv = compilerEnv;
+ bodygen.scriptOrFn = n;
+ bodygen.scriptOrFnIndex = i;
+
+ try {
+ bodygen.generateBodyCode();
+ } catch (ClassFileWriter.ClassFileFormatException e) {
+ throw reportClassFileFormatException(n, e.getMessage());
+ }
+
+ if (n.getType() == Token.FUNCTION) {
+ OptFunctionNode ofn = OptFunctionNode.get(n);
+ generateFunctionInit(cfw, ofn);
+ if (ofn.isTargetOfDirectCall()) {
+ emitDirectConstructor(cfw, ofn);
+ }
+ }
+ }
+
+ if (directCallTargets != null) {
+ int N = directCallTargets.size();
+ for (int j = 0; j != N; ++j) {
+ cfw.addField(getDirectTargetFieldName(j),
+ mainClassSignature,
+ ClassFileWriter.ACC_PRIVATE);
+ }
+ }
+
+ emitRegExpInit(cfw);
+ emitConstantDudeInitializers(cfw);
+
+ return cfw.toByteArray();
+ }
+
+ private void emitDirectConstructor(ClassFileWriter cfw,
+ OptFunctionNode ofn)
+ {
+/*
+ we generate ..
+ Scriptable directConstruct(<directCallArgs>) {
+ Scriptable newInstance = createObject(cx, scope);
+ Object val = <body-name>(cx, scope, newInstance, <directCallArgs>);
+ if (val instanceof Scriptable) {
+ return (Scriptable) val;
+ }
+ return newInstance;
+ }
+*/
+ cfw.startMethod(getDirectCtorName(ofn.fnode),
+ getBodyMethodSignature(ofn.fnode),
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+
+ int argCount = ofn.fnode.getParamCount();
+ int firstLocal = (4 + argCount * 3) + 1;
+
+ cfw.addALoad(0); // this
+ cfw.addALoad(1); // cx
+ cfw.addALoad(2); // scope
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
+ "org/mozilla/javascript/BaseFunction",
+ "createObject",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(firstLocal);
+
+ cfw.addALoad(0);
+ cfw.addALoad(1);
+ cfw.addALoad(2);
+ cfw.addALoad(firstLocal);
+ for (int i = 0; i < argCount; i++) {
+ cfw.addALoad(4 + (i * 3));
+ cfw.addDLoad(5 + (i * 3));
+ }
+ cfw.addALoad(4 + argCount * 3);
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ mainClassName,
+ getBodyMethodName(ofn.fnode),
+ getBodyMethodSignature(ofn.fnode));
+ int exitLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.DUP); // make a copy of direct call result
+ cfw.add(ByteCode.INSTANCEOF, "org/mozilla/javascript/Scriptable");
+ cfw.add(ByteCode.IFEQ, exitLabel);
+ // cast direct call result
+ cfw.add(ByteCode.CHECKCAST, "org/mozilla/javascript/Scriptable");
+ cfw.add(ByteCode.ARETURN);
+ cfw.markLabel(exitLabel);
+
+ cfw.addALoad(firstLocal);
+ cfw.add(ByteCode.ARETURN);
+
+ cfw.stopMethod((short)(firstLocal + 1));
+ }
+
+ static boolean isGenerator(ScriptOrFnNode node)
+ {
+ return (node.getType() == Token.FUNCTION ) &&
+ ((FunctionNode)node).isGenerator();
+ }
+
+ // How dispatch to generators works:
+ // Two methods are generated corresponding to a user-written generator.
+ // One of these creates a generator object (NativeGenerator), which is
+ // returned to the user. The other method contains all of the body code
+ // of the generator.
+ // When a user calls a generator, the call() method dispatches control to
+ // to the method that creates the NativeGenerator object. Subsequently when
+ // the user invokes .next(), .send() or any such method on the generator
+ // object, the resumeGenerator() below dispatches the call to the
+ // method corresponding to the generator body. As a matter of convention
+ // the generator body is given the name of the generator activation function
+ // appended by "_gen".
+ private void generateResumeGenerator(ClassFileWriter cfw)
+ {
+ boolean hasGenerators = false;
+ for (int i=0; i < scriptOrFnNodes.length; i++) {
+ if (isGenerator(scriptOrFnNodes[i]))
+ hasGenerators = true;
+ }
+
+ // if there are no generators defined, we don't implement a
+ // resumeGenerator(). The base class provides a default implementation.
+ if (!hasGenerators)
+ return;
+
+ cfw.startMethod("resumeGenerator",
+ "(Lorg/mozilla/javascript/Context;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "ILjava/lang/Object;" +
+ "Ljava/lang/Object;)Ljava/lang/Object;",
+ (short)(ClassFileWriter.ACC_PUBLIC
+ | ClassFileWriter.ACC_FINAL));
+
+ // load arguments for dispatch to the corresponding *_gen method
+ cfw.addALoad(0);
+ cfw.addALoad(1);
+ cfw.addALoad(2);
+ cfw.addALoad(4);
+ cfw.addALoad(5);
+ cfw.addILoad(3);
+
+ cfw.addLoadThis();
+ cfw.add(ByteCode.GETFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
+
+ int startSwitch = cfw.addTableSwitch(0, scriptOrFnNodes.length - 1);
+ cfw.markTableSwitchDefault(startSwitch);
+ int endlabel = cfw.acquireLabel();
+
+ for (int i = 0; i < scriptOrFnNodes.length; i++) {
+ ScriptOrFnNode n = scriptOrFnNodes[i];
+ cfw.markTableSwitchCase(startSwitch, i, (short)6);
+ if (isGenerator(n)) {
+ String type = "(" +
+ mainClassSignature +
+ "Lorg/mozilla/javascript/Context;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "Ljava/lang/Object;" +
+ "Ljava/lang/Object;I)Ljava/lang/Object;";
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ mainClassName,
+ getBodyMethodName(n) + "_gen",
+ type);
+ cfw.add(ByteCode.ARETURN);
+ } else {
+ cfw.add(ByteCode.GOTO, endlabel);
+ }
+ }
+
+ cfw.markLabel(endlabel);
+ pushUndefined(cfw);
+ cfw.add(ByteCode.ARETURN);
+
+
+ // this method uses as many locals as there are arguments (hence 6)
+ cfw.stopMethod((short)6);
+ }
+
+ private void generateCallMethod(ClassFileWriter cfw)
+ {
+ cfw.startMethod("call",
+ "(Lorg/mozilla/javascript/Context;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "[Ljava/lang/Object;)Ljava/lang/Object;",
+ (short)(ClassFileWriter.ACC_PUBLIC
+ | ClassFileWriter.ACC_FINAL));
+
+ // Generate code for:
+ // if (!ScriptRuntime.hasTopCall(cx)) {
+ // return ScriptRuntime.doTopCall(this, cx, scope, thisObj, args);
+ // }
+
+ int nonTopCallLabel = cfw.acquireLabel();
+ cfw.addALoad(1); //cx
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "hasTopCall",
+ "(Lorg/mozilla/javascript/Context;"
+ +")Z");
+ cfw.add(ByteCode.IFNE, nonTopCallLabel);
+ cfw.addALoad(0);
+ cfw.addALoad(1);
+ cfw.addALoad(2);
+ cfw.addALoad(3);
+ cfw.addALoad(4);
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "doTopCall",
+ "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Ljava/lang/Object;");
+ cfw.add(ByteCode.ARETURN);
+ cfw.markLabel(nonTopCallLabel);
+
+ // Now generate switch to call the real methods
+ cfw.addALoad(0);
+ cfw.addALoad(1);
+ cfw.addALoad(2);
+ cfw.addALoad(3);
+ cfw.addALoad(4);
+
+ int end = scriptOrFnNodes.length;
+ boolean generateSwitch = (2 <= end);
+
+ int switchStart = 0;
+ int switchStackTop = 0;
+ if (generateSwitch) {
+ cfw.addLoadThis();
+ cfw.add(ByteCode.GETFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
+ // do switch from (1, end - 1) mapping 0 to
+ // the default case
+ switchStart = cfw.addTableSwitch(1, end - 1);
+ }
+
+ for (int i = 0; i != end; ++i) {
+ ScriptOrFnNode n = scriptOrFnNodes[i];
+ if (generateSwitch) {
+ if (i == 0) {
+ cfw.markTableSwitchDefault(switchStart);
+ switchStackTop = cfw.getStackTop();
+ } else {
+ cfw.markTableSwitchCase(switchStart, i - 1,
+ switchStackTop);
+ }
+ }
+ if (n.getType() == Token.FUNCTION) {
+ OptFunctionNode ofn = OptFunctionNode.get(n);
+ if (ofn.isTargetOfDirectCall()) {
+ int pcount = ofn.fnode.getParamCount();
+ if (pcount != 0) {
+ // loop invariant:
+ // stack top == arguments array from addALoad4()
+ for (int p = 0; p != pcount; ++p) {
+ cfw.add(ByteCode.ARRAYLENGTH);
+ cfw.addPush(p);
+ int undefArg = cfw.acquireLabel();
+ int beyond = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ICMPLE, undefArg);
+ // get array[p]
+ cfw.addALoad(4);
+ cfw.addPush(p);
+ cfw.add(ByteCode.AALOAD);
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(undefArg);
+ pushUndefined(cfw);
+ cfw.markLabel(beyond);
+ // Only one push
+ cfw.adjustStackTop(-1);
+ cfw.addPush(0.0);
+ // restore invariant
+ cfw.addALoad(4);
+ }
+ }
+ }
+ }
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ mainClassName,
+ getBodyMethodName(n),
+ getBodyMethodSignature(n));
+ cfw.add(ByteCode.ARETURN);
+ }
+ cfw.stopMethod((short)5);
+ // 5: this, cx, scope, js this, args[]
+ }
+
+ private void generateMain(ClassFileWriter cfw)
+ {
+ cfw.startMethod("main", "([Ljava/lang/String;)V",
+ (short)(ClassFileWriter.ACC_PUBLIC
+ | ClassFileWriter.ACC_STATIC));
+
+ // load new ScriptImpl()
+ cfw.add(ByteCode.NEW, cfw.getClassName());
+ cfw.add(ByteCode.DUP);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, cfw.getClassName(),
+ "<init>", "()V");
+ // load 'args'
+ cfw.add(ByteCode.ALOAD_0);
+ // Call mainMethodClass.main(Script script, String[] args)
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ mainMethodClass,
+ "main",
+ "(Lorg/mozilla/javascript/Script;[Ljava/lang/String;)V");
+ cfw.add(ByteCode.RETURN);
+ // 1 = String[] args
+ cfw.stopMethod((short)1);
+ }
+
+ private void generateExecute(ClassFileWriter cfw)
+ {
+ cfw.startMethod("exec",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;",
+ (short)(ClassFileWriter.ACC_PUBLIC
+ | ClassFileWriter.ACC_FINAL));
+
+ final int CONTEXT_ARG = 1;
+ final int SCOPE_ARG = 2;
+
+ cfw.addLoadThis();
+ cfw.addALoad(CONTEXT_ARG);
+ cfw.addALoad(SCOPE_ARG);
+ cfw.add(ByteCode.DUP);
+ cfw.add(ByteCode.ACONST_NULL);
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
+ cfw.getClassName(),
+ "call",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Ljava/lang/Object;");
+
+ cfw.add(ByteCode.ARETURN);
+ // 3 = this + context + scope
+ cfw.stopMethod((short)3);
+ }
+
+ private void generateScriptCtor(ClassFileWriter cfw)
+ {
+ cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
+
+ cfw.addLoadThis();
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, SUPER_CLASS_NAME,
+ "<init>", "()V");
+ // set id to 0
+ cfw.addLoadThis();
+ cfw.addPush(0);
+ cfw.add(ByteCode.PUTFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
+
+ cfw.add(ByteCode.RETURN);
+ // 1 parameter = this
+ cfw.stopMethod((short)1);
+ }
+
+ private void generateFunctionConstructor(ClassFileWriter cfw)
+ {
+ final int SCOPE_ARG = 1;
+ final int CONTEXT_ARG = 2;
+ final int ID_ARG = 3;
+
+ cfw.startMethod("<init>", FUNCTION_CONSTRUCTOR_SIGNATURE,
+ ClassFileWriter.ACC_PUBLIC);
+ cfw.addALoad(0);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, SUPER_CLASS_NAME,
+ "<init>", "()V");
+
+ cfw.addLoadThis();
+ cfw.addILoad(ID_ARG);
+ cfw.add(ByteCode.PUTFIELD, cfw.getClassName(), ID_FIELD_NAME, "I");
+
+ cfw.addLoadThis();
+ cfw.addALoad(CONTEXT_ARG);
+ cfw.addALoad(SCOPE_ARG);
+
+ int start = (scriptOrFnNodes[0].getType() == Token.SCRIPT) ? 1 : 0;
+ int end = scriptOrFnNodes.length;
+ if (start == end) throw badTree();
+ boolean generateSwitch = (2 <= end - start);
+
+ int switchStart = 0;
+ int switchStackTop = 0;
+ if (generateSwitch) {
+ cfw.addILoad(ID_ARG);
+ // do switch from (start + 1, end - 1) mapping start to
+ // the default case
+ switchStart = cfw.addTableSwitch(start + 1, end - 1);
+ }
+
+ for (int i = start; i != end; ++i) {
+ if (generateSwitch) {
+ if (i == start) {
+ cfw.markTableSwitchDefault(switchStart);
+ switchStackTop = cfw.getStackTop();
+ } else {
+ cfw.markTableSwitchCase(switchStart, i - 1 - start,
+ switchStackTop);
+ }
+ }
+ OptFunctionNode ofn = OptFunctionNode.get(scriptOrFnNodes[i]);
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
+ mainClassName,
+ getFunctionInitMethodName(ofn),
+ FUNCTION_INIT_SIGNATURE);
+ cfw.add(ByteCode.RETURN);
+ }
+
+ // 4 = this + scope + context + id
+ cfw.stopMethod((short)4);
+ }
+
+ private void generateFunctionInit(ClassFileWriter cfw,
+ OptFunctionNode ofn)
+ {
+ final int CONTEXT_ARG = 1;
+ final int SCOPE_ARG = 2;
+ cfw.startMethod(getFunctionInitMethodName(ofn),
+ FUNCTION_INIT_SIGNATURE,
+ (short)(ClassFileWriter.ACC_PRIVATE
+ | ClassFileWriter.ACC_FINAL));
+
+ // Call NativeFunction.initScriptFunction
+ cfw.addLoadThis();
+ cfw.addALoad(CONTEXT_ARG);
+ cfw.addALoad(SCOPE_ARG);
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
+ "org/mozilla/javascript/NativeFunction",
+ "initScriptFunction",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")V");
+
+ // precompile all regexp literals
+ int regexpCount = ofn.fnode.getRegexpCount();
+ if (regexpCount != 0) {
+ cfw.addLoadThis();
+ pushRegExpArray(cfw, ofn.fnode, CONTEXT_ARG, SCOPE_ARG);
+ cfw.add(ByteCode.PUTFIELD, mainClassName,
+ REGEXP_ARRAY_FIELD_NAME, REGEXP_ARRAY_FIELD_TYPE);
+ }
+
+ cfw.add(ByteCode.RETURN);
+ // 3 = (scriptThis/functionRef) + scope + context
+ cfw.stopMethod((short)3);
+ }
+
+ private void generateNativeFunctionOverrides(ClassFileWriter cfw,
+ String encodedSource)
+ {
+ // Override NativeFunction.getLanguageVersion() with
+ // public int getLanguageVersion() { return <version-constant>; }
+
+ cfw.startMethod("getLanguageVersion", "()I",
+ ClassFileWriter.ACC_PUBLIC);
+
+ cfw.addPush(compilerEnv.getLanguageVersion());
+ cfw.add(ByteCode.IRETURN);
+
+ // 1: this and no argument or locals
+ cfw.stopMethod((short)1);
+
+ // The rest of NativeFunction overrides require specific code for each
+ // script/function id
+
+ final int Do_getFunctionName = 0;
+ final int Do_getParamCount = 1;
+ final int Do_getParamAndVarCount = 2;
+ final int Do_getParamOrVarName = 3;
+ final int Do_getEncodedSource = 4;
+ final int Do_getParamOrVarConst = 5;
+ final int SWITCH_COUNT = 6;
+
+ for (int methodIndex = 0; methodIndex != SWITCH_COUNT; ++methodIndex) {
+ if (methodIndex == Do_getEncodedSource && encodedSource == null) {
+ continue;
+ }
+
+ // Generate:
+ // prologue;
+ // switch over function id to implement function-specific action
+ // epilogue
+
+ short methodLocals;
+ switch (methodIndex) {
+ case Do_getFunctionName:
+ methodLocals = 1; // Only this
+ cfw.startMethod("getFunctionName", "()Ljava/lang/String;",
+ ClassFileWriter.ACC_PUBLIC);
+ break;
+ case Do_getParamCount:
+ methodLocals = 1; // Only this
+ cfw.startMethod("getParamCount", "()I",
+ ClassFileWriter.ACC_PUBLIC);
+ break;
+ case Do_getParamAndVarCount:
+ methodLocals = 1; // Only this
+ cfw.startMethod("getParamAndVarCount", "()I",
+ ClassFileWriter.ACC_PUBLIC);
+ break;
+ case Do_getParamOrVarName:
+ methodLocals = 1 + 1; // this + paramOrVarIndex
+ cfw.startMethod("getParamOrVarName", "(I)Ljava/lang/String;",
+ ClassFileWriter.ACC_PUBLIC);
+ break;
+ case Do_getParamOrVarConst:
+ methodLocals = 1 + 1 + 1; // this + paramOrVarName
+ cfw.startMethod("getParamOrVarConst", "(I)Z",
+ ClassFileWriter.ACC_PUBLIC);
+ break;
+ case Do_getEncodedSource:
+ methodLocals = 1; // Only this
+ cfw.startMethod("getEncodedSource", "()Ljava/lang/String;",
+ ClassFileWriter.ACC_PUBLIC);
+ cfw.addPush(encodedSource);
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+
+ int count = scriptOrFnNodes.length;
+
+ int switchStart = 0;
+ int switchStackTop = 0;
+ if (count > 1) {
+ // Generate switch but only if there is more then one
+ // script/function
+ cfw.addLoadThis();
+ cfw.add(ByteCode.GETFIELD, cfw.getClassName(),
+ ID_FIELD_NAME, "I");
+
+ // do switch from 1 .. count - 1 mapping 0 to the default case
+ switchStart = cfw.addTableSwitch(1, count - 1);
+ }
+
+ for (int i = 0; i != count; ++i) {
+ ScriptOrFnNode n = scriptOrFnNodes[i];
+ if (i == 0) {
+ if (count > 1) {
+ cfw.markTableSwitchDefault(switchStart);
+ switchStackTop = cfw.getStackTop();
+ }
+ } else {
+ cfw.markTableSwitchCase(switchStart, i - 1,
+ switchStackTop);
+ }
+
+ // Impelemnet method-specific switch code
+ switch (methodIndex) {
+ case Do_getFunctionName:
+ // Push function name
+ if (n.getType() == Token.SCRIPT) {
+ cfw.addPush("");
+ } else {
+ String name = ((FunctionNode)n).getFunctionName();
+ cfw.addPush(name);
+ }
+ cfw.add(ByteCode.ARETURN);
+ break;
+
+ case Do_getParamCount:
+ // Push number of defined parameters
+ cfw.addPush(n.getParamCount());
+ cfw.add(ByteCode.IRETURN);
+ break;
+
+ case Do_getParamAndVarCount:
+ // Push number of defined parameters and declared variables
+ cfw.addPush(n.getParamAndVarCount());
+ cfw.add(ByteCode.IRETURN);
+ break;
+
+ case Do_getParamOrVarName:
+ // Push name of parameter using another switch
+ // over paramAndVarCount
+ int paramAndVarCount = n.getParamAndVarCount();
+ if (paramAndVarCount == 0) {
+ // The runtime should never call the method in this
+ // case but to make bytecode verifier happy return null
+ // as throwing execption takes more code
+ cfw.add(ByteCode.ACONST_NULL);
+ cfw.add(ByteCode.ARETURN);
+ } else if (paramAndVarCount == 1) {
+ // As above do not check for valid index but always
+ // return the name of the first param
+ cfw.addPush(n.getParamOrVarName(0));
+ cfw.add(ByteCode.ARETURN);
+ } else {
+ // Do switch over getParamOrVarName
+ cfw.addILoad(1); // param or var index
+ // do switch from 1 .. paramAndVarCount - 1 mapping 0
+ // to the default case
+ int paramSwitchStart = cfw.addTableSwitch(
+ 1, paramAndVarCount - 1);
+ for (int j = 0; j != paramAndVarCount; ++j) {
+ if (cfw.getStackTop() != 0) Kit.codeBug();
+ String s = n.getParamOrVarName(j);
+ if (j == 0) {
+ cfw.markTableSwitchDefault(paramSwitchStart);
+ } else {
+ cfw.markTableSwitchCase(paramSwitchStart, j - 1,
+ 0);
+ }
+ cfw.addPush(s);
+ cfw.add(ByteCode.ARETURN);
+ }
+ }
+ break;
+
+ case Do_getParamOrVarConst:
+ // Push name of parameter using another switch
+ // over paramAndVarCount
+ paramAndVarCount = n.getParamAndVarCount();
+ boolean [] constness = n.getParamAndVarConst();
+ if (paramAndVarCount == 0) {
+ // The runtime should never call the method in this
+ // case but to make bytecode verifier happy return null
+ // as throwing execption takes more code
+ cfw.add(ByteCode.ICONST_0);
+ cfw.add(ByteCode.IRETURN);
+ } else if (paramAndVarCount == 1) {
+ // As above do not check for valid index but always
+ // return the name of the first param
+ cfw.addPush(constness[0]);
+ cfw.add(ByteCode.IRETURN);
+ } else {
+ // Do switch over getParamOrVarName
+ cfw.addILoad(1); // param or var index
+ // do switch from 1 .. paramAndVarCount - 1 mapping 0
+ // to the default case
+ int paramSwitchStart = cfw.addTableSwitch(
+ 1, paramAndVarCount - 1);
+ for (int j = 0; j != paramAndVarCount; ++j) {
+ if (cfw.getStackTop() != 0) Kit.codeBug();
+ if (j == 0) {
+ cfw.markTableSwitchDefault(paramSwitchStart);
+ } else {
+ cfw.markTableSwitchCase(paramSwitchStart, j - 1,
+ 0);
+ }
+ cfw.addPush(constness[j]);
+ cfw.add(ByteCode.IRETURN);
+ }
+ }
+ break;
+
+ case Do_getEncodedSource:
+ // Push number encoded source start and end
+ // to prepare for encodedSource.substring(start, end)
+ cfw.addPush(n.getEncodedSourceStart());
+ cfw.addPush(n.getEncodedSourceEnd());
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL,
+ "java/lang/String",
+ "substring",
+ "(II)Ljava/lang/String;");
+ cfw.add(ByteCode.ARETURN);
+ break;
+
+ default:
+ throw Kit.codeBug();
+ }
+ }
+
+ cfw.stopMethod(methodLocals);
+ }
+ }
+
+ private void emitRegExpInit(ClassFileWriter cfw)
+ {
+ // precompile all regexp literals
+
+ int totalRegCount = 0;
+ for (int i = 0; i != scriptOrFnNodes.length; ++i) {
+ totalRegCount += scriptOrFnNodes[i].getRegexpCount();
+ }
+ if (totalRegCount == 0) {
+ return;
+ }
+
+ cfw.startMethod(REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE,
+ (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_PRIVATE
+ | ClassFileWriter.ACC_SYNCHRONIZED));
+ cfw.addField("_reInitDone", "Z",
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+ cfw.add(ByteCode.GETSTATIC, mainClassName, "_reInitDone", "Z");
+ int doInit = cfw.acquireLabel();
+ cfw.add(ByteCode.IFEQ, doInit);
+ cfw.add(ByteCode.RETURN);
+ cfw.markLabel(doInit);
+
+ for (int i = 0; i != scriptOrFnNodes.length; ++i) {
+ ScriptOrFnNode n = scriptOrFnNodes[i];
+ int regCount = n.getRegexpCount();
+ for (int j = 0; j != regCount; ++j) {
+ String reFieldName = getCompiledRegexpName(n, j);
+ String reFieldType = "Ljava/lang/Object;";
+ String reString = n.getRegexpString(j);
+ String reFlags = n.getRegexpFlags(j);
+ cfw.addField(reFieldName, reFieldType,
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+ cfw.addALoad(0); // proxy
+ cfw.addALoad(1); // context
+ cfw.addPush(reString);
+ if (reFlags == null) {
+ cfw.add(ByteCode.ACONST_NULL);
+ } else {
+ cfw.addPush(reFlags);
+ }
+ /*APPJET*/cfw.addLineNumberEntry((short)n.getRegexpLineno(j));
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/RegExpProxy",
+ "compileRegExp",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Ljava/lang/String;Ljava/lang/String;"
+ +")Ljava/lang/Object;");
+ cfw.add(ByteCode.PUTSTATIC, mainClassName,
+ reFieldName, reFieldType);
+ }
+ }
+
+ cfw.addPush(1);
+ cfw.add(ByteCode.PUTSTATIC, mainClassName, "_reInitDone", "Z");
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)2);
+ }
+
+ private void emitConstantDudeInitializers(ClassFileWriter cfw)
+ {
+ int N = itsConstantListSize;
+ if (N == 0)
+ return;
+
+ cfw.startMethod("<clinit>", "()V",
+ (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_FINAL));
+
+ double[] array = itsConstantList;
+ for (int i = 0; i != N; ++i) {
+ double num = array[i];
+ String constantName = "_k" + i;
+ String constantType = getStaticConstantWrapperType(num);
+ cfw.addField(constantName, constantType,
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+ int inum = (int)num;
+ if (inum == num) {
+ cfw.add(ByteCode.NEW, "java/lang/Integer");
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(inum);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Integer",
+ "<init>", "(I)V");
+ } else {
+ cfw.addPush(num);
+ addDoubleWrap(cfw);
+ }
+ cfw.add(ByteCode.PUTSTATIC, mainClassName,
+ constantName, constantType);
+ }
+
+ cfw.add(ByteCode.RETURN);
+ cfw.stopMethod((short)0);
+ }
+
+ void pushRegExpArray(ClassFileWriter cfw, ScriptOrFnNode n,
+ int contextArg, int scopeArg)
+ {
+ int regexpCount = n.getRegexpCount();
+ if (regexpCount == 0) throw badTree();
+
+ cfw.addPush(regexpCount);
+ cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
+
+ cfw.addALoad(contextArg);
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "checkRegExpProxy",
+ "(Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/RegExpProxy;");
+ // Stack: proxy, array
+ cfw.add(ByteCode.DUP);
+ cfw.addALoad(contextArg);
+ cfw.addInvoke(ByteCode.INVOKESTATIC, mainClassName,
+ REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE);
+ for (int i = 0; i != regexpCount; ++i) {
+ // Stack: proxy, array
+ cfw.add(ByteCode.DUP2);
+ cfw.addALoad(contextArg);
+ cfw.addALoad(scopeArg);
+ cfw.add(ByteCode.GETSTATIC, mainClassName,
+ getCompiledRegexpName(n, i), "Ljava/lang/Object;");
+ // Stack: compiledRegExp, scope, cx, proxy, array, proxy, array
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/RegExpProxy",
+ "wrapRegExp",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ // Stack: wrappedRegExp, array, proxy, array
+ cfw.addPush(i);
+ cfw.add(ByteCode.SWAP);
+ cfw.add(ByteCode.AASTORE);
+ // Stack: proxy, array
+ }
+ // remove proxy
+ cfw.add(ByteCode.POP);
+ }
+
+ void pushNumberAsObject(ClassFileWriter cfw, double num)
+ {
+ if (num == 0.0) {
+ if (1 / num > 0) {
+ // +0.0
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/optimizer/OptRuntime",
+ "zeroObj", "Ljava/lang/Double;");
+ } else {
+ cfw.addPush(num);
+ addDoubleWrap(cfw);
+ }
+
+ } else if (num == 1.0) {
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/optimizer/OptRuntime",
+ "oneObj", "Ljava/lang/Double;");
+ return;
+
+ } else if (num == -1.0) {
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/optimizer/OptRuntime",
+ "minusOneObj", "Ljava/lang/Double;");
+
+ } else if (num != num) {
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "NaNobj", "Ljava/lang/Double;");
+
+ } else if (itsConstantListSize >= 2000) {
+ // There appears to be a limit in the JVM on either the number
+ // of static fields in a class or the size of the class
+ // initializer. Either way, we can't have any more than 2000
+ // statically init'd constants.
+ cfw.addPush(num);
+ addDoubleWrap(cfw);
+
+ } else {
+ int N = itsConstantListSize;
+ int index = 0;
+ if (N == 0) {
+ itsConstantList = new double[64];
+ } else {
+ double[] array = itsConstantList;
+ while (index != N && array[index] != num) {
+ ++index;
+ }
+ if (N == array.length) {
+ array = new double[N * 2];
+ System.arraycopy(itsConstantList, 0, array, 0, N);
+ itsConstantList = array;
+ }
+ }
+ if (index == N) {
+ itsConstantList[N] = num;
+ itsConstantListSize = N + 1;
+ }
+ String constantName = "_k" + index;
+ String constantType = getStaticConstantWrapperType(num);
+ cfw.add(ByteCode.GETSTATIC, mainClassName,
+ constantName, constantType);
+ }
+ }
+
+ private static void addDoubleWrap(ClassFileWriter cfw)
+ {
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/optimizer/OptRuntime",
+ "wrapDouble", "(D)Ljava/lang/Double;");
+ }
+
+ private static String getStaticConstantWrapperType(double num)
+ {
+ int inum = (int)num;
+ if (inum == num) {
+ return "Ljava/lang/Integer;";
+ } else {
+ return "Ljava/lang/Double;";
+ }
+ }
+ static void pushUndefined(ClassFileWriter cfw)
+ {
+ cfw.add(ByteCode.GETSTATIC, "org/mozilla/javascript/Undefined",
+ "instance", "Ljava/lang/Object;");
+ }
+
+ int getIndex(ScriptOrFnNode n)
+ {
+ return scriptOrFnIndexes.getExisting(n);
+ }
+
+ static String getDirectTargetFieldName(int i)
+ {
+ return "_dt" + i;
+ }
+
+ String getDirectCtorName(ScriptOrFnNode n)
+ {
+ return "_n"+getIndex(n);
+ }
+
+ String getBodyMethodName(ScriptOrFnNode n)
+ {
+ return "_c"+getIndex(n);
+ }
+
+ String getBodyMethodSignature(ScriptOrFnNode n)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ sb.append(mainClassSignature);
+ sb.append("Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;");
+ if (n.getType() == Token.FUNCTION) {
+ OptFunctionNode ofn = OptFunctionNode.get(n);
+ if (ofn.isTargetOfDirectCall()) {
+ int pCount = ofn.fnode.getParamCount();
+ for (int i = 0; i != pCount; i++) {
+ sb.append("Ljava/lang/Object;D");
+ }
+ }
+ }
+ sb.append("[Ljava/lang/Object;)Ljava/lang/Object;");
+ return sb.toString();
+ }
+
+ String getFunctionInitMethodName(OptFunctionNode ofn)
+ {
+ return "_i"+getIndex(ofn.fnode);
+ }
+
+ String getCompiledRegexpName(ScriptOrFnNode n, int regexpIndex)
+ {
+ return "_re"+getIndex(n)+"_"+regexpIndex;
+ }
+
+ static RuntimeException badTree()
+ {
+ throw new RuntimeException("Bad tree in codegen");
+ }
+
+ void setMainMethodClass(String className)
+ {
+ mainMethodClass = className;
+ }
+
+ static final String DEFAULT_MAIN_METHOD_CLASS
+ = "org.mozilla.javascript.optimizer.OptRuntime";
+
+ private static final String SUPER_CLASS_NAME
+ = "org.mozilla.javascript.NativeFunction";
+
+ static final String DIRECT_CALL_PARENT_FIELD = "_dcp";
+ private static final String ID_FIELD_NAME = "_id";
+
+ private static final String REGEXP_INIT_METHOD_NAME = "_reInit";
+ private static final String REGEXP_INIT_METHOD_SIGNATURE
+ = "(Lorg/mozilla/javascript/RegExpProxy;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")V";
+ static final String REGEXP_ARRAY_FIELD_NAME = "_re";
+ static final String REGEXP_ARRAY_FIELD_TYPE = "[Ljava/lang/Object;";
+
+ static final String FUNCTION_INIT_SIGNATURE
+ = "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")V";
+
+ static final String FUNCTION_CONSTRUCTOR_SIGNATURE
+ = "(Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Context;I)V";
+
+ private static final Object globalLock = new Object();
+ private static int globalSerialClassCounter;
+
+ private CompilerEnvirons compilerEnv;
+
+ private ObjArray directCallTargets;
+ ScriptOrFnNode[] scriptOrFnNodes;
+ private ObjToIntMap scriptOrFnIndexes;
+
+ private String mainMethodClass = DEFAULT_MAIN_METHOD_CLASS;
+
+ String mainClassName;
+ String mainClassSignature;
+
+ private double[] itsConstantList;
+ private int itsConstantListSize;
+}
+
+
+class BodyCodegen
+{
+ void generateBodyCode()
+ {
+ isGenerator = Codegen.isGenerator(scriptOrFn);
+
+ // generate the body of the current function or script object
+ initBodyGeneration();
+
+ if (isGenerator) {
+
+ // All functions in the generated bytecode have a unique name. Every
+ // generator has a unique prefix followed by _gen
+ String type = "(" +
+ codegen.mainClassSignature +
+ "Lorg/mozilla/javascript/Context;" +
+ "Lorg/mozilla/javascript/Scriptable;" +
+ "Ljava/lang/Object;" +
+ "Ljava/lang/Object;I)Ljava/lang/Object;";
+ cfw.startMethod(codegen.getBodyMethodName(scriptOrFn) + "_gen",
+ type,
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+ } else {
+ cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),
+ codegen.getBodyMethodSignature(scriptOrFn),
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+ }
+
+ generatePrologue();
+ Node treeTop;
+ if (fnCurrent != null) {
+ treeTop = scriptOrFn.getLastChild();
+ } else {
+ treeTop = scriptOrFn;
+ }
+ generateStatement(treeTop);
+ generateEpilogue();
+
+ cfw.stopMethod((short)(localsMax + 1));
+
+ if (isGenerator) {
+ // generate the user visible method which when invoked will
+ // return a generator object
+ generateGenerator();
+ }
+ }
+
+ // This creates a the user-facing function that returns a NativeGenerator
+ // object.
+ private void generateGenerator()
+ {
+ cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),
+ codegen.getBodyMethodSignature(scriptOrFn),
+ (short)(ClassFileWriter.ACC_STATIC
+ | ClassFileWriter.ACC_PRIVATE));
+
+ initBodyGeneration();
+ argsLocal = firstFreeLocal++;
+ localsMax = firstFreeLocal;
+
+ // get top level scope
+ if (fnCurrent != null && !inDirectCallFunction
+ && (!compilerEnv.isUseDynamicScope()
+ || fnCurrent.fnode.getIgnoreDynamicScope()))
+ {
+ // Unless we're either in a direct call or using dynamic scope,
+ // use the enclosing scope of the function as our variable object.
+ cfw.addALoad(funObjLocal);
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/Scriptable",
+ "getParentScope",
+ "()Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ }
+
+ // generators are forced to have an activation record
+ cfw.addALoad(funObjLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(argsLocal);
+ addScriptRuntimeInvoke("createFunctionActivation",
+ "(Lorg/mozilla/javascript/NativeFunction;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+
+ // create a function object
+ cfw.add(ByteCode.NEW, codegen.mainClassName);
+ // Call function constructor
+ cfw.add(ByteCode.DUP);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(contextLocal); // load 'cx'
+ cfw.addPush(scriptOrFnIndex);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,
+ "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);
+
+ // Init mainScript field
+ cfw.add(ByteCode.DUP);
+ if (isTopLevel) Kit.codeBug(); // Only functions can be generators
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD,
+ codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+ cfw.add(ByteCode.PUTFIELD,
+ codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+
+ generateNestedFunctionInits();
+
+ // create the NativeGenerator object that we return
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(thisObjLocal);
+ cfw.addLoadConstant(maxLocals);
+ cfw.addLoadConstant(maxStack);
+ addOptRuntimeInvoke("createNativeGenerator",
+ "(Lorg/mozilla/javascript/NativeFunction;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;II"
+ +")Lorg/mozilla/javascript/Scriptable;");
+
+ cfw.add(ByteCode.ARETURN);
+ cfw.stopMethod((short)(localsMax + 1));
+ }
+
+ private void generateNestedFunctionInits()
+ {
+ int functionCount = scriptOrFn.getFunctionCount();
+ for (int i = 0; i != functionCount; i++) {
+ OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, i);
+ if (ofn.fnode.getFunctionType()
+ == FunctionNode.FUNCTION_STATEMENT)
+ {
+ visitFunction(ofn, FunctionNode.FUNCTION_STATEMENT);
+ }
+ }
+ }
+
+ private void initBodyGeneration()
+ {
+ isTopLevel = (scriptOrFn == codegen.scriptOrFnNodes[0]);
+
+ varRegisters = null;
+ if (scriptOrFn.getType() == Token.FUNCTION) {
+ fnCurrent = OptFunctionNode.get(scriptOrFn);
+ hasVarsInRegs = !fnCurrent.fnode.requiresActivation();
+ if (hasVarsInRegs) {
+ int n = fnCurrent.fnode.getParamAndVarCount();
+ if (n != 0) {
+ varRegisters = new short[n];
+ }
+ }
+ inDirectCallFunction = fnCurrent.isTargetOfDirectCall();
+ if (inDirectCallFunction && !hasVarsInRegs) Codegen.badTree();
+ } else {
+ fnCurrent = null;
+ hasVarsInRegs = false;
+ inDirectCallFunction = false;
+ }
+
+ locals = new int[MAX_LOCALS];
+
+ funObjLocal = 0;
+ contextLocal = 1;
+ variableObjectLocal = 2;
+ thisObjLocal = 3;
+ localsMax = (short) 4; // number of parms + "this"
+ firstFreeLocal = 4;
+
+ popvLocal = -1;
+ argsLocal = -1;
+ itsZeroArgArray = -1;
+ itsOneArgArray = -1;
+ scriptRegexpLocal = -1;
+ epilogueLabel = -1;
+ enterAreaStartLabel = -1;
+ generatorStateLocal = -1;
+ }
+
+ /**
+ * Generate the prologue for a function or script.
+ */
+ private void generatePrologue()
+ {
+ if (inDirectCallFunction) {
+ int directParameterCount = scriptOrFn.getParamCount();
+ // 0 is reserved for function Object 'this'
+ // 1 is reserved for context
+ // 2 is reserved for parentScope
+ // 3 is reserved for script 'this'
+ if (firstFreeLocal != 4) Kit.codeBug();
+ for (int i = 0; i != directParameterCount; ++i) {
+ varRegisters[i] = firstFreeLocal;
+ // 3 is 1 for Object parm and 2 for double parm
+ firstFreeLocal += 3;
+ }
+ if (!fnCurrent.getParameterNumberContext()) {
+ // make sure that all parameters are objects
+ itsForcedObjectParameters = true;
+ for (int i = 0; i != directParameterCount; ++i) {
+ short reg = varRegisters[i];
+ cfw.addALoad(reg);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ int isObjectLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPNE, isObjectLabel);
+ cfw.addDLoad(reg + 1);
+ addDoubleWrap();
+ cfw.addAStore(reg);
+ cfw.markLabel(isObjectLabel);
+ }
+ }
+ }
+
+ if (fnCurrent != null && !inDirectCallFunction
+ && (!compilerEnv.isUseDynamicScope()
+ || fnCurrent.fnode.getIgnoreDynamicScope()))
+ {
+ // Unless we're either in a direct call or using dynamic scope,
+ // use the enclosing scope of the function as our variable object.
+ cfw.addALoad(funObjLocal);
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/Scriptable",
+ "getParentScope",
+ "()Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ }
+
+ // reserve 'args[]'
+ argsLocal = firstFreeLocal++;
+ localsMax = firstFreeLocal;
+
+ // Generate Generator specific prelude
+ if (isGenerator) {
+
+ // reserve 'args[]'
+ operationLocal = firstFreeLocal++;
+ localsMax = firstFreeLocal;
+
+ // Local 3 is a reference to a GeneratorState object. The rest
+ // of codegen expects local 3 to be a reference to the thisObj.
+ // So move the value in local 3 to generatorStateLocal, and load
+ // the saved thisObj from the GeneratorState object.
+ cfw.addALoad(thisObjLocal);
+ generatorStateLocal = firstFreeLocal++;
+ localsMax = firstFreeLocal;
+ cfw.add(ByteCode.CHECKCAST, OptRuntime.GeneratorState.CLASS_NAME);
+ cfw.add(ByteCode.DUP);
+ cfw.addAStore(generatorStateLocal);
+ cfw.add(ByteCode.GETFIELD,
+ OptRuntime.GeneratorState.CLASS_NAME,
+ OptRuntime.GeneratorState.thisObj_NAME,
+ OptRuntime.GeneratorState.thisObj_TYPE);
+ cfw.addAStore(thisObjLocal);
+
+ if (epilogueLabel == -1) {
+ epilogueLabel = cfw.acquireLabel();
+ }
+
+ ArrayList targets = ((FunctionNode)scriptOrFn).getResumptionPoints();
+ if (targets != null) {
+ // get resumption point
+ generateGetGeneratorResumptionPoint();
+
+ // generate dispatch table
+ generatorSwitch = cfw.addTableSwitch(0,
+ targets.size() + GENERATOR_START);
+ generateCheckForThrowOrClose(-1, false, GENERATOR_START);
+ }
+ }
+
+ if (fnCurrent == null) {
+ // See comments in case Token.REGEXP
+ if (scriptOrFn.getRegexpCount() != 0) {
+ scriptRegexpLocal = getNewWordLocal();
+ codegen.pushRegExpArray(cfw, scriptOrFn, contextLocal,
+ variableObjectLocal);
+ cfw.addAStore(scriptRegexpLocal);
+ }
+ }
+
+ if (compilerEnv.isGenerateObserverCount())
+ saveCurrentCodeOffset();
+
+ if (hasVarsInRegs) {
+ // No need to create activation. Pad arguments if need be.
+ int parmCount = scriptOrFn.getParamCount();
+ if (parmCount > 0 && !inDirectCallFunction) {
+ // Set up args array
+ // check length of arguments, pad if need be
+ cfw.addALoad(argsLocal);
+ cfw.add(ByteCode.ARRAYLENGTH);
+ cfw.addPush(parmCount);
+ int label = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ICMPGE, label);
+ cfw.addALoad(argsLocal);
+ cfw.addPush(parmCount);
+ addScriptRuntimeInvoke("padArguments",
+ "([Ljava/lang/Object;I"
+ +")[Ljava/lang/Object;");
+ cfw.addAStore(argsLocal);
+ cfw.markLabel(label);
+ }
+
+ int paramCount = fnCurrent.fnode.getParamCount();
+ int varCount = fnCurrent.fnode.getParamAndVarCount();
+ boolean [] constDeclarations = fnCurrent.fnode.getParamAndVarConst();
+
+ // REMIND - only need to initialize the vars that don't get a value
+ // before the next call and are used in the function
+ short firstUndefVar = -1;
+ for (int i = 0; i != varCount; ++i) {
+ short reg = -1;
+ if (i < paramCount) {
+ if (!inDirectCallFunction) {
+ reg = getNewWordLocal();
+ cfw.addALoad(argsLocal);
+ cfw.addPush(i);
+ cfw.add(ByteCode.AALOAD);
+ cfw.addAStore(reg);
+ }
+ } else if (fnCurrent.isNumberVar(i)) {
+ reg = getNewWordPairLocal(constDeclarations[i]);
+ cfw.addPush(0.0);
+ cfw.addDStore(reg);
+ } else {
+ reg = getNewWordLocal(constDeclarations[i]);
+ if (firstUndefVar == -1) {
+ Codegen.pushUndefined(cfw);
+ firstUndefVar = reg;
+ } else {
+ cfw.addALoad(firstUndefVar);
+ }
+ cfw.addAStore(reg);
+ }
+ if (reg >= 0) {
+ if (constDeclarations[i]) {
+ cfw.addPush(0);
+ cfw.addIStore(reg + (fnCurrent.isNumberVar(i) ? 2 : 1));
+ }
+ varRegisters[i] = reg;
+ }
+
+ // Add debug table entry if we're generating debug info
+ if (compilerEnv.isGenerateDebugInfo()) {
+ String name = fnCurrent.fnode.getParamOrVarName(i);
+ String type = fnCurrent.isNumberVar(i)
+ ? "D" : "Ljava/lang/Object;";
+ int startPC = cfw.getCurrentCodeOffset();
+ if (reg < 0) {
+ reg = varRegisters[i];
+ }
+ cfw.addVariableDescriptor(name, type, startPC, reg);
+ }
+ }
+
+ // Skip creating activation object.
+ return;
+ }
+
+ // skip creating activation object for the body of a generator. The
+ // activation record required by a generator has already been created
+ // in generateGenerator().
+ if (isGenerator)
+ return;
+
+
+ String debugVariableName;
+ if (fnCurrent != null) {
+ debugVariableName = "activation";
+ cfw.addALoad(funObjLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(argsLocal);
+ addScriptRuntimeInvoke("createFunctionActivation",
+ "(Lorg/mozilla/javascript/NativeFunction;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke("enterActivationFunction",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")V");
+ } else {
+ debugVariableName = "global";
+ cfw.addALoad(funObjLocal);
+ cfw.addALoad(thisObjLocal);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(0); // false to indicate it is not eval script
+ addScriptRuntimeInvoke("initScript",
+ "(Lorg/mozilla/javascript/NativeFunction;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Z"
+ +")V");
+ }
+
+ enterAreaStartLabel = cfw.acquireLabel();
+ epilogueLabel = cfw.acquireLabel();
+ cfw.markLabel(enterAreaStartLabel);
+
+ generateNestedFunctionInits();
+
+ // default is to generate debug info
+ if (compilerEnv.isGenerateDebugInfo()) {
+ cfw.addVariableDescriptor(debugVariableName,
+ "Lorg/mozilla/javascript/Scriptable;",
+ cfw.getCurrentCodeOffset(), variableObjectLocal);
+ }
+
+ if (fnCurrent == null) {
+ // OPT: use dataflow to prove that this assignment is dead
+ popvLocal = getNewWordLocal();
+ Codegen.pushUndefined(cfw);
+ cfw.addAStore(popvLocal);
+
+ int linenum = scriptOrFn.getEndLineno();
+ if (linenum != -1)
+ cfw.addLineNumberEntry((short)linenum);
+
+ } else {
+ if (fnCurrent.itsContainsCalls0) {
+ itsZeroArgArray = getNewWordLocal();
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "emptyArgs", "[Ljava/lang/Object;");
+ cfw.addAStore(itsZeroArgArray);
+ }
+ if (fnCurrent.itsContainsCalls1) {
+ itsOneArgArray = getNewWordLocal();
+ cfw.addPush(1);
+ cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
+ cfw.addAStore(itsOneArgArray);
+ }
+ }
+ }
+
+ private void generateGetGeneratorResumptionPoint()
+ {
+ cfw.addALoad(generatorStateLocal);
+ cfw.add(ByteCode.GETFIELD,
+ OptRuntime.GeneratorState.CLASS_NAME,
+ OptRuntime.GeneratorState.resumptionPoint_NAME,
+ OptRuntime.GeneratorState.resumptionPoint_TYPE);
+ }
+
+ private void generateSetGeneratorResumptionPoint(int nextState)
+ {
+ cfw.addALoad(generatorStateLocal);
+ cfw.addLoadConstant(nextState);
+ cfw.add(ByteCode.PUTFIELD,
+ OptRuntime.GeneratorState.CLASS_NAME,
+ OptRuntime.GeneratorState.resumptionPoint_NAME,
+ OptRuntime.GeneratorState.resumptionPoint_TYPE);
+ }
+
+ private void generateGetGeneratorStackState()
+ {
+ cfw.addALoad(generatorStateLocal);
+ addOptRuntimeInvoke("getGeneratorStackState",
+ "(Ljava/lang/Object;)[Ljava/lang/Object;");
+ }
+
+ private void generateEpilogue()
+ {
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ if (isGenerator) {
+ // generate locals initialization
+ HashMap liveLocals = ((FunctionNode)scriptOrFn).getLiveLocals();
+ if (liveLocals != null) {
+ ArrayList nodes = ((FunctionNode)scriptOrFn).getResumptionPoints();
+ for (int i = 0; i < nodes.size(); i++) {
+ Node node = (Node) nodes.get(i);
+ int[] live = (int [])liveLocals.get(node);
+ if (live != null) {
+ cfw.markTableSwitchCase(generatorSwitch,
+ getNextGeneratorState(node));
+ generateGetGeneratorLocalsState();
+ for (int j = 0; j < live.length; j++) {
+ cfw.add(ByteCode.DUP);
+ cfw.addLoadConstant(j);
+ cfw.add(ByteCode.AALOAD);
+ cfw.addAStore(live[j]);
+ }
+ cfw.add(ByteCode.POP);
+ cfw.add(ByteCode.GOTO, getTargetLabel(node));
+ }
+ }
+ }
+
+ // generate dispatch tables for finally
+ if (finallys != null) {
+ Enumeration en = finallys.keys();
+ while(en.hasMoreElements()) {
+ Node n = (Node) en.nextElement();
+ if (n.getType() == Token.FINALLY) {
+ FinallyReturnPoint ret =
+ (FinallyReturnPoint)finallys.get(n);
+ // the finally will jump here
+ cfw.markLabel(ret.tableLabel, (short)1);
+
+ // start generating a dispatch table
+ int startSwitch = cfw.addTableSwitch(0,
+ ret.jsrPoints.size() - 1);
+ int c = 0;
+ cfw.markTableSwitchDefault(startSwitch);
+ for (int i = 0; i < ret.jsrPoints.size(); i++) {
+ // generate gotos back to the JSR location
+ cfw.markTableSwitchCase(startSwitch, c);
+ cfw.add(ByteCode.GOTO,
+ ((Integer)ret.jsrPoints.get(i)).intValue());
+ c++;
+ }
+ }
+ }
+ }
+ }
+
+ if (epilogueLabel != -1) {
+ cfw.markLabel(epilogueLabel);
+ }
+
+ if (hasVarsInRegs) {
+ cfw.add(ByteCode.ARETURN);
+ return;
+ } else if (isGenerator) {
+ if (((FunctionNode)scriptOrFn).getResumptionPoints() != null) {
+ cfw.markTableSwitchDefault(generatorSwitch);
+ }
+
+ // change state for re-entry
+ generateSetGeneratorResumptionPoint(GENERATOR_TERMINATE);
+
+ // throw StopIteration
+ cfw.addALoad(variableObjectLocal);
+ addOptRuntimeInvoke("throwStopIteration",
+ "(Ljava/lang/Object;)V");
+
+ Codegen.pushUndefined(cfw);
+ cfw.add(ByteCode.ARETURN);
+
+ } else if (fnCurrent == null) {
+ cfw.addALoad(popvLocal);
+ cfw.add(ByteCode.ARETURN);
+ } else {
+ generateActivationExit();
+ cfw.add(ByteCode.ARETURN);
+
+ // Generate catch block to catch all and rethrow to call exit code
+ // under exception propagation as well.
+
+ int finallyHandler = cfw.acquireLabel();
+ cfw.markHandler(finallyHandler);
+ short exceptionObject = getNewWordLocal();
+ cfw.addAStore(exceptionObject);
+
+ // Duplicate generateActivationExit() in the catch block since it
+ // takes less space then full-featured ByteCode.JSR/ByteCode.RET
+ generateActivationExit();
+
+ cfw.addALoad(exceptionObject);
+ releaseWordLocal(exceptionObject);
+ // rethrow
+ cfw.add(ByteCode.ATHROW);
+
+ // mark the handler
+ cfw.addExceptionHandler(enterAreaStartLabel, epilogueLabel,
+ finallyHandler, null); // catch any
+ }
+ }
+
+ private void generateGetGeneratorLocalsState() {
+ cfw.addALoad(generatorStateLocal);
+ addOptRuntimeInvoke("getGeneratorLocalsState",
+ "(Ljava/lang/Object;)[Ljava/lang/Object;");
+ }
+
+ private void generateActivationExit()
+ {
+ if (fnCurrent == null || hasVarsInRegs) throw Kit.codeBug();
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("exitActivationFunction",
+ "(Lorg/mozilla/javascript/Context;)V");
+ }
+
+ private void generateStatement(Node node)
+ {
+ updateLineNumber(node);
+ int type = node.getType();
+ Node child = node.getFirstChild();
+ switch (type) {
+ case Token.LOOP:
+ case Token.LABEL:
+ case Token.WITH:
+ case Token.SCRIPT:
+ case Token.BLOCK:
+ case Token.EMPTY:
+ // no-ops.
+ while (child != null) {
+ generateStatement(child);
+ child = child.getNext();
+ }
+ break;
+
+ case Token.LOCAL_BLOCK: {
+ int local = getNewWordLocal();
+ if (isGenerator) {
+ cfw.add(ByteCode.ACONST_NULL);
+ cfw.addAStore(local);
+ }
+ node.putIntProp(Node.LOCAL_PROP, local);
+ while (child != null) {
+ generateStatement(child);
+ child = child.getNext();
+ }
+ releaseWordLocal((short)local);
+ node.removeProp(Node.LOCAL_PROP);
+ break;
+ }
+
+ case Token.FUNCTION: {
+ int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
+ OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn, fnIndex);
+ int t = ofn.fnode.getFunctionType();
+ if (t == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
+ visitFunction(ofn, t);
+ } else {
+ if (t != FunctionNode.FUNCTION_STATEMENT) {
+ throw Codegen.badTree();
+ }
+ }
+ break;
+ }
+
+ case Token.TRY:
+ visitTryCatchFinally((Node.Jump)node, child);
+ break;
+
+ case Token.CATCH_SCOPE:
+ {
+ // nothing stays on the stack on entry into a catch scope
+ cfw.setStackTop((short) 0);
+
+ int local = getLocalBlockRegister(node);
+ int scopeIndex
+ = node.getExistingIntProp(Node.CATCH_SCOPE_PROP);
+
+ String name = child.getString(); // name of exception
+ child = child.getNext();
+ generateExpression(child, node); // load expression object
+ if (scopeIndex == 0) {
+ cfw.add(ByteCode.ACONST_NULL);
+ } else {
+ // Load previous catch scope object
+ cfw.addALoad(local);
+ }
+ cfw.addPush(name);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+
+ addScriptRuntimeInvoke(
+ "newCatchScope",
+ "(Ljava/lang/Throwable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(local);
+ }
+ break;
+
+ case Token.THROW:
+ generateExpression(child, node);
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ generateThrowJavaScriptException();
+ break;
+
+ case Token.RETHROW:
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ cfw.addALoad(getLocalBlockRegister(node));
+ cfw.add(ByteCode.ATHROW);
+ break;
+
+ case Token.RETURN_RESULT:
+ case Token.RETURN:
+ if (!isGenerator) {
+ if (child != null) {
+ generateExpression(child, node);
+ } else if (type == Token.RETURN) {
+ Codegen.pushUndefined(cfw);
+ } else {
+ if (popvLocal < 0) throw Codegen.badTree();
+ cfw.addALoad(popvLocal);
+ }
+ }
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ if (epilogueLabel == -1) {
+ if (!hasVarsInRegs) throw Codegen.badTree();
+ epilogueLabel = cfw.acquireLabel();
+ }
+ cfw.add(ByteCode.GOTO, epilogueLabel);
+ break;
+
+ case Token.SWITCH:
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ visitSwitch((Node.Jump)node, child);
+ break;
+
+ case Token.ENTERWITH:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke(
+ "enterWith",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ incReferenceWordLocal(variableObjectLocal);
+ break;
+
+ case Token.LEAVEWITH:
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke(
+ "leaveWith",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ decReferenceWordLocal(variableObjectLocal);
+ break;
+
+ case Token.ENUM_INIT_KEYS:
+ case Token.ENUM_INIT_VALUES:
+ case Token.ENUM_INIT_ARRAY:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ int enumType = type == Token.ENUM_INIT_KEYS
+ ? ScriptRuntime.ENUMERATE_KEYS :
+ type == Token.ENUM_INIT_VALUES
+ ? ScriptRuntime.ENUMERATE_VALUES :
+ ScriptRuntime.ENUMERATE_ARRAY;
+ cfw.addPush(enumType);
+ addScriptRuntimeInvoke("enumInit",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I"
+ +")Ljava/lang/Object;");
+ cfw.addAStore(getLocalBlockRegister(node));
+ break;
+
+ case Token.EXPR_VOID:
+ if (child.getType() == Token.SETVAR) {
+ /* special case this so as to avoid unnecessary
+ load's & pop's */
+ visitSetVar(child, child.getFirstChild(), false);
+ }
+ else if (child.getType() == Token.SETCONSTVAR) {
+ /* special case this so as to avoid unnecessary
+ load's & pop's */
+ visitSetConstVar(child, child.getFirstChild(), false);
+ }
+ else if (child.getType() == Token.YIELD) {
+ generateYieldPoint(child, false);
+ }
+ else {
+ generateExpression(child, node);
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1)
+ cfw.add(ByteCode.POP2);
+ else
+ cfw.add(ByteCode.POP);
+ }
+ break;
+
+ case Token.EXPR_RESULT:
+ generateExpression(child, node);
+ if (popvLocal < 0) {
+ popvLocal = getNewWordLocal();
+ }
+ cfw.addAStore(popvLocal);
+ break;
+
+ case Token.TARGET:
+ {
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ int label = getTargetLabel(node);
+ cfw.markLabel(label);
+ if (compilerEnv.isGenerateObserverCount())
+ saveCurrentCodeOffset();
+ }
+ break;
+
+ case Token.JSR:
+ case Token.GOTO:
+ case Token.IFEQ:
+ case Token.IFNE:
+ if (compilerEnv.isGenerateObserverCount())
+ addInstructionCount();
+ visitGoto((Node.Jump)node, type, child);
+ break;
+
+ case Token.FINALLY:
+ {
+ if (compilerEnv.isGenerateObserverCount())
+ saveCurrentCodeOffset();
+ // there is exactly one value on the stack when enterring
+ // finally blocks: the return address (or its int encoding)
+ cfw.setStackTop((short)1);
+
+ // Save return address in a new local
+ int finallyRegister = getNewWordLocal();
+ if (isGenerator)
+ generateIntegerWrap();
+ cfw.addAStore(finallyRegister);
+
+ while (child != null) {
+ generateStatement(child);
+ child = child.getNext();
+ }
+ if (isGenerator) {
+ cfw.addALoad(finallyRegister);
+ cfw.add(ByteCode.CHECKCAST, "java/lang/Integer");
+ generateIntegerUnwrap();
+ FinallyReturnPoint ret =
+ (FinallyReturnPoint)finallys.get(node);
+ ret.tableLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, ret.tableLabel);
+ } else {
+ cfw.add(ByteCode.RET, finallyRegister);
+ }
+ releaseWordLocal((short)finallyRegister);
+ }
+ break;
+
+ case Token.DEBUGGER:
+ break;
+
+ default:
+ throw Codegen.badTree();
+ }
+
+ }
+
+ private void generateIntegerWrap()
+ {
+ cfw.addInvoke(ByteCode.INVOKESTATIC, "java/lang/Integer", "valueOf",
+ "(I)Ljava/lang/Integer;");
+ }
+
+
+ private void generateIntegerUnwrap()
+ {
+ cfw.addInvoke(ByteCode.INVOKEVIRTUAL, "java/lang/Integer",
+ "intValue", "()I");
+ }
+
+
+ private void generateThrowJavaScriptException()
+ {
+ cfw.add(ByteCode.NEW,
+ "org/mozilla/javascript/JavaScriptException");
+ cfw.add(ByteCode.DUP_X1);
+ cfw.add(ByteCode.SWAP);
+ cfw.addPush(scriptOrFn.getSourceName());
+ cfw.addPush(itsLineNumber);
+ cfw.addInvoke(
+ ByteCode.INVOKESPECIAL,
+ "org/mozilla/javascript/JavaScriptException",
+ "<init>",
+ "(Ljava/lang/Object;Ljava/lang/String;I)V");
+ cfw.add(ByteCode.ATHROW);
+ }
+
+ private int getNextGeneratorState(Node node)
+ {
+ int nodeIndex = ((FunctionNode)scriptOrFn).getResumptionPoints()
+ .indexOf(node);
+ return nodeIndex + GENERATOR_YIELD_START;
+ }
+
+ private void generateExpression(Node node, Node parent)
+ {
+ int type = node.getType();
+ Node child = node.getFirstChild();
+ switch (type) {
+ case Token.USE_STACK:
+ break;
+
+ case Token.FUNCTION:
+ if (fnCurrent != null || parent.getType() != Token.SCRIPT) {
+ int fnIndex = node.getExistingIntProp(Node.FUNCTION_PROP);
+ OptFunctionNode ofn = OptFunctionNode.get(scriptOrFn,
+ fnIndex);
+ int t = ofn.fnode.getFunctionType();
+ if (t != FunctionNode.FUNCTION_EXPRESSION) {
+ throw Codegen.badTree();
+ }
+ visitFunction(ofn, t);
+ }
+ break;
+
+ case Token.NAME:
+ {
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(node.getString());
+ addScriptRuntimeInvoke(
+ "name",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +")Ljava/lang/Object;");
+ }
+ break;
+
+ case Token.CALL:
+ case Token.NEW:
+ {
+ int specialType = node.getIntProp(Node.SPECIALCALL_PROP,
+ Node.NON_SPECIALCALL);
+ if (specialType == Node.NON_SPECIALCALL) {
+ OptFunctionNode target;
+ target = (OptFunctionNode)node.getProp(
+ Node.DIRECTCALL_PROP);
+
+ if (target != null) {
+ visitOptimizedCall(node, target, type, child);
+ } else if (type == Token.CALL) {
+ visitStandardCall(node, child);
+ } else {
+ visitStandardNew(node, child);
+ }
+ } else {
+ visitSpecialCall(node, type, specialType, child);
+ }
+ }
+ break;
+
+ case Token.REF_CALL:
+ generateFunctionAndThisObj(child, node);
+ // stack: ... functionObj thisObj
+ child = child.getNext();
+ generateCallArgArray(node, child, false);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "callRef",
+ "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Ref;");
+ break;
+
+ case Token.NUMBER:
+ {
+ double num = node.getDouble();
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
+ cfw.addPush(num);
+ } else {
+ codegen.pushNumberAsObject(cfw, num);
+ }
+ }
+ break;
+
+ case Token.STRING:
+ cfw.addPush(node.getString());
+ break;
+
+ case Token.THIS:
+ cfw.addALoad(thisObjLocal);
+ break;
+
+ case Token.THISFN:
+ cfw.add(ByteCode.ALOAD_0);
+ break;
+
+ case Token.NULL:
+ cfw.add(ByteCode.ACONST_NULL);
+ break;
+
+ case Token.TRUE:
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "TRUE", "Ljava/lang/Boolean;");
+ break;
+
+ case Token.FALSE:
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "FALSE", "Ljava/lang/Boolean;");
+ break;
+
+ case Token.REGEXP:
+ {
+ int i = node.getExistingIntProp(Node.REGEXP_PROP);
+ // Scripts can not use REGEXP_ARRAY_FIELD_NAME since
+ // it it will make script.exec non-reentrant so they
+ // store regexp array in a local variable while
+ // functions always access precomputed
+ // REGEXP_ARRAY_FIELD_NAME not to consume locals
+ if (fnCurrent == null) {
+ cfw.addALoad(scriptRegexpLocal);
+ } else {
+ cfw.addALoad(funObjLocal);
+ cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
+ Codegen.REGEXP_ARRAY_FIELD_NAME,
+ Codegen.REGEXP_ARRAY_FIELD_TYPE);
+ }
+ cfw.addPush(i);
+ cfw.add(ByteCode.AALOAD);
+ }
+ break;
+
+ case Token.COMMA: {
+ Node next = child.getNext();
+ while (next != null) {
+ generateExpression(child, node);
+ cfw.add(ByteCode.POP);
+ child = next;
+ next = next.getNext();
+ }
+ generateExpression(child, node);
+ break;
+ }
+
+ case Token.ENUM_NEXT:
+ case Token.ENUM_ID: {
+ int local = getLocalBlockRegister(node);
+ cfw.addALoad(local);
+ if (type == Token.ENUM_NEXT) {
+ addScriptRuntimeInvoke(
+ "enumNext", "(Ljava/lang/Object;)Ljava/lang/Boolean;");
+ } else {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("enumId",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ break;
+ }
+
+ case Token.ARRAYLIT:
+ visitArrayLiteral(node, child);
+ break;
+
+ case Token.OBJECTLIT:
+ visitObjectLiteral(node, child);
+ break;
+
+ case Token.NOT: {
+ int trueTarget = cfw.acquireLabel();
+ int falseTarget = cfw.acquireLabel();
+ int beyond = cfw.acquireLabel();
+ generateIfJump(child, node, trueTarget, falseTarget);
+
+ cfw.markLabel(trueTarget);
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "FALSE", "Ljava/lang/Boolean;");
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(falseTarget);
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "TRUE", "Ljava/lang/Boolean;");
+ cfw.markLabel(beyond);
+ cfw.adjustStackTop(-1);
+ break;
+ }
+
+ case Token.BITNOT:
+ generateExpression(child, node);
+ addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
+ cfw.addPush(-1); // implement ~a as (a ^ -1)
+ cfw.add(ByteCode.IXOR);
+ cfw.add(ByteCode.I2D);
+ addDoubleWrap();
+ break;
+
+ case Token.VOID:
+ generateExpression(child, node);
+ cfw.add(ByteCode.POP);
+ Codegen.pushUndefined(cfw);
+ break;
+
+ case Token.TYPEOF:
+ generateExpression(child, node);
+ addScriptRuntimeInvoke("typeof",
+ "(Ljava/lang/Object;"
+ +")Ljava/lang/String;");
+ break;
+
+ case Token.TYPEOFNAME:
+ visitTypeofname(node);
+ break;
+
+ case Token.INC:
+ case Token.DEC:
+ visitIncDec(node);
+ break;
+
+ case Token.OR:
+ case Token.AND: {
+ generateExpression(child, node);
+ cfw.add(ByteCode.DUP);
+ addScriptRuntimeInvoke("toBoolean",
+ "(Ljava/lang/Object;)Z");
+ int falseTarget = cfw.acquireLabel();
+ if (type == Token.AND)
+ cfw.add(ByteCode.IFEQ, falseTarget);
+ else
+ cfw.add(ByteCode.IFNE, falseTarget);
+ cfw.add(ByteCode.POP);
+ generateExpression(child.getNext(), node);
+ cfw.markLabel(falseTarget);
+ }
+ break;
+
+ case Token.HOOK : {
+ Node ifThen = child.getNext();
+ Node ifElse = ifThen.getNext();
+ generateExpression(child, node);
+ addScriptRuntimeInvoke("toBoolean",
+ "(Ljava/lang/Object;)Z");
+ int elseTarget = cfw.acquireLabel();
+ cfw.add(ByteCode.IFEQ, elseTarget);
+ short stack = cfw.getStackTop();
+ generateExpression(ifThen, node);
+ int afterHook = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, afterHook);
+ cfw.markLabel(elseTarget, stack);
+ generateExpression(ifElse, node);
+ cfw.markLabel(afterHook);
+ }
+ break;
+
+ case Token.ADD: {
+ generateExpression(child, node);
+ generateExpression(child.getNext(), node);
+ switch (node.getIntProp(Node.ISNUMBER_PROP, -1)) {
+ case Node.BOTH:
+ cfw.add(ByteCode.DADD);
+ break;
+ case Node.LEFT:
+ addOptRuntimeInvoke("add",
+ "(DLjava/lang/Object;)Ljava/lang/Object;");
+ break;
+ case Node.RIGHT:
+ addOptRuntimeInvoke("add",
+ "(Ljava/lang/Object;D)Ljava/lang/Object;");
+ break;
+ default:
+ if (child.getType() == Token.STRING) {
+ addScriptRuntimeInvoke("add",
+ "(Ljava/lang/String;"
+ +"Ljava/lang/Object;"
+ +")Ljava/lang/String;");
+ } else if (child.getNext().getType() == Token.STRING) {
+ addScriptRuntimeInvoke("add",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +")Ljava/lang/String;");
+ } else {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("add",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ }
+ }
+ break;
+
+ case Token.MUL:
+ visitArithmetic(node, ByteCode.DMUL, child, parent);
+ break;
+
+ case Token.SUB:
+ visitArithmetic(node, ByteCode.DSUB, child, parent);
+ break;
+
+ case Token.DIV:
+ case Token.MOD:
+ visitArithmetic(node, type == Token.DIV
+ ? ByteCode.DDIV
+ : ByteCode.DREM, child, parent);
+ break;
+
+ case Token.BITOR:
+ case Token.BITXOR:
+ case Token.BITAND:
+ case Token.LSH:
+ case Token.RSH:
+ case Token.URSH:
+ visitBitOp(node, type, child);
+ break;
+
+ case Token.POS:
+ case Token.NEG:
+ generateExpression(child, node);
+ addObjectToDouble();
+ if (type == Token.NEG) {
+ cfw.add(ByteCode.DNEG);
+ }
+ addDoubleWrap();
+ break;
+
+ case Token.TO_DOUBLE:
+ // cnvt to double (not Double)
+ generateExpression(child, node);
+ addObjectToDouble();
+ break;
+
+ case Token.TO_OBJECT: {
+ // convert from double
+ int prop = -1;
+ if (child.getType() == Token.NUMBER) {
+ prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
+ }
+ if (prop != -1) {
+ child.removeProp(Node.ISNUMBER_PROP);
+ generateExpression(child, node);
+ child.putIntProp(Node.ISNUMBER_PROP, prop);
+ } else {
+ generateExpression(child, node);
+ addDoubleWrap();
+ }
+ break;
+ }
+
+ case Token.IN:
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT: {
+ int trueGOTO = cfw.acquireLabel();
+ int falseGOTO = cfw.acquireLabel();
+ visitIfJumpRelOp(node, child, trueGOTO, falseGOTO);
+ addJumpedBooleanWrap(trueGOTO, falseGOTO);
+ break;
+ }
+
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE: {
+ int trueGOTO = cfw.acquireLabel();
+ int falseGOTO = cfw.acquireLabel();
+ visitIfJumpEqOp(node, child, trueGOTO, falseGOTO);
+ addJumpedBooleanWrap(trueGOTO, falseGOTO);
+ break;
+ }
+
+ case Token.GETPROP:
+ case Token.GETPROPNOWARN:
+ visitGetProp(node, child);
+ break;
+
+ case Token.GETELEM:
+ generateExpression(child, node); // object
+ generateExpression(child.getNext(), node); // id
+ cfw.addALoad(contextLocal);
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
+ addScriptRuntimeInvoke(
+ "getObjectIndex",
+ "(Ljava/lang/Object;D"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ else {
+ addScriptRuntimeInvoke(
+ "getObjectElem",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ break;
+
+ case Token.GET_REF:
+ generateExpression(child, node); // reference
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "refGet",
+ "(Lorg/mozilla/javascript/Ref;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ break;
+
+ case Token.GETVAR:
+ visitGetVar(node);
+ break;
+
+ case Token.SETVAR:
+ visitSetVar(node, child, true);
+ break;
+
+ case Token.SETNAME:
+ visitSetName(node, child);
+ break;
+
+ case Token.SETCONST:
+ visitSetConst(node, child);
+ break;
+
+ case Token.SETCONSTVAR:
+ visitSetConstVar(node, child, true);
+ break;
+
+ case Token.SETPROP:
+ case Token.SETPROP_OP:
+ visitSetProp(type, node, child);
+ break;
+
+ case Token.SETELEM:
+ case Token.SETELEM_OP:
+ visitSetElem(type, node, child);
+ break;
+
+ case Token.SET_REF:
+ case Token.SET_REF_OP:
+ {
+ generateExpression(child, node);
+ child = child.getNext();
+ if (type == Token.SET_REF_OP) {
+ cfw.add(ByteCode.DUP);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "refGet",
+ "(Lorg/mozilla/javascript/Ref;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "refSet",
+ "(Lorg/mozilla/javascript/Ref;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ break;
+
+ case Token.DEL_REF:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("refDel",
+ "(Lorg/mozilla/javascript/Ref;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ break;
+
+ case Token.DELPROP:
+ generateExpression(child, node);
+ child = child.getNext();
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("delete",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ break;
+
+ case Token.BINDNAME:
+ {
+ while (child != null) {
+ generateExpression(child, node);
+ child = child.getNext();
+ }
+ // Generate code for "ScriptRuntime.bind(varObj, "s")"
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(node.getString());
+ addScriptRuntimeInvoke(
+ "bind",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ }
+ break;
+
+ case Token.LOCAL_LOAD:
+ cfw.addALoad(getLocalBlockRegister(node));
+ break;
+
+ case Token.REF_SPECIAL:
+ {
+ String special = (String)node.getProp(Node.NAME_PROP);
+ generateExpression(child, node);
+ cfw.addPush(special);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "specialRef",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Ref;");
+ }
+ break;
+
+ case Token.REF_MEMBER:
+ case Token.REF_NS_MEMBER:
+ case Token.REF_NAME:
+ case Token.REF_NS_NAME:
+ {
+ int memberTypeFlags
+ = node.getIntProp(Node.MEMBER_TYPE_PROP, 0);
+ // generate possible target, possible namespace and member
+ do {
+ generateExpression(child, node);
+ child = child.getNext();
+ } while (child != null);
+ cfw.addALoad(contextLocal);
+ String methodName, signature;
+ switch (type) {
+ case Token.REF_MEMBER:
+ methodName = "memberRef";
+ signature = "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I"
+ +")Lorg/mozilla/javascript/Ref;";
+ break;
+ case Token.REF_NS_MEMBER:
+ methodName = "memberRef";
+ signature = "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I"
+ +")Lorg/mozilla/javascript/Ref;";
+ break;
+ case Token.REF_NAME:
+ methodName = "nameRef";
+ signature = "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"I"
+ +")Lorg/mozilla/javascript/Ref;";
+ cfw.addALoad(variableObjectLocal);
+ break;
+ case Token.REF_NS_NAME:
+ methodName = "nameRef";
+ signature = "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"I"
+ +")Lorg/mozilla/javascript/Ref;";
+ cfw.addALoad(variableObjectLocal);
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ cfw.addPush(memberTypeFlags);
+ addScriptRuntimeInvoke(methodName, signature);
+ }
+ break;
+
+ case Token.DOTQUERY:
+ visitDotQuery(node, child);
+ break;
+
+ case Token.ESCXMLATTR:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("escapeAttributeValue",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/String;");
+ break;
+
+ case Token.ESCXMLTEXT:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("escapeTextValue",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/String;");
+ break;
+
+ case Token.DEFAULTNAMESPACE:
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke("setDefaultNamespace",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ break;
+
+ case Token.YIELD:
+ generateYieldPoint(node, true);
+ break;
+
+ case Token.WITHEXPR: {
+ Node enterWith = child;
+ Node with = enterWith.getNext();
+ Node leaveWith = with.getNext();
+ generateStatement(enterWith);
+ generateExpression(with.getFirstChild(), with);
+ generateStatement(leaveWith);
+ break;
+ }
+
+ case Token.ARRAYCOMP: {
+ Node initStmt = child;
+ Node expr = child.getNext();
+ generateStatement(initStmt);
+ generateExpression(expr, node);
+ break;
+ }
+
+ default:
+ throw new RuntimeException("Unexpected node type "+type);
+ }
+
+ }
+
+ private void generateYieldPoint(Node node, boolean exprContext) {
+ // save stack state
+ int top = cfw.getStackTop();
+ maxStack = maxStack > top ? maxStack : top;
+ if (cfw.getStackTop() != 0) {
+ generateGetGeneratorStackState();
+ for (int i = 0; i < top; i++) {
+ cfw.add(ByteCode.DUP_X1);
+ cfw.add(ByteCode.SWAP);
+ cfw.addLoadConstant(i);
+ cfw.add(ByteCode.SWAP);
+ cfw.add(ByteCode.AASTORE);
+ }
+ // pop the array object
+ cfw.add(ByteCode.POP);
+ }
+
+ // generate the yield argument
+ Node child = node.getFirstChild();
+ if (child != null)
+ generateExpression(child, node);
+ else
+ Codegen.pushUndefined(cfw);
+
+ // change the resumption state
+ int nextState = getNextGeneratorState(node);
+ generateSetGeneratorResumptionPoint(nextState);
+
+ boolean hasLocals = generateSaveLocals(node);
+
+ cfw.add(ByteCode.ARETURN);
+
+ generateCheckForThrowOrClose(getTargetLabel(node),
+ hasLocals, nextState);
+
+ // reconstruct the stack
+ if (top != 0) {
+ generateGetGeneratorStackState();
+ for (int i = 0; i < top; i++) {
+ cfw.add(ByteCode.DUP);
+ cfw.addLoadConstant(top - i - 1);
+ cfw.add(ByteCode.AALOAD);
+ cfw.add(ByteCode.SWAP);
+ }
+ cfw.add(ByteCode.POP);
+ }
+
+ // load return value from yield
+ if (exprContext) {
+ cfw.addALoad(argsLocal);
+ }
+ }
+
+ private void generateCheckForThrowOrClose(int label,
+ boolean hasLocals,
+ int nextState) {
+ int throwLabel = cfw.acquireLabel();
+ int closeLabel = cfw.acquireLabel();
+
+ // throw the user provided object, if the operation is .throw()
+ cfw.markLabel(throwLabel);
+ cfw.addALoad(argsLocal);
+ generateThrowJavaScriptException();
+
+ // throw our special internal exception if the generator is being closed
+ cfw.markLabel(closeLabel);
+ cfw.addALoad(argsLocal);
+ cfw.add(ByteCode.CHECKCAST, "java/lang/Throwable");
+ cfw.add(ByteCode.ATHROW);
+
+ // mark the re-entry point
+ // jump here after initializing the locals
+ if (label != -1)
+ cfw.markLabel(label);
+ if (!hasLocals) {
+ // jump here directly if there are no locals
+ cfw.markTableSwitchCase(generatorSwitch, nextState);
+ }
+
+ // see if we need to dispatch for .close() or .throw()
+ cfw.addILoad(operationLocal);
+ cfw.addLoadConstant(NativeGenerator.GENERATOR_CLOSE);
+ cfw.add(ByteCode.IF_ICMPEQ, closeLabel);
+ cfw.addILoad(operationLocal);
+ cfw.addLoadConstant(NativeGenerator.GENERATOR_THROW);
+ cfw.add(ByteCode.IF_ICMPEQ, throwLabel);
+ }
+
+ private void generateIfJump(Node node, Node parent,
+ int trueLabel, int falseLabel)
+ {
+ // System.out.println("gen code for " + node.toString());
+
+ int type = node.getType();
+ Node child = node.getFirstChild();
+
+ switch (type) {
+ case Token.NOT:
+ generateIfJump(child, node, falseLabel, trueLabel);
+ break;
+
+ case Token.OR:
+ case Token.AND: {
+ int interLabel = cfw.acquireLabel();
+ if (type == Token.AND) {
+ generateIfJump(child, node, interLabel, falseLabel);
+ }
+ else {
+ generateIfJump(child, node, trueLabel, interLabel);
+ }
+ cfw.markLabel(interLabel);
+ child = child.getNext();
+ generateIfJump(child, node, trueLabel, falseLabel);
+ break;
+ }
+
+ case Token.IN:
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ visitIfJumpRelOp(node, child, trueLabel, falseLabel);
+ break;
+
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ visitIfJumpEqOp(node, child, trueLabel, falseLabel);
+ break;
+
+ default:
+ // Generate generic code for non-optimized jump
+ generateExpression(node, parent);
+ addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z");
+ cfw.add(ByteCode.IFNE, trueLabel);
+ cfw.add(ByteCode.GOTO, falseLabel);
+ }
+ }
+
+ private void visitFunction(OptFunctionNode ofn, int functionType)
+ {
+ int fnIndex = codegen.getIndex(ofn.fnode);
+ cfw.add(ByteCode.NEW, codegen.mainClassName);
+ // Call function constructor
+ cfw.add(ByteCode.DUP);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(contextLocal); // load 'cx'
+ cfw.addPush(fnIndex);
+ cfw.addInvoke(ByteCode.INVOKESPECIAL, codegen.mainClassName,
+ "<init>", Codegen.FUNCTION_CONSTRUCTOR_SIGNATURE);
+
+ // Init mainScript field;
+ cfw.add(ByteCode.DUP);
+ if (isTopLevel) {
+ cfw.add(ByteCode.ALOAD_0);
+ } else {
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD,
+ codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+ }
+ cfw.add(ByteCode.PUTFIELD,
+ codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+
+ int directTargetIndex = ofn.getDirectTargetIndex();
+ if (directTargetIndex >= 0) {
+ cfw.add(ByteCode.DUP);
+ if (isTopLevel) {
+ cfw.add(ByteCode.ALOAD_0);
+ } else {
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD,
+ codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+ }
+ cfw.add(ByteCode.SWAP);
+ cfw.add(ByteCode.PUTFIELD,
+ codegen.mainClassName,
+ Codegen.getDirectTargetFieldName(directTargetIndex),
+ codegen.mainClassSignature);
+ }
+
+ if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
+ // Leave closure object on stack and do not pass it to
+ // initFunction which suppose to connect statements to scope
+ return;
+ }
+ cfw.addPush(functionType);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(contextLocal); // load 'cx'
+ addOptRuntimeInvoke("initFunction",
+ "(Lorg/mozilla/javascript/NativeFunction;"
+ +"I"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")V");
+ }
+
+ private int getTargetLabel(Node target)
+ {
+ int labelId = target.labelId();
+ if (labelId == -1) {
+ labelId = cfw.acquireLabel();
+ target.labelId(labelId);
+ }
+ return labelId;
+ }
+
+ private void visitGoto(Node.Jump node, int type, Node child)
+ {
+ Node target = node.target;
+ if (type == Token.IFEQ || type == Token.IFNE) {
+ if (child == null) throw Codegen.badTree();
+ int targetLabel = getTargetLabel(target);
+ int fallThruLabel = cfw.acquireLabel();
+ if (type == Token.IFEQ)
+ generateIfJump(child, node, targetLabel, fallThruLabel);
+ else
+ generateIfJump(child, node, fallThruLabel, targetLabel);
+ cfw.markLabel(fallThruLabel);
+ } else {
+ if (type == Token.JSR) {
+ if (isGenerator) {
+ addGotoWithReturn(target);
+ } else {
+ addGoto(target, ByteCode.JSR);
+ }
+ } else {
+ addGoto(target, ByteCode.GOTO);
+ }
+ }
+ }
+
+ private void addGotoWithReturn(Node target) {
+ FinallyReturnPoint ret =
+ (FinallyReturnPoint)finallys.get(target);
+ cfw.addLoadConstant(ret.jsrPoints.size());
+ addGoto(target, ByteCode.GOTO);
+ int retLabel = cfw.acquireLabel();
+ cfw.markLabel(retLabel);
+ ret.jsrPoints.add(Integer.valueOf(retLabel));
+ }
+
+ private void visitArrayLiteral(Node node, Node child)
+ {
+ int count = 0;
+ for (Node cursor = child; cursor != null; cursor = cursor.getNext()) {
+ ++count;
+ }
+ // load array to store array literal objects
+ addNewObjectArray(count);
+ for (int i = 0; i != count; ++i) {
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ generateExpression(child, node);
+ cfw.add(ByteCode.AASTORE);
+ child = child.getNext();
+ }
+ int[] skipIndexes = (int[])node.getProp(Node.SKIP_INDEXES_PROP);
+ if (skipIndexes == null) {
+ cfw.add(ByteCode.ACONST_NULL);
+ cfw.add(ByteCode.ICONST_0);
+ } else {
+ cfw.addPush(OptRuntime.encodeIntArray(skipIndexes));
+ cfw.addPush(skipIndexes.length);
+ }
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addOptRuntimeInvoke("newArrayLiteral",
+ "([Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"I"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ }
+
+ private void visitObjectLiteral(Node node, Node child)
+ {
+ Object[] properties = (Object[])node.getProp(Node.OBJECT_IDS_PROP);
+ int count = properties.length;
+
+ // load array with property ids
+ addNewObjectArray(count);
+ for (int i = 0; i != count; ++i) {
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ Object id = properties[i];
+ if (id instanceof String) {
+ cfw.addPush((String)id);
+ } else {
+ cfw.addPush(((Integer)id).intValue());
+ addScriptRuntimeInvoke("wrapInt", "(I)Ljava/lang/Integer;");
+ }
+ cfw.add(ByteCode.AASTORE);
+ }
+ // load array with property values
+ addNewObjectArray(count);
+ Node child2 = child;
+ for (int i = 0; i != count; ++i) {
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ int childType = child.getType();
+ if (childType == Token.GET) {
+ generateExpression(child.getFirstChild(), node);
+ } else if (childType == Token.SET) {
+ generateExpression(child.getFirstChild(), node);
+ } else {
+ generateExpression(child, node);
+ }
+ cfw.add(ByteCode.AASTORE);
+ child = child.getNext();
+ }
+ // load array with getterSetter values
+ cfw.addPush(count);
+ cfw.add(ByteCode.NEWARRAY, ByteCode.T_INT);
+ for (int i = 0; i != count; ++i) {
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ int childType = child2.getType();
+ if (childType == Token.GET) {
+ cfw.add(ByteCode.ICONST_M1);
+ } else if (childType == Token.SET) {
+ cfw.add(ByteCode.ICONST_1);
+ } else {
+ cfw.add(ByteCode.ICONST_0);
+ }
+ cfw.add(ByteCode.IASTORE);
+ child2 = child2.getNext();
+ }
+
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke("newObjectLiteral",
+ "([Ljava/lang/Object;"
+ +"[Ljava/lang/Object;"
+ +"[I"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ }
+
+ private void visitSpecialCall(Node node, int type, int specialType,
+ Node child)
+ {
+ cfw.addALoad(contextLocal);
+
+ if (type == Token.NEW) {
+ generateExpression(child, node);
+ // stack: ... cx functionObj
+ } else {
+ generateFunctionAndThisObj(child, node);
+ // stack: ... cx functionObj thisObj
+ }
+ child = child.getNext();
+
+ generateCallArgArray(node, child, false);
+
+ String methodName;
+ String callSignature;
+
+ if (type == Token.NEW) {
+ methodName = "newObjectSpecial";
+ callSignature = "(Lorg/mozilla/javascript/Context;"
+ +"Ljava/lang/Object;"
+ +"[Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"I" // call type
+ +")Ljava/lang/Object;";
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(thisObjLocal);
+ cfw.addPush(specialType);
+ } else {
+ methodName = "callSpecial";
+ callSignature = "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"I" // call type
+ +"Ljava/lang/String;I" // filename, linenumber
+ +")Ljava/lang/Object;";
+ cfw.addALoad(variableObjectLocal);
+ cfw.addALoad(thisObjLocal);
+ cfw.addPush(specialType);
+ String sourceName = scriptOrFn.getSourceName();
+ cfw.addPush(sourceName == null ? "" : sourceName);
+ cfw.addPush(itsLineNumber);
+ }
+
+ addOptRuntimeInvoke(methodName, callSignature);
+ }
+
+ private void visitStandardCall(Node node, Node child)
+ {
+ if (node.getType() != Token.CALL) throw Codegen.badTree();
+
+ Node firstArgChild = child.getNext();
+ int childType = child.getType();
+
+ String methodName;
+ String signature;
+
+ if (firstArgChild == null) {
+ if (childType == Token.NAME) {
+ // name() call
+ String name = child.getString();
+ cfw.addPush(name);
+ methodName = "callName0";
+ signature = "(Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ } else if (childType == Token.GETPROP) {
+ // x.name() call
+ Node propTarget = child.getFirstChild();
+ generateExpression(propTarget, node);
+ Node id = propTarget.getNext();
+ String property = id.getString();
+ cfw.addPush(property);
+ methodName = "callProp0";
+ signature = "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ } else if (childType == Token.GETPROPNOWARN) {
+ throw Kit.codeBug();
+ } else {
+ generateFunctionAndThisObj(child, node);
+ methodName = "call0";
+ signature = "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ }
+
+ } else if (childType == Token.NAME) {
+ // XXX: this optimization is only possible if name
+ // resolution
+ // is not affected by arguments evaluation and currently
+ // there are no checks for it
+ String name = child.getString();
+ generateCallArgArray(node, firstArgChild, false);
+ cfw.addPush(name);
+ methodName = "callName";
+ signature = "([Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ } else {
+ int argCount = 0;
+ for (Node arg = firstArgChild; arg != null; arg = arg.getNext()) {
+ ++argCount;
+ }
+ generateFunctionAndThisObj(child, node);
+ // stack: ... functionObj thisObj
+ if (argCount == 1) {
+ generateExpression(firstArgChild, node);
+ methodName = "call1";
+ signature = "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ } else if (argCount == 2) {
+ generateExpression(firstArgChild, node);
+ generateExpression(firstArgChild.getNext(), node);
+ methodName = "call2";
+ signature = "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ } else {
+ generateCallArgArray(node, firstArgChild, false);
+ methodName = "callN";
+ signature = "(Lorg/mozilla/javascript/Callable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;";
+ }
+ }
+
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addOptRuntimeInvoke(methodName, signature);
+ }
+
+ private void visitStandardNew(Node node, Node child)
+ {
+ if (node.getType() != Token.NEW) throw Codegen.badTree();
+
+ Node firstArgChild = child.getNext();
+
+ generateExpression(child, node);
+ // stack: ... functionObj
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ // stack: ... functionObj cx scope
+ generateCallArgArray(node, firstArgChild, false);
+ addScriptRuntimeInvoke(
+ "newObject",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ }
+
+ private void visitOptimizedCall(Node node, OptFunctionNode target,
+ int type, Node child)
+ {
+ Node firstArgChild = child.getNext();
+
+ short thisObjLocal = 0;
+ if (type == Token.NEW) {
+ generateExpression(child, node);
+ } else {
+ generateFunctionAndThisObj(child, node);
+ thisObjLocal = getNewWordLocal();
+ cfw.addAStore(thisObjLocal);
+ }
+ // stack: ... functionObj
+
+ int beyond = cfw.acquireLabel();
+
+ int directTargetIndex = target.getDirectTargetIndex();
+ if (isTopLevel) {
+ cfw.add(ByteCode.ALOAD_0);
+ } else {
+ cfw.add(ByteCode.ALOAD_0);
+ cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
+ Codegen.DIRECT_CALL_PARENT_FIELD,
+ codegen.mainClassSignature);
+ }
+ cfw.add(ByteCode.GETFIELD, codegen.mainClassName,
+ Codegen.getDirectTargetFieldName(directTargetIndex),
+ codegen.mainClassSignature);
+
+ cfw.add(ByteCode.DUP2);
+ // stack: ... functionObj directFunct functionObj directFunct
+
+ int regularCall = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPNE, regularCall);
+
+ // stack: ... functionObj directFunct
+ short stackHeight = cfw.getStackTop();
+ cfw.add(ByteCode.SWAP);
+ cfw.add(ByteCode.POP);
+ // stack: ... directFunct
+ if (compilerEnv.isUseDynamicScope()) {
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ } else {
+ cfw.add(ByteCode.DUP);
+ // stack: ... directFunct directFunct
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/Scriptable",
+ "getParentScope",
+ "()Lorg/mozilla/javascript/Scriptable;");
+ // stack: ... directFunct scope
+ cfw.addALoad(contextLocal);
+ // stack: ... directFunct scope cx
+ cfw.add(ByteCode.SWAP);
+ }
+ // stack: ... directFunc cx scope
+
+ if (type == Token.NEW) {
+ cfw.add(ByteCode.ACONST_NULL);
+ } else {
+ cfw.addALoad(thisObjLocal);
+ }
+ // stack: ... directFunc cx scope thisObj
+/*
+Remember that directCall parameters are paired in 1 aReg and 1 dReg
+If the argument is an incoming arg, just pass the orginal pair thru.
+Else, if the argument is known to be typed 'Number', pass Void.TYPE
+in the aReg and the number is the dReg
+Else pass the JS object in the aReg and 0.0 in the dReg.
+*/
+ Node argChild = firstArgChild;
+ while (argChild != null) {
+ int dcp_register = nodeIsDirectCallParameter(argChild);
+ if (dcp_register >= 0) {
+ cfw.addALoad(dcp_register);
+ cfw.addDLoad(dcp_register + 1);
+ } else if (argChild.getIntProp(Node.ISNUMBER_PROP, -1)
+ == Node.BOTH)
+ {
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ generateExpression(argChild, node);
+ } else {
+ generateExpression(argChild, node);
+ cfw.addPush(0.0);
+ }
+ argChild = argChild.getNext();
+ }
+
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "emptyArgs", "[Ljava/lang/Object;");
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ codegen.mainClassName,
+ (type == Token.NEW)
+ ? codegen.getDirectCtorName(target.fnode)
+ : codegen.getBodyMethodName(target.fnode),
+ codegen.getBodyMethodSignature(target.fnode));
+
+ cfw.add(ByteCode.GOTO, beyond);
+
+ cfw.markLabel(regularCall, stackHeight);
+ // stack: ... functionObj directFunct
+ cfw.add(ByteCode.POP);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ // stack: ... functionObj cx scope
+ if (type != Token.NEW) {
+ cfw.addALoad(thisObjLocal);
+ releaseWordLocal(thisObjLocal);
+ // stack: ... functionObj cx scope thisObj
+ }
+ // XXX: this will generate code for the child array the second time,
+ // so expression code generation better not to alter tree structure...
+ generateCallArgArray(node, firstArgChild, true);
+
+ if (type == Token.NEW) {
+ addScriptRuntimeInvoke(
+ "newObject",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ } else {
+ cfw.addInvoke(ByteCode.INVOKEINTERFACE,
+ "org/mozilla/javascript/Callable",
+ "call",
+ "(Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"[Ljava/lang/Object;"
+ +")Ljava/lang/Object;");
+ }
+
+ cfw.markLabel(beyond);
+ }
+
+ private void generateCallArgArray(Node node, Node argChild, boolean directCall)
+ {
+ int argCount = 0;
+ for (Node child = argChild; child != null; child = child.getNext()) {
+ ++argCount;
+ }
+ // load array object to set arguments
+ if (argCount == 1 && itsOneArgArray >= 0) {
+ cfw.addALoad(itsOneArgArray);
+ } else {
+ addNewObjectArray(argCount);
+ }
+ // Copy arguments into it
+ for (int i = 0; i != argCount; ++i) {
+ // If we are compiling a generator an argument could be the result
+ // of a yield. In that case we will have an immediate on the stack
+ // which we need to avoid
+ if (!isGenerator) {
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ }
+
+ if (!directCall) {
+ generateExpression(argChild, node);
+ } else {
+ // If this has also been a directCall sequence, the Number
+ // flag will have remained set for any parameter so that
+ // the values could be copied directly into the outgoing
+ // args. Here we want to force it to be treated as not in
+ // a Number context, so we set the flag off.
+ int dcp_register = nodeIsDirectCallParameter(argChild);
+ if (dcp_register >= 0) {
+ dcpLoadAsObject(dcp_register);
+ } else {
+ generateExpression(argChild, node);
+ int childNumberFlag
+ = argChild.getIntProp(Node.ISNUMBER_PROP, -1);
+ if (childNumberFlag == Node.BOTH) {
+ addDoubleWrap();
+ }
+ }
+ }
+
+ // When compiling generators, any argument to a method may be a
+ // yield expression. Hence we compile the argument first and then
+ // load the argument index and assign the value to the args array.
+ if (isGenerator) {
+ short tempLocal = getNewWordLocal();
+ cfw.addAStore(tempLocal);
+ cfw.add(ByteCode.CHECKCAST, "[Ljava/lang/Object;");
+ cfw.add(ByteCode.DUP);
+ cfw.addPush(i);
+ cfw.addALoad(tempLocal);
+ releaseWordLocal(tempLocal);
+ }
+
+ cfw.add(ByteCode.AASTORE);
+
+ argChild = argChild.getNext();
+ }
+ }
+
+ private void generateFunctionAndThisObj(Node node, Node parent)
+ {
+ // Place on stack (function object, function this) pair
+ int type = node.getType();
+ switch (node.getType()) {
+ case Token.GETPROPNOWARN:
+ throw Kit.codeBug();
+
+ case Token.GETPROP:
+ case Token.GETELEM: {
+ Node target = node.getFirstChild();
+ generateExpression(target, node);
+ Node id = target.getNext();
+ if (type == Token.GETPROP) {
+ String property = id.getString();
+ cfw.addPush(property);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getPropFunctionAndThis",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Callable;");
+ } else {
+ // Optimizer do not optimize this case for now
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1)
+ throw Codegen.badTree();
+ generateExpression(id, node); // id
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getElemFunctionAndThis",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Callable;");
+ }
+ break;
+ }
+
+ case Token.NAME: {
+ String name = node.getString();
+ cfw.addPush(name);
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke(
+ "getNameFunctionAndThis",
+ "(Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Callable;");
+ break;
+ }
+
+ default: // including GETVAR
+ generateExpression(node, parent);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getValueFunctionAndThis",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Callable;");
+ break;
+ }
+ // Get thisObj prepared by get(Name|Prop|Elem|Value)FunctionAndThis
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "lastStoredScriptable",
+ "(Lorg/mozilla/javascript/Context;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ }
+
+ private void updateLineNumber(Node node)
+ {
+ itsLineNumber = node.getLineno();
+ if (itsLineNumber == -1)
+ return;
+ cfw.addLineNumberEntry((short)itsLineNumber);
+ }
+
+ private void visitTryCatchFinally(Node.Jump node, Node child)
+ {
+ /* Save the variable object, in case there are with statements
+ * enclosed by the try block and we catch some exception.
+ * We'll restore it for the catch block so that catch block
+ * statements get the right scope.
+ */
+
+ // OPT we only need to do this if there are enclosed WITH
+ // statements; could statically check and omit this if there aren't any.
+
+ // XXX OPT Maybe instead do syntactic transforms to associate
+ // each 'with' with a try/finally block that does the exitwith.
+
+ short savedVariableObject = getNewWordLocal();
+ cfw.addALoad(variableObjectLocal);
+ cfw.addAStore(savedVariableObject);
+
+ /*
+ * Generate the code for the tree; most of the work is done in IRFactory
+ * and NodeTransformer; Codegen just adds the java handlers for the
+ * javascript catch and finally clauses. */
+
+ int startLabel = cfw.acquireLabel();
+ cfw.markLabel(startLabel, (short)0);
+
+ Node catchTarget = node.target;
+ Node finallyTarget = node.getFinally();
+
+ // create a table for the equivalent of JSR returns
+ if (isGenerator && finallyTarget != null) {
+ FinallyReturnPoint ret = new FinallyReturnPoint();
+ if (finallys == null) {
+ finallys = new Hashtable();
+ }
+ // add the finally target to hashtable
+ finallys.put(finallyTarget, ret);
+ // add the finally node as well to the hash table
+ finallys.put(finallyTarget.getNext(), ret);
+ }
+
+ while (child != null) {
+ generateStatement(child);
+ child = child.getNext();
+ }
+
+ // control flow skips the handlers
+ int realEnd = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, realEnd);
+
+ int exceptionLocal = getLocalBlockRegister(node);
+ // javascript handler; unwrap exception and GOTO to javascript
+ // catch area.
+ if (catchTarget != null) {
+ // get the label to goto
+ int catchLabel = catchTarget.labelId();
+
+ generateCatchBlock(JAVASCRIPT_EXCEPTION, savedVariableObject,
+ catchLabel, startLabel, exceptionLocal);
+ /*
+ * catch WrappedExceptions, see if they are wrapped
+ * JavaScriptExceptions. Otherwise, rethrow.
+ */
+ generateCatchBlock(EVALUATOR_EXCEPTION, savedVariableObject,
+ catchLabel, startLabel, exceptionLocal);
+
+ /*
+ we also need to catch EcmaErrors and feed the
+ associated error object to the handler
+ */
+ generateCatchBlock(ECMAERROR_EXCEPTION, savedVariableObject,
+ catchLabel, startLabel, exceptionLocal);
+
+ Context cx = Context.getCurrentContext();
+ if (cx != null &&
+ cx.hasFeature(Context.FEATURE_ENHANCED_JAVA_ACCESS))
+ {
+ generateCatchBlock(THROWABLE_EXCEPTION, savedVariableObject,
+ catchLabel, startLabel, exceptionLocal);
+ }
+ }
+
+ // finally handler; catch all exceptions, store to a local; JSR to
+ // the finally, then re-throw.
+ if (finallyTarget != null) {
+ int finallyHandler = cfw.acquireLabel();
+ cfw.markHandler(finallyHandler);
+ cfw.addAStore(exceptionLocal);
+
+ // reset the variable object local
+ cfw.addALoad(savedVariableObject);
+ cfw.addAStore(variableObjectLocal);
+
+ // get the label to JSR to
+ int finallyLabel = finallyTarget.labelId();
+ if (isGenerator)
+ addGotoWithReturn(finallyTarget);
+ else
+ cfw.add(ByteCode.JSR, finallyLabel);
+
+ // rethrow
+ cfw.addALoad(exceptionLocal);
+ if (isGenerator)
+ cfw.add(ByteCode.CHECKCAST, "java/lang/Throwable");
+ cfw.add(ByteCode.ATHROW);
+
+ // mark the handler
+ cfw.addExceptionHandler(startLabel, finallyLabel,
+ finallyHandler, null); // catch any
+ }
+ releaseWordLocal(savedVariableObject);
+ cfw.markLabel(realEnd);
+ }
+
+ private static final int JAVASCRIPT_EXCEPTION = 0;
+ private static final int EVALUATOR_EXCEPTION = 1;
+ private static final int ECMAERROR_EXCEPTION = 2;
+ private static final int THROWABLE_EXCEPTION = 3;
+
+ private void generateCatchBlock(int exceptionType,
+ short savedVariableObject,
+ int catchLabel, int startLabel,
+ int exceptionLocal)
+ {
+ int handler = cfw.acquireLabel();
+ cfw.markHandler(handler);
+
+ // MS JVM gets cranky if the exception object is left on the stack
+ cfw.addAStore(exceptionLocal);
+
+ // reset the variable object local
+ cfw.addALoad(savedVariableObject);
+ cfw.addAStore(variableObjectLocal);
+
+ String exceptionName;
+ if (exceptionType == JAVASCRIPT_EXCEPTION) {
+ exceptionName = "org/mozilla/javascript/JavaScriptException";
+ } else if (exceptionType == EVALUATOR_EXCEPTION) {
+ exceptionName = "org/mozilla/javascript/EvaluatorException";
+ } else if (exceptionType == ECMAERROR_EXCEPTION) {
+ exceptionName = "org/mozilla/javascript/EcmaError";
+ } else if (exceptionType == THROWABLE_EXCEPTION) {
+ exceptionName = "java/lang/Throwable";
+ } else {
+ throw Kit.codeBug();
+ }
+
+ // mark the handler
+ cfw.addExceptionHandler(startLabel, catchLabel, handler,
+ exceptionName);
+
+ cfw.add(ByteCode.GOTO, catchLabel);
+ }
+
+
+ private boolean generateSaveLocals(Node node)
+ {
+ int count = 0;
+ for (int i = 0; i < firstFreeLocal; i++) {
+ if (locals[i] != 0)
+ count++;
+ }
+
+ if (count == 0) {
+ ((FunctionNode)scriptOrFn).addLiveLocals(node, null);
+ return false;
+ }
+
+ // calculate the max locals
+ maxLocals = maxLocals > count ? maxLocals : count;
+
+ // create a locals list
+ int[] ls = new int[count];
+ int s = 0;
+ for (int i = 0; i < firstFreeLocal; i++) {
+ if (locals[i] != 0) {
+ ls[s] = i;
+ s++;
+ }
+ }
+
+ // save the locals
+ ((FunctionNode)scriptOrFn).addLiveLocals(node, ls);
+
+ // save locals
+ generateGetGeneratorLocalsState();
+ for (int i = 0; i < count; i++) {
+ cfw.add(ByteCode.DUP);
+ cfw.addLoadConstant(i);
+ cfw.addALoad(ls[i]);
+ cfw.add(ByteCode.AASTORE);
+ }
+ // pop the array off the stack
+ cfw.add(ByteCode.POP);
+
+ return true;
+ }
+
+ private void visitSwitch(Node.Jump switchNode, Node child)
+ {
+ // See comments in IRFactory.createSwitch() for description
+ // of SWITCH node
+
+ generateExpression(child, switchNode);
+ // save selector value
+ short selector = getNewWordLocal();
+ cfw.addAStore(selector);
+
+ for (Node.Jump caseNode = (Node.Jump)child.getNext();
+ caseNode != null;
+ caseNode = (Node.Jump)caseNode.getNext())
+ {
+ if (caseNode.getType() != Token.CASE)
+ throw Codegen.badTree();
+ Node test = caseNode.getFirstChild();
+ generateExpression(test, caseNode);
+ cfw.addALoad(selector);
+ addScriptRuntimeInvoke("shallowEq",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +")Z");
+ addGoto(caseNode.target, ByteCode.IFNE);
+ }
+ releaseWordLocal(selector);
+ }
+
+ private void visitTypeofname(Node node)
+ {
+ if (hasVarsInRegs) {
+ int varIndex = fnCurrent.fnode.getIndexForNameNode(node);
+ if (varIndex >= 0) {
+ if (fnCurrent.isNumberVar(varIndex)) {
+ cfw.addPush("number");
+ } else if (varIsDirectCallParameter(varIndex)) {
+ int dcp_register = varRegisters[varIndex];
+ cfw.addALoad(dcp_register);
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Void", "TYPE",
+ "Ljava/lang/Class;");
+ int isNumberLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
+ short stack = cfw.getStackTop();
+ cfw.addALoad(dcp_register);
+ addScriptRuntimeInvoke("typeof",
+ "(Ljava/lang/Object;"
+ +")Ljava/lang/String;");
+ int beyond = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(isNumberLabel, stack);
+ cfw.addPush("number");
+ cfw.markLabel(beyond);
+ } else {
+ cfw.addALoad(varRegisters[varIndex]);
+ addScriptRuntimeInvoke("typeof",
+ "(Ljava/lang/Object;"
+ +")Ljava/lang/String;");
+ }
+ return;
+ }
+ }
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(node.getString());
+ addScriptRuntimeInvoke("typeofName",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +")Ljava/lang/String;");
+ }
+
+ /**
+ * Save the current code offset. This saved code offset is used to
+ * compute instruction counts in subsequent calls to
+ * {@link #addInstructionCount}.
+ */
+ private void saveCurrentCodeOffset() {
+ savedCodeOffset = cfw.getCurrentCodeOffset();
+ }
+
+ /**
+ * Generate calls to ScriptRuntime.addInstructionCount to keep track of
+ * executed instructions and call <code>observeInstructionCount()</code>
+ * if a threshold is exceeded.
+ */
+ private void addInstructionCount() {
+ int count = cfw.getCurrentCodeOffset() - savedCodeOffset;
+ if (count == 0)
+ return;
+ cfw.addALoad(contextLocal);
+ cfw.addPush(count);
+ addScriptRuntimeInvoke("addInstructionCount",
+ "(Lorg/mozilla/javascript/Context;"
+ +"I)V");
+ }
+
+ private void visitIncDec(Node node)
+ {
+ int incrDecrMask = node.getExistingIntProp(Node.INCRDECR_PROP);
+ Node child = node.getFirstChild();
+ switch (child.getType()) {
+ case Token.GETVAR:
+ if (!hasVarsInRegs) Kit.codeBug();
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
+ boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
+ int varIndex = fnCurrent.getVarIndex(child);
+ short reg = varRegisters[varIndex];
+ int offset = varIsDirectCallParameter(varIndex) ? 1 : 0;
+ cfw.addDLoad(reg + offset);
+ if (post) {
+ cfw.add(ByteCode.DUP2);
+ }
+ cfw.addPush(1.0);
+ if ((incrDecrMask & Node.DECR_FLAG) == 0) {
+ cfw.add(ByteCode.DADD);
+ } else {
+ cfw.add(ByteCode.DSUB);
+ }
+ if (!post) {
+ cfw.add(ByteCode.DUP2);
+ }
+ cfw.addDStore(reg + offset);
+ } else {
+ boolean post = ((incrDecrMask & Node.POST_FLAG) != 0);
+ int varIndex = fnCurrent.getVarIndex(child);
+ short reg = varRegisters[varIndex];
+ cfw.addALoad(reg);
+ if (post) {
+ cfw.add(ByteCode.DUP);
+ }
+ addObjectToDouble();
+ cfw.addPush(1.0);
+ if ((incrDecrMask & Node.DECR_FLAG) == 0) {
+ cfw.add(ByteCode.DADD);
+ } else {
+ cfw.add(ByteCode.DSUB);
+ }
+ addDoubleWrap();
+ if (!post) {
+ cfw.add(ByteCode.DUP);
+ }
+ cfw.addAStore(reg);
+ break;
+ }
+ break;
+ case Token.NAME:
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(child.getString()); // push name
+ cfw.addALoad(contextLocal);
+ cfw.addPush(incrDecrMask);
+ addScriptRuntimeInvoke("nameIncrDecr",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I)Ljava/lang/Object;");
+ break;
+ case Token.GETPROPNOWARN:
+ throw Kit.codeBug();
+ case Token.GETPROP: {
+ Node getPropChild = child.getFirstChild();
+ generateExpression(getPropChild, node);
+ generateExpression(getPropChild.getNext(), node);
+ cfw.addALoad(contextLocal);
+ cfw.addPush(incrDecrMask);
+ addScriptRuntimeInvoke("propIncrDecr",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I)Ljava/lang/Object;");
+ break;
+ }
+ case Token.GETELEM: {
+ Node elemChild = child.getFirstChild();
+ generateExpression(elemChild, node);
+ generateExpression(elemChild.getNext(), node);
+ cfw.addALoad(contextLocal);
+ cfw.addPush(incrDecrMask);
+ if (elemChild.getNext().getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
+ addOptRuntimeInvoke("elemIncrDecr",
+ "(Ljava/lang/Object;"
+ +"D"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I"
+ +")Ljava/lang/Object;");
+ } else {
+ addScriptRuntimeInvoke("elemIncrDecr",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I"
+ +")Ljava/lang/Object;");
+ }
+ break;
+ }
+ case Token.GET_REF: {
+ Node refChild = child.getFirstChild();
+ generateExpression(refChild, node);
+ cfw.addALoad(contextLocal);
+ cfw.addPush(incrDecrMask);
+ addScriptRuntimeInvoke(
+ "refIncrDecr",
+ "(Lorg/mozilla/javascript/Ref;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"I)Ljava/lang/Object;");
+ break;
+ }
+ default:
+ Codegen.badTree();
+ }
+ }
+
+ private static boolean isArithmeticNode(Node node)
+ {
+ int type = node.getType();
+ return (type == Token.SUB)
+ || (type == Token.MOD)
+ || (type == Token.DIV)
+ || (type == Token.MUL);
+ }
+
+ private void visitArithmetic(Node node, int opCode, Node child,
+ Node parent)
+ {
+ int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
+ if (childNumberFlag != -1) {
+ generateExpression(child, node);
+ generateExpression(child.getNext(), node);
+ cfw.add(opCode);
+ }
+ else {
+ boolean childOfArithmetic = isArithmeticNode(parent);
+ generateExpression(child, node);
+ if (!isArithmeticNode(child))
+ addObjectToDouble();
+ generateExpression(child.getNext(), node);
+ if (!isArithmeticNode(child.getNext()))
+ addObjectToDouble();
+ cfw.add(opCode);
+ if (!childOfArithmetic) {
+ addDoubleWrap();
+ }
+ }
+ }
+
+ private void visitBitOp(Node node, int type, Node child)
+ {
+ int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
+ generateExpression(child, node);
+
+ // special-case URSH; work with the target arg as a long, so
+ // that we can return a 32-bit unsigned value, and call
+ // toUint32 instead of toInt32.
+ if (type == Token.URSH) {
+ addScriptRuntimeInvoke("toUint32", "(Ljava/lang/Object;)J");
+ generateExpression(child.getNext(), node);
+ addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
+ // Looks like we need to explicitly mask the shift to 5 bits -
+ // LUSHR takes 6 bits.
+ cfw.addPush(31);
+ cfw.add(ByteCode.IAND);
+ cfw.add(ByteCode.LUSHR);
+ cfw.add(ByteCode.L2D);
+ addDoubleWrap();
+ return;
+ }
+ if (childNumberFlag == -1) {
+ addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
+ generateExpression(child.getNext(), node);
+ addScriptRuntimeInvoke("toInt32", "(Ljava/lang/Object;)I");
+ }
+ else {
+ addScriptRuntimeInvoke("toInt32", "(D)I");
+ generateExpression(child.getNext(), node);
+ addScriptRuntimeInvoke("toInt32", "(D)I");
+ }
+ switch (type) {
+ case Token.BITOR:
+ cfw.add(ByteCode.IOR);
+ break;
+ case Token.BITXOR:
+ cfw.add(ByteCode.IXOR);
+ break;
+ case Token.BITAND:
+ cfw.add(ByteCode.IAND);
+ break;
+ case Token.RSH:
+ cfw.add(ByteCode.ISHR);
+ break;
+ case Token.LSH:
+ cfw.add(ByteCode.ISHL);
+ break;
+ default:
+ throw Codegen.badTree();
+ }
+ cfw.add(ByteCode.I2D);
+ if (childNumberFlag == -1) {
+ addDoubleWrap();
+ }
+ }
+
+ private int nodeIsDirectCallParameter(Node node)
+ {
+ if (node.getType() == Token.GETVAR
+ && inDirectCallFunction && !itsForcedObjectParameters)
+ {
+ int varIndex = fnCurrent.getVarIndex(node);
+ if (fnCurrent.isParameter(varIndex)) {
+ return varRegisters[varIndex];
+ }
+ }
+ return -1;
+ }
+
+ private boolean varIsDirectCallParameter(int varIndex)
+ {
+ return fnCurrent.isParameter(varIndex)
+ && inDirectCallFunction && !itsForcedObjectParameters;
+ }
+
+ private void genSimpleCompare(int type, int trueGOTO, int falseGOTO)
+ {
+ if (trueGOTO == -1) throw Codegen.badTree();
+ switch (type) {
+ case Token.LE :
+ cfw.add(ByteCode.DCMPG);
+ cfw.add(ByteCode.IFLE, trueGOTO);
+ break;
+ case Token.GE :
+ cfw.add(ByteCode.DCMPL);
+ cfw.add(ByteCode.IFGE, trueGOTO);
+ break;
+ case Token.LT :
+ cfw.add(ByteCode.DCMPG);
+ cfw.add(ByteCode.IFLT, trueGOTO);
+ break;
+ case Token.GT :
+ cfw.add(ByteCode.DCMPL);
+ cfw.add(ByteCode.IFGT, trueGOTO);
+ break;
+ default :
+ throw Codegen.badTree();
+
+ }
+ if (falseGOTO != -1)
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ }
+
+ private void visitIfJumpRelOp(Node node, Node child,
+ int trueGOTO, int falseGOTO)
+ {
+ if (trueGOTO == -1 || falseGOTO == -1) throw Codegen.badTree();
+ int type = node.getType();
+ Node rChild = child.getNext();
+ if (type == Token.INSTANCEOF || type == Token.IN) {
+ generateExpression(child, node);
+ generateExpression(rChild, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ (type == Token.INSTANCEOF) ? "instanceOf" : "in",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Z");
+ cfw.add(ByteCode.IFNE, trueGOTO);
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ return;
+ }
+ int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
+ int left_dcp_register = nodeIsDirectCallParameter(child);
+ int right_dcp_register = nodeIsDirectCallParameter(rChild);
+ if (childNumberFlag != -1) {
+ // Force numeric context on both parameters and optimize
+ // direct call case as Optimizer currently does not handle it
+
+ if (childNumberFlag != Node.RIGHT) {
+ // Left already has number content
+ generateExpression(child, node);
+ } else if (left_dcp_register != -1) {
+ dcpLoadAsNumber(left_dcp_register);
+ } else {
+ generateExpression(child, node);
+ addObjectToDouble();
+ }
+
+ if (childNumberFlag != Node.LEFT) {
+ // Right already has number content
+ generateExpression(rChild, node);
+ } else if (right_dcp_register != -1) {
+ dcpLoadAsNumber(right_dcp_register);
+ } else {
+ generateExpression(rChild, node);
+ addObjectToDouble();
+ }
+
+ genSimpleCompare(type, trueGOTO, falseGOTO);
+
+ } else {
+ if (left_dcp_register != -1 && right_dcp_register != -1) {
+ // Generate code to dynamically check for number content
+ // if both operands are dcp
+ short stack = cfw.getStackTop();
+ int leftIsNotNumber = cfw.acquireLabel();
+ cfw.addALoad(left_dcp_register);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ cfw.add(ByteCode.IF_ACMPNE, leftIsNotNumber);
+ cfw.addDLoad(left_dcp_register + 1);
+ dcpLoadAsNumber(right_dcp_register);
+ genSimpleCompare(type, trueGOTO, falseGOTO);
+ if (stack != cfw.getStackTop()) throw Codegen.badTree();
+
+ cfw.markLabel(leftIsNotNumber);
+ int rightIsNotNumber = cfw.acquireLabel();
+ cfw.addALoad(right_dcp_register);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ cfw.add(ByteCode.IF_ACMPNE, rightIsNotNumber);
+ cfw.addALoad(left_dcp_register);
+ addObjectToDouble();
+ cfw.addDLoad(right_dcp_register + 1);
+ genSimpleCompare(type, trueGOTO, falseGOTO);
+ if (stack != cfw.getStackTop()) throw Codegen.badTree();
+
+ cfw.markLabel(rightIsNotNumber);
+ // Load both register as objects to call generic cmp_*
+ cfw.addALoad(left_dcp_register);
+ cfw.addALoad(right_dcp_register);
+
+ } else {
+ generateExpression(child, node);
+ generateExpression(rChild, node);
+ }
+
+ if (type == Token.GE || type == Token.GT) {
+ cfw.add(ByteCode.SWAP);
+ }
+ String routine = ((type == Token.LT)
+ || (type == Token.GT)) ? "cmp_LT" : "cmp_LE";
+ addScriptRuntimeInvoke(routine,
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +")Z");
+ cfw.add(ByteCode.IFNE, trueGOTO);
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ }
+ }
+
+ private void visitIfJumpEqOp(Node node, Node child,
+ int trueGOTO, int falseGOTO)
+ {
+ if (trueGOTO == -1 || falseGOTO == -1) throw Codegen.badTree();
+
+ short stackInitial = cfw.getStackTop();
+ int type = node.getType();
+ Node rChild = child.getNext();
+
+ // Optimize if one of operands is null
+ if (child.getType() == Token.NULL || rChild.getType() == Token.NULL) {
+ // eq is symmetric in this case
+ if (child.getType() == Token.NULL) {
+ child = rChild;
+ }
+ generateExpression(child, node);
+ if (type == Token.SHEQ || type == Token.SHNE) {
+ int testCode = (type == Token.SHEQ)
+ ? ByteCode.IFNULL : ByteCode.IFNONNULL;
+ cfw.add(testCode, trueGOTO);
+ } else {
+ if (type != Token.EQ) {
+ // swap false/true targets for !=
+ if (type != Token.NE) throw Codegen.badTree();
+ int tmp = trueGOTO;
+ trueGOTO = falseGOTO;
+ falseGOTO = tmp;
+ }
+ cfw.add(ByteCode.DUP);
+ int undefCheckLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IFNONNULL, undefCheckLabel);
+ short stack = cfw.getStackTop();
+ cfw.add(ByteCode.POP);
+ cfw.add(ByteCode.GOTO, trueGOTO);
+ cfw.markLabel(undefCheckLabel, stack);
+ Codegen.pushUndefined(cfw);
+ cfw.add(ByteCode.IF_ACMPEQ, trueGOTO);
+ }
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ } else {
+ int child_dcp_register = nodeIsDirectCallParameter(child);
+ if (child_dcp_register != -1
+ && rChild.getType() == Token.TO_OBJECT)
+ {
+ Node convertChild = rChild.getFirstChild();
+ if (convertChild.getType() == Token.NUMBER) {
+ cfw.addALoad(child_dcp_register);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ int notNumbersLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPNE, notNumbersLabel);
+ cfw.addDLoad(child_dcp_register + 1);
+ cfw.addPush(convertChild.getDouble());
+ cfw.add(ByteCode.DCMPL);
+ if (type == Token.EQ)
+ cfw.add(ByteCode.IFEQ, trueGOTO);
+ else
+ cfw.add(ByteCode.IFNE, trueGOTO);
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ cfw.markLabel(notNumbersLabel);
+ // fall thru into generic handling
+ }
+ }
+
+ generateExpression(child, node);
+ generateExpression(rChild, node);
+
+ String name;
+ int testCode;
+ switch (type) {
+ case Token.EQ:
+ name = "eq";
+ testCode = ByteCode.IFNE;
+ break;
+ case Token.NE:
+ name = "eq";
+ testCode = ByteCode.IFEQ;
+ break;
+ case Token.SHEQ:
+ name = "shallowEq";
+ testCode = ByteCode.IFNE;
+ break;
+ case Token.SHNE:
+ name = "shallowEq";
+ testCode = ByteCode.IFEQ;
+ break;
+ default:
+ throw Codegen.badTree();
+ }
+ addScriptRuntimeInvoke(name,
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +")Z");
+ cfw.add(testCode, trueGOTO);
+ cfw.add(ByteCode.GOTO, falseGOTO);
+ }
+ if (stackInitial != cfw.getStackTop()) throw Codegen.badTree();
+ }
+
+ private void visitSetName(Node node, Node child)
+ {
+ String name = node.getFirstChild().getString();
+ while (child != null) {
+ generateExpression(child, node);
+ child = child.getNext();
+ }
+ cfw.addALoad(contextLocal);
+ cfw.addALoad(variableObjectLocal);
+ cfw.addPush(name);
+ addScriptRuntimeInvoke(
+ "setName",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +")Ljava/lang/Object;");
+ }
+
+ private void visitSetConst(Node node, Node child)
+ {
+ String name = node.getFirstChild().getString();
+ while (child != null) {
+ generateExpression(child, node);
+ child = child.getNext();
+ }
+ cfw.addALoad(contextLocal);
+ cfw.addPush(name);
+ addScriptRuntimeInvoke(
+ "setConst",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +"Ljava/lang/String;"
+ +")Ljava/lang/Object;");
+ }
+
+ private void visitGetVar(Node node)
+ {
+ if (!hasVarsInRegs) Kit.codeBug();
+ int varIndex = fnCurrent.getVarIndex(node);
+ short reg = varRegisters[varIndex];
+ if (varIsDirectCallParameter(varIndex)) {
+ // Remember that here the isNumber flag means that we
+ // want to use the incoming parameter in a Number
+ // context, so test the object type and convert the
+ // value as necessary.
+ if (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1) {
+ dcpLoadAsNumber(reg);
+ } else {
+ dcpLoadAsObject(reg);
+ }
+ } else if (fnCurrent.isNumberVar(varIndex)) {
+ cfw.addDLoad(reg);
+ } else {
+ cfw.addALoad(reg);
+ }
+ }
+
+ private void visitSetVar(Node node, Node child, boolean needValue)
+ {
+ if (!hasVarsInRegs) Kit.codeBug();
+ int varIndex = fnCurrent.getVarIndex(node);
+ generateExpression(child.getNext(), node);
+ boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
+ short reg = varRegisters[varIndex];
+ boolean [] constDeclarations = fnCurrent.fnode.getParamAndVarConst();
+ if (constDeclarations[varIndex]) {
+ if (!needValue) {
+ if (isNumber)
+ cfw.add(ByteCode.POP2);
+ else
+ cfw.add(ByteCode.POP);
+ }
+ }
+ else if (varIsDirectCallParameter(varIndex)) {
+ if (isNumber) {
+ if (needValue) cfw.add(ByteCode.DUP2);
+ cfw.addALoad(reg);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ int isNumberLabel = cfw.acquireLabel();
+ int beyond = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
+ short stack = cfw.getStackTop();
+ addDoubleWrap();
+ cfw.addAStore(reg);
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(isNumberLabel, stack);
+ cfw.addDStore(reg + 1);
+ cfw.markLabel(beyond);
+ }
+ else {
+ if (needValue) cfw.add(ByteCode.DUP);
+ cfw.addAStore(reg);
+ }
+ } else {
+ boolean isNumberVar = fnCurrent.isNumberVar(varIndex);
+ if (isNumber) {
+ if (isNumberVar) {
+ cfw.addDStore(reg);
+ if (needValue) cfw.addDLoad(reg);
+ } else {
+ if (needValue) cfw.add(ByteCode.DUP2);
+ // Cannot save number in variable since !isNumberVar,
+ // so convert to object
+ addDoubleWrap();
+ cfw.addAStore(reg);
+ }
+ } else {
+ if (isNumberVar) Kit.codeBug();
+ cfw.addAStore(reg);
+ if (needValue) cfw.addALoad(reg);
+ }
+ }
+ }
+
+ private void visitSetConstVar(Node node, Node child, boolean needValue)
+ {
+ if (!hasVarsInRegs) Kit.codeBug();
+ int varIndex = fnCurrent.getVarIndex(node);
+ generateExpression(child.getNext(), node);
+ boolean isNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
+ short reg = varRegisters[varIndex];
+ int beyond = cfw.acquireLabel();
+ int noAssign = cfw.acquireLabel();
+ if (isNumber) {
+ cfw.addILoad(reg + 2);
+ cfw.add(ByteCode.IFNE, noAssign);
+ short stack = cfw.getStackTop();
+ cfw.addPush(1);
+ cfw.addIStore(reg + 2);
+ cfw.addDStore(reg);
+ if (needValue) {
+ cfw.addDLoad(reg);
+ cfw.markLabel(noAssign, stack);
+ } else {
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(noAssign, stack);
+ cfw.add(ByteCode.POP2);
+ }
+ }
+ else {
+ cfw.addILoad(reg + 1);
+ cfw.add(ByteCode.IFNE, noAssign);
+ short stack = cfw.getStackTop();
+ cfw.addPush(1);
+ cfw.addIStore(reg + 1);
+ cfw.addAStore(reg);
+ if (needValue) {
+ cfw.addALoad(reg);
+ cfw.markLabel(noAssign, stack);
+ } else {
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(noAssign, stack);
+ cfw.add(ByteCode.POP);
+ }
+ }
+ cfw.markLabel(beyond);
+ }
+
+ private void visitGetProp(Node node, Node child)
+ {
+ generateExpression(child, node); // object
+ Node nameChild = child.getNext();
+ generateExpression(nameChild, node); // the name
+ if (node.getType() == Token.GETPROPNOWARN) {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectPropNoWarn",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ return;
+ }
+ /*
+ for 'this.foo' we call getObjectProp(Scriptable...) which can
+ skip some casting overhead.
+ */
+ int childType = child.getType();
+ if (childType == Token.THIS && nameChild.getType() == Token.STRING) {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectProp",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ } else {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectProp",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ }
+
+ private void visitSetProp(int type, Node node, Node child)
+ {
+ Node objectChild = child;
+ generateExpression(child, node);
+ child = child.getNext();
+ if (type == Token.SETPROP_OP) {
+ cfw.add(ByteCode.DUP);
+ }
+ Node nameChild = child;
+ generateExpression(child, node);
+ child = child.getNext();
+ if (type == Token.SETPROP_OP) {
+ // stack: ... object object name -> ... object name object name
+ cfw.add(ByteCode.DUP_X1);
+ //for 'this.foo += ...' we call thisGet which can skip some
+ //casting overhead.
+ if (objectChild.getType() == Token.THIS
+ && nameChild.getType() == Token.STRING)
+ {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectProp",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ } else {
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectProp",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ }
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "setObjectProp",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/String;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+
+ private void visitSetElem(int type, Node node, Node child)
+ {
+ generateExpression(child, node);
+ child = child.getNext();
+ if (type == Token.SETELEM_OP) {
+ cfw.add(ByteCode.DUP);
+ }
+ generateExpression(child, node);
+ child = child.getNext();
+ boolean indexIsNumber = (node.getIntProp(Node.ISNUMBER_PROP, -1) != -1);
+ if (type == Token.SETELEM_OP) {
+ if (indexIsNumber) {
+ // stack: ... object object number
+ // -> ... object number object number
+ cfw.add(ByteCode.DUP2_X1);
+ cfw.addALoad(contextLocal);
+ addOptRuntimeInvoke(
+ "getObjectIndex",
+ "(Ljava/lang/Object;D"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ } else {
+ // stack: ... object object indexObject
+ // -> ... object indexObject object indexObject
+ cfw.add(ByteCode.DUP_X1);
+ cfw.addALoad(contextLocal);
+ addScriptRuntimeInvoke(
+ "getObjectElem",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ }
+ generateExpression(child, node);
+ cfw.addALoad(contextLocal);
+ if (indexIsNumber) {
+ addScriptRuntimeInvoke(
+ "setObjectIndex",
+ "(Ljava/lang/Object;"
+ +"D"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ } else {
+ addScriptRuntimeInvoke(
+ "setObjectElem",
+ "(Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Context;"
+ +")Ljava/lang/Object;");
+ }
+ }
+
+ private void visitDotQuery(Node node, Node child)
+ {
+ updateLineNumber(node);
+ generateExpression(child, node);
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke("enterDotQuery",
+ "(Ljava/lang/Object;"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+
+ // add push null/pop with label in between to simplify code for loop
+ // continue when it is necessary to pop the null result from
+ // updateDotQuery
+ cfw.add(ByteCode.ACONST_NULL);
+ int queryLoopStart = cfw.acquireLabel();
+ cfw.markLabel(queryLoopStart); // loop continue jumps here
+ cfw.add(ByteCode.POP);
+
+ generateExpression(child.getNext(), node);
+ addScriptRuntimeInvoke("toBoolean", "(Ljava/lang/Object;)Z");
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke("updateDotQuery",
+ "(Z"
+ +"Lorg/mozilla/javascript/Scriptable;"
+ +")Ljava/lang/Object;");
+ cfw.add(ByteCode.DUP);
+ cfw.add(ByteCode.IFNULL, queryLoopStart);
+ // stack: ... non_null_result_of_updateDotQuery
+ cfw.addALoad(variableObjectLocal);
+ addScriptRuntimeInvoke("leaveDotQuery",
+ "(Lorg/mozilla/javascript/Scriptable;"
+ +")Lorg/mozilla/javascript/Scriptable;");
+ cfw.addAStore(variableObjectLocal);
+ }
+
+ private int getLocalBlockRegister(Node node)
+ {
+ Node localBlock = (Node)node.getProp(Node.LOCAL_BLOCK_PROP);
+ int localSlot = localBlock.getExistingIntProp(Node.LOCAL_PROP);
+ return localSlot;
+ }
+
+ private void dcpLoadAsNumber(int dcp_register)
+ {
+ cfw.addALoad(dcp_register);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ int isNumberLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
+ short stack = cfw.getStackTop();
+ cfw.addALoad(dcp_register);
+ addObjectToDouble();
+ int beyond = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(isNumberLabel, stack);
+ cfw.addDLoad(dcp_register + 1);
+ cfw.markLabel(beyond);
+ }
+
+ private void dcpLoadAsObject(int dcp_register)
+ {
+ cfw.addALoad(dcp_register);
+ cfw.add(ByteCode.GETSTATIC,
+ "java/lang/Void",
+ "TYPE",
+ "Ljava/lang/Class;");
+ int isNumberLabel = cfw.acquireLabel();
+ cfw.add(ByteCode.IF_ACMPEQ, isNumberLabel);
+ short stack = cfw.getStackTop();
+ cfw.addALoad(dcp_register);
+ int beyond = cfw.acquireLabel();
+ cfw.add(ByteCode.GOTO, beyond);
+ cfw.markLabel(isNumberLabel, stack);
+ cfw.addDLoad(dcp_register + 1);
+ addDoubleWrap();
+ cfw.markLabel(beyond);
+ }
+
+ private void addGoto(Node target, int jumpcode)
+ {
+ int targetLabel = getTargetLabel(target);
+ cfw.add(jumpcode, targetLabel);
+ }
+
+ private void addObjectToDouble()
+ {
+ addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
+ }
+
+ private void addNewObjectArray(int size)
+ {
+ if (size == 0) {
+ if (itsZeroArgArray >= 0) {
+ cfw.addALoad(itsZeroArgArray);
+ } else {
+ cfw.add(ByteCode.GETSTATIC,
+ "org/mozilla/javascript/ScriptRuntime",
+ "emptyArgs", "[Ljava/lang/Object;");
+ }
+ } else {
+ cfw.addPush(size);
+ cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
+ }
+ }
+
+ private void addScriptRuntimeInvoke(String methodName,
+ String methodSignature)
+ {
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org.mozilla.javascript.ScriptRuntime",
+ methodName,
+ methodSignature);
+ }
+
+ private void addOptRuntimeInvoke(String methodName,
+ String methodSignature)
+ {
+ cfw.addInvoke(ByteCode.INVOKESTATIC,
+ "org/mozilla/javascript/optimizer/OptRuntime",
+ methodName,
+ methodSignature);
+ }
+
+ private void addJumpedBooleanWrap(int trueLabel, int falseLabel)
+ {
+ cfw.markLabel(falseLabel);
+ int skip = cfw.acquireLabel();
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "FALSE", "Ljava/lang/Boolean;");
+ cfw.add(ByteCode.GOTO, skip);
+ cfw.markLabel(trueLabel);
+ cfw.add(ByteCode.GETSTATIC, "java/lang/Boolean",
+ "TRUE", "Ljava/lang/Boolean;");
+ cfw.markLabel(skip);
+ cfw.adjustStackTop(-1); // only have 1 of true/false
+ }
+
+ private void addDoubleWrap()
+ {
+ addOptRuntimeInvoke("wrapDouble", "(D)Ljava/lang/Double;");
+ }
+
+ /**
+ * Const locals use an extra slot to hold the has-been-assigned-once flag at
+ * runtime.
+ * @param isConst true iff the variable is const
+ * @return the register for the word pair (double/long)
+ */
+ private short getNewWordPairLocal(boolean isConst)
+ {
+ short result = getConsecutiveSlots(2, isConst);
+ if (result < (MAX_LOCALS - 1)) {
+ locals[result] = 1;
+ locals[result + 1] = 1;
+ if (isConst)
+ locals[result + 2] = 1;
+ if (result == firstFreeLocal) {
+ for (int i = firstFreeLocal + 2; i < MAX_LOCALS; i++) {
+ if (locals[i] == 0) {
+ firstFreeLocal = (short) i;
+ if (localsMax < firstFreeLocal)
+ localsMax = firstFreeLocal;
+ return result;
+ }
+ }
+ }
+ else {
+ return result;
+ }
+ }
+ throw Context.reportRuntimeError("Program too complex " +
+ "(out of locals)");
+ }
+
+ private short getNewWordLocal(boolean isConst)
+ {
+ short result = getConsecutiveSlots(1, isConst);
+ if (result < (MAX_LOCALS - 1)) {
+ locals[result] = 1;
+ if (isConst)
+ locals[result + 1] = 1;
+ if (result == firstFreeLocal) {
+ for (int i = firstFreeLocal + 2; i < MAX_LOCALS; i++) {
+ if (locals[i] == 0) {
+ firstFreeLocal = (short) i;
+ if (localsMax < firstFreeLocal)
+ localsMax = firstFreeLocal;
+ return result;
+ }
+ }
+ }
+ else {
+ return result;
+ }
+ }
+ throw Context.reportRuntimeError("Program too complex " +
+ "(out of locals)");
+ }
+
+ private short getNewWordLocal()
+ {
+ short result = firstFreeLocal;
+ locals[result] = 1;
+ for (int i = firstFreeLocal + 1; i < MAX_LOCALS; i++) {
+ if (locals[i] == 0) {
+ firstFreeLocal = (short) i;
+ if (localsMax < firstFreeLocal)
+ localsMax = firstFreeLocal;
+ return result;
+ }
+ }
+ throw Context.reportRuntimeError("Program too complex " +
+ "(out of locals)");
+ }
+
+ private short getConsecutiveSlots(int count, boolean isConst) {
+ if (isConst)
+ count++;
+ short result = firstFreeLocal;
+ while (true) {
+ if (result >= (MAX_LOCALS - 1))
+ break;
+ int i;
+ for (i = 0; i < count; i++)
+ if (locals[result + i] != 0)
+ break;
+ if (i >= count)
+ break;
+ result++;
+ }
+ return result;
+ }
+
+ // This is a valid call only for a local that is allocated by default.
+ private void incReferenceWordLocal(short local)
+ {
+ locals[local]++;
+ }
+
+ // This is a valid call only for a local that is allocated by default.
+ private void decReferenceWordLocal(short local)
+ {
+ locals[local]--;
+ }
+
+ private void releaseWordLocal(short local)
+ {
+ if (local < firstFreeLocal)
+ firstFreeLocal = local;
+ locals[local] = 0;
+ }
+
+
+ static final int GENERATOR_TERMINATE = -1;
+ static final int GENERATOR_START = 0;
+ static final int GENERATOR_YIELD_START = 1;
+
+ ClassFileWriter cfw;
+ Codegen codegen;
+ CompilerEnvirons compilerEnv;
+ ScriptOrFnNode scriptOrFn;
+ public int scriptOrFnIndex;
+ private int savedCodeOffset;
+
+ private OptFunctionNode fnCurrent;
+ private boolean isTopLevel;
+
+ private static final int MAX_LOCALS = 256;
+ private int[] locals;
+ private short firstFreeLocal;
+ private short localsMax;
+
+ private int itsLineNumber;
+
+ private boolean hasVarsInRegs;
+ private short[] varRegisters;
+ private boolean inDirectCallFunction;
+ private boolean itsForcedObjectParameters;
+ private int enterAreaStartLabel;
+ private int epilogueLabel;
+
+ // special known locals. If you add a new local here, be sure
+ // to initialize it to -1 in initBodyGeneration
+ private short variableObjectLocal;
+ private short popvLocal;
+ private short contextLocal;
+ private short argsLocal;
+ private short operationLocal;
+ private short thisObjLocal;
+ private short funObjLocal;
+ private short itsZeroArgArray;
+ private short itsOneArgArray;
+ private short scriptRegexpLocal;
+ private short generatorStateLocal;
+
+ private boolean isGenerator;
+ private int generatorSwitch;
+ private int maxLocals = 0;
+ private int maxStack = 0;
+
+ private Hashtable finallys;
+
+ class FinallyReturnPoint {
+ public ArrayList jsrPoints = new ArrayList();
+ public int tableLabel = 0;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java
new file mode 100644
index 0000000..607e649
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/DataFlowBitSet.java
@@ -0,0 +1,134 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+package org.mozilla.javascript.optimizer;
+
+class DataFlowBitSet {
+
+ private int itsBits[];
+ private int itsSize;
+
+ DataFlowBitSet(int size)
+ {
+ itsSize = size;
+ itsBits = new int[(size + 31) >> 5];
+ }
+
+ void set(int n)
+ {
+ if (!(0 <= n && n < itsSize)) badIndex(n);
+ itsBits[n >> 5] |= 1 << (n & 31);
+ }
+
+ boolean test(int n)
+ {
+ if (!(0 <= n && n < itsSize)) badIndex(n);
+ return ((itsBits[n >> 5] & (1 << (n & 31))) != 0);
+ }
+
+ void not()
+ {
+ int bitsLength = itsBits.length;
+ for (int i = 0; i < bitsLength; i++)
+ itsBits[i] = ~itsBits[i];
+ }
+
+ void clear(int n)
+ {
+ if (!(0 <= n && n < itsSize)) badIndex(n);
+ itsBits[n >> 5] &= ~(1 << (n & 31));
+ }
+
+ void clear()
+ {
+ int bitsLength = itsBits.length;
+ for (int i = 0; i < bitsLength; i++)
+ itsBits[i] = 0;
+ }
+
+ void or(DataFlowBitSet b)
+ {
+ int bitsLength = itsBits.length;
+ for (int i = 0; i < bitsLength; i++)
+ itsBits[i] |= b.itsBits[i];
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("DataFlowBitSet, size = ");
+ sb.append(itsSize);
+ sb.append('\n');
+ int bitsLength = itsBits.length;
+ for (int i = 0; i < bitsLength; i++) {
+ sb.append(Integer.toHexString(itsBits[i]));
+ sb.append(' ');
+ }
+ return sb.toString();
+ }
+
+ boolean df(DataFlowBitSet in, DataFlowBitSet gen, DataFlowBitSet notKill)
+ {
+ int bitsLength = itsBits.length;
+ boolean changed = false;
+ for (int i = 0; i < bitsLength; i++) {
+ int oldBits = itsBits[i];
+ itsBits[i] = (in.itsBits[i] | gen.itsBits[i]) & notKill.itsBits[i];
+ changed |= (oldBits != itsBits[i]);
+ }
+ return changed;
+ }
+
+ boolean df2(DataFlowBitSet in, DataFlowBitSet gen, DataFlowBitSet notKill)
+ {
+ int bitsLength = itsBits.length;
+ boolean changed = false;
+ for (int i = 0; i < bitsLength; i++) {
+ int oldBits = itsBits[i];
+ itsBits[i] = (in.itsBits[i] & notKill.itsBits[i]) | gen.itsBits[i];
+ changed |= (oldBits != itsBits[i]);
+ }
+ return changed;
+ }
+
+ private void badIndex(int n)
+ {
+ throw new RuntimeException("DataFlowBitSet bad index " + n);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java
new file mode 100644
index 0000000..e043165
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptFunctionNode.java
@@ -0,0 +1,149 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Bob Jervis
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+
+final class OptFunctionNode
+{
+ OptFunctionNode(FunctionNode fnode)
+ {
+ this.fnode = fnode;
+ fnode.setCompilerData(this);
+ }
+
+ static OptFunctionNode get(ScriptOrFnNode scriptOrFn, int i)
+ {
+ FunctionNode fnode = scriptOrFn.getFunctionNode(i);
+ return (OptFunctionNode)fnode.getCompilerData();
+ }
+
+ static OptFunctionNode get(ScriptOrFnNode scriptOrFn)
+ {
+ return (OptFunctionNode)scriptOrFn.getCompilerData();
+ }
+
+ boolean isTargetOfDirectCall()
+ {
+ return directTargetIndex >= 0;
+ }
+
+ int getDirectTargetIndex()
+ {
+ return directTargetIndex;
+ }
+
+ void setDirectTargetIndex(int directTargetIndex)
+ {
+ // One time action
+ if (directTargetIndex < 0 || this.directTargetIndex >= 0)
+ Kit.codeBug();
+ this.directTargetIndex = directTargetIndex;
+ }
+
+ void setParameterNumberContext(boolean b)
+ {
+ itsParameterNumberContext = b;
+ }
+
+ boolean getParameterNumberContext()
+ {
+ return itsParameterNumberContext;
+ }
+
+ int getVarCount()
+ {
+ return fnode.getParamAndVarCount();
+ }
+
+ boolean isParameter(int varIndex)
+ {
+ return varIndex < fnode.getParamCount();
+ }
+
+ boolean isNumberVar(int varIndex)
+ {
+ varIndex -= fnode.getParamCount();
+ if (varIndex >= 0 && numberVarFlags != null) {
+ return numberVarFlags[varIndex];
+ }
+ return false;
+ }
+
+ void setIsNumberVar(int varIndex)
+ {
+ varIndex -= fnode.getParamCount();
+ // Can only be used with non-parameters
+ if (varIndex < 0) Kit.codeBug();
+ if (numberVarFlags == null) {
+ int size = fnode.getParamAndVarCount() - fnode.getParamCount();
+ numberVarFlags = new boolean[size];
+ }
+ numberVarFlags[varIndex] = true;
+ }
+
+ int getVarIndex(Node n)
+ {
+ int index = n.getIntProp(Node.VARIABLE_PROP, -1);
+ if (index == -1) {
+ Node node;
+ int type = n.getType();
+ if (type == Token.GETVAR) {
+ node = n;
+ } else if (type == Token.SETVAR ||
+ type == Token.SETCONSTVAR) {
+ node = n.getFirstChild();
+ } else {
+ throw Kit.codeBug();
+ }
+ index = fnode.getIndexForNameNode(node);
+ if (index < 0) throw Kit.codeBug();
+ n.putIntProp(Node.VARIABLE_PROP, index);
+ }
+ return index;
+ }
+
+ FunctionNode fnode;
+ private boolean[] numberVarFlags;
+ private int directTargetIndex = -1;
+ private boolean itsParameterNumberContext;
+ boolean itsContainsCalls0;
+ boolean itsContainsCalls1;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java
new file mode 100644
index 0000000..ba8ca03
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptRuntime.java
@@ -0,0 +1,311 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ * Hannes Wallnoefer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+
+public final class OptRuntime extends ScriptRuntime
+{
+
+ public static final Double zeroObj = new Double(0.0);
+ public static final Double oneObj = new Double(1.0);
+ public static final Double minusOneObj = new Double(-1.0);
+
+ /**
+ * Implement ....() call shrinking optimizer code.
+ */
+ public static Object call0(Callable fun, Scriptable thisObj,
+ Context cx, Scriptable scope)
+ {
+ return fun.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
+ }
+
+ /**
+ * Implement ....(arg) call shrinking optimizer code.
+ */
+ public static Object call1(Callable fun, Scriptable thisObj, Object arg0,
+ Context cx, Scriptable scope)
+ {
+ return fun.call(cx, scope, thisObj, new Object[] { arg0 } );
+ }
+
+ /**
+ * Implement ....(arg0, arg1) call shrinking optimizer code.
+ */
+ public static Object call2(Callable fun, Scriptable thisObj,
+ Object arg0, Object arg1,
+ Context cx, Scriptable scope)
+ {
+ return fun.call(cx, scope, thisObj, new Object[] { arg0, arg1 });
+ }
+
+ /**
+ * Implement ....(arg0, arg1, ...) call shrinking optimizer code.
+ */
+ public static Object callN(Callable fun, Scriptable thisObj,
+ Object[] args,
+ Context cx, Scriptable scope)
+ {
+ return fun.call(cx, scope, thisObj, args);
+ }
+
+ /**
+ * Implement name(args) call shrinking optimizer code.
+ */
+ public static Object callName(Object[] args, String name,
+ Context cx, Scriptable scope)
+ {
+ Callable f = getNameFunctionAndThis(name, cx, scope);
+ Scriptable thisObj = lastStoredScriptable(cx);
+ return f.call(cx, scope, thisObj, args);
+ }
+
+ /**
+ * Implement name() call shrinking optimizer code.
+ */
+ public static Object callName0(String name,
+ Context cx, Scriptable scope)
+ {
+ Callable f = getNameFunctionAndThis(name, cx, scope);
+ Scriptable thisObj = lastStoredScriptable(cx);
+ return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
+ }
+
+ /**
+ * Implement x.property() call shrinking optimizer code.
+ */
+ public static Object callProp0(Object value, String property,
+ Context cx, Scriptable scope)
+ {
+ Callable f = getPropFunctionAndThis(value, property, cx);
+ Scriptable thisObj = lastStoredScriptable(cx);
+ return f.call(cx, scope, thisObj, ScriptRuntime.emptyArgs);
+ }
+
+ public static Object add(Object val1, double val2)
+ {
+ if (val1 instanceof Scriptable)
+ val1 = ((Scriptable) val1).getDefaultValue(null);
+ if (!(val1 instanceof String))
+ return wrapDouble(toNumber(val1) + val2);
+ return ((String)val1).concat(toString(val2));
+ }
+
+ public static Object add(double val1, Object val2)
+ {
+ if (val2 instanceof Scriptable)
+ val2 = ((Scriptable) val2).getDefaultValue(null);
+ if (!(val2 instanceof String))
+ return wrapDouble(toNumber(val2) + val1);
+ return toString(val1).concat((String)val2);
+ }
+
+ public static Object elemIncrDecr(Object obj, double index,
+ Context cx, int incrDecrMask)
+ {
+ return ScriptRuntime.elemIncrDecr(obj, new Double(index), cx,
+ incrDecrMask);
+ }
+
+ public static Object[] padStart(Object[] currentArgs, int count) {
+ Object[] result = new Object[currentArgs.length + count];
+ System.arraycopy(currentArgs, 0, result, count, currentArgs.length);
+ return result;
+ }
+
+ public static void initFunction(NativeFunction fn, int functionType,
+ Scriptable scope, Context cx)
+ {
+ ScriptRuntime.initFunction(cx, scope, fn, functionType, false);
+ }
+
+ public static Object callSpecial(Context cx, Callable fun,
+ Scriptable thisObj, Object[] args,
+ Scriptable scope,
+ Scriptable callerThis, int callType,
+ String fileName, int lineNumber)
+ {
+ return ScriptRuntime.callSpecial(cx, fun, thisObj, args, scope,
+ callerThis, callType,
+ fileName, lineNumber);
+ }
+
+ public static Object newObjectSpecial(Context cx, Object fun,
+ Object[] args, Scriptable scope,
+ Scriptable callerThis, int callType)
+ {
+ return ScriptRuntime.newSpecial(cx, fun, args, scope, callType);
+ }
+
+ public static Double wrapDouble(double num)
+ {
+ if (num == 0.0) {
+ if (1 / num > 0) {
+ // +0.0
+ return zeroObj;
+ }
+ } else if (num == 1.0) {
+ return oneObj;
+ } else if (num == -1.0) {
+ return minusOneObj;
+ } else if (num != num) {
+ return NaNobj;
+ }
+ return new Double(num);
+ }
+
+ static String encodeIntArray(int[] array)
+ {
+ // XXX: this extremely inefficient for small integers
+ if (array == null) { return null; }
+ int n = array.length;
+ char[] buffer = new char[1 + n * 2];
+ buffer[0] = 1;
+ for (int i = 0; i != n; ++i) {
+ int value = array[i];
+ int shift = 1 + i * 2;
+ buffer[shift] = (char)(value >>> 16);
+ buffer[shift + 1] = (char)value;
+ }
+ return new String(buffer);
+ }
+
+ private static int[] decodeIntArray(String str, int arraySize)
+ {
+ // XXX: this extremely inefficient for small integers
+ if (arraySize == 0) {
+ if (str != null) throw new IllegalArgumentException();
+ return null;
+ }
+ if (str.length() != 1 + arraySize * 2 && str.charAt(0) != 1) {
+ throw new IllegalArgumentException();
+ }
+ int[] array = new int[arraySize];
+ for (int i = 0; i != arraySize; ++i) {
+ int shift = 1 + i * 2;
+ array[i] = (str.charAt(shift) << 16) | str.charAt(shift + 1);
+ }
+ return array;
+ }
+
+ public static Scriptable newArrayLiteral(Object[] objects,
+ String encodedInts,
+ int skipCount,
+ Context cx,
+ Scriptable scope)
+ {
+ int[] skipIndexces = decodeIntArray(encodedInts, skipCount);
+ return newArrayLiteral(objects, skipIndexces, cx, scope);
+ }
+
+ public static void main(final Script script, final String[] args)
+ {
+ Context.call(new ContextAction() {
+ public Object run(Context cx)
+ {
+ ScriptableObject global = getGlobal(cx);
+
+ // get the command line arguments and define "arguments"
+ // array in the top-level object
+ Object[] argsCopy = new Object[args.length];
+ System.arraycopy(args, 0, argsCopy, 0, args.length);
+ Scriptable argsObj = cx.newArray(global, argsCopy);
+ global.defineProperty("arguments", argsObj,
+ ScriptableObject.DONTENUM);
+ script.exec(cx, global);
+ return null;
+ }
+ });
+ }
+
+ public static void throwStopIteration(Object obj) {
+ throw new JavaScriptException(
+ NativeIterator.getStopIterationObject((Scriptable)obj), "", 0);
+ }
+
+ public static Scriptable createNativeGenerator(NativeFunction funObj,
+ Scriptable scope,
+ Scriptable thisObj,
+ int maxLocals,
+ int maxStack)
+ {
+ return new NativeGenerator(scope, funObj,
+ new GeneratorState(thisObj, maxLocals, maxStack));
+ }
+
+ public static Object[] getGeneratorStackState(Object obj) {
+ GeneratorState rgs = (GeneratorState) obj;
+ if (rgs.stackState == null)
+ rgs.stackState = new Object[rgs.maxStack];
+ return rgs.stackState;
+ }
+
+ public static Object[] getGeneratorLocalsState(Object obj) {
+ GeneratorState rgs = (GeneratorState) obj;
+ if (rgs.localsState == null)
+ rgs.localsState = new Object[rgs.maxLocals];
+ return rgs.localsState;
+ }
+
+ public static class GeneratorState {
+ static final String CLASS_NAME =
+ "org/mozilla/javascript/optimizer/OptRuntime$GeneratorState";
+
+ public int resumptionPoint;
+ static final String resumptionPoint_NAME = "resumptionPoint";
+ static final String resumptionPoint_TYPE = "I";
+
+ public Scriptable thisObj;
+ static final String thisObj_NAME = "thisObj";
+ static final String thisObj_TYPE =
+ "Lorg/mozilla/javascript/Scriptable;";
+
+ Object[] stackState;
+ Object[] localsState;
+ int maxLocals;
+ int maxStack;
+
+ GeneratorState(Scriptable thisObj, int maxLocals, int maxStack) {
+ this.thisObj = thisObj;
+ this.maxLocals = maxLocals;
+ this.maxStack = maxStack;
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java
new file mode 100644
index 0000000..7cf679f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/OptTransformer.java
@@ -0,0 +1,133 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+import java.util.Hashtable;
+
+/**
+ * This class performs node transforms to prepare for optimization.
+ *
+ * @see NodeTransformer
+ * @author Norris Boyd
+ */
+
+class OptTransformer extends NodeTransformer {
+
+ OptTransformer(Hashtable possibleDirectCalls, ObjArray directCallTargets)
+ {
+ this.possibleDirectCalls = possibleDirectCalls;
+ this.directCallTargets = directCallTargets;
+ }
+
+ protected void visitNew(Node node, ScriptOrFnNode tree) {
+ detectDirectCall(node, tree);
+ super.visitNew(node, tree);
+ }
+
+ protected void visitCall(Node node, ScriptOrFnNode tree) {
+ detectDirectCall(node, tree);
+ super.visitCall(node, tree);
+ }
+
+ private void detectDirectCall(Node node, ScriptOrFnNode tree)
+ {
+ if (tree.getType() == Token.FUNCTION) {
+ Node left = node.getFirstChild();
+
+ // count the arguments
+ int argCount = 0;
+ Node arg = left.getNext();
+ while (arg != null) {
+ arg = arg.getNext();
+ argCount++;
+ }
+
+ if (argCount == 0) {
+ OptFunctionNode.get(tree).itsContainsCalls0 = true;
+ }
+
+ /*
+ * Optimize a call site by converting call("a", b, c) into :
+ *
+ * FunctionObjectFor"a" <-- instance variable init'd by constructor
+ *
+ * // this is a DIRECTCALL node
+ * fn = GetProp(tmp = GetBase("a"), "a");
+ * if (fn == FunctionObjectFor"a")
+ * fn.call(tmp, b, c)
+ * else
+ * ScriptRuntime.Call(fn, tmp, b, c)
+ */
+ if (possibleDirectCalls != null) {
+ String targetName = null;
+ if (left.getType() == Token.NAME) {
+ targetName = left.getString();
+ } else if (left.getType() == Token.GETPROP) {
+ targetName = left.getFirstChild().getNext().getString();
+ } else if (left.getType() == Token.GETPROPNOWARN) {
+ throw Kit.codeBug();
+ }
+ if (targetName != null) {
+ OptFunctionNode ofn;
+ ofn = (OptFunctionNode)possibleDirectCalls.get(targetName);
+ if (ofn != null
+ && argCount == ofn.fnode.getParamCount()
+ && !ofn.fnode.requiresActivation())
+ {
+ // Refuse to directCall any function with more
+ // than 32 parameters - prevent code explosion
+ // for wacky test cases
+ if (argCount <= 32) {
+ node.putProp(Node.DIRECTCALL_PROP, ofn);
+ if (!ofn.isTargetOfDirectCall()) {
+ int index = directCallTargets.size();
+ directCallTargets.add(ofn);
+ ofn.setDirectTargetIndex(index);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private Hashtable possibleDirectCalls;
+ private ObjArray directCallTargets;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java
new file mode 100644
index 0000000..575c7e7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/optimizer/Optimizer.java
@@ -0,0 +1,510 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+package org.mozilla.javascript.optimizer;
+
+import org.mozilla.javascript.*;
+
+class Optimizer
+{
+
+ static final int NoType = 0;
+ static final int NumberType = 1;
+ static final int AnyType = 3;
+
+ // It is assumed that (NumberType | AnyType) == AnyType
+
+ void optimize(ScriptOrFnNode scriptOrFn)
+ {
+ // run on one function at a time for now
+ int functionCount = scriptOrFn.getFunctionCount();
+ for (int i = 0; i != functionCount; ++i) {
+ OptFunctionNode f = OptFunctionNode.get(scriptOrFn, i);
+ optimizeFunction(f);
+ }
+ }
+
+ private void optimizeFunction(OptFunctionNode theFunction)
+ {
+ if (theFunction.fnode.requiresActivation()) return;
+
+ inDirectCallFunction = theFunction.isTargetOfDirectCall();
+ this.theFunction = theFunction;
+
+ ObjArray statementsArray = new ObjArray();
+ buildStatementList_r(theFunction.fnode, statementsArray);
+ Node[] theStatementNodes = new Node[statementsArray.size()];
+ statementsArray.toArray(theStatementNodes);
+
+ Block.runFlowAnalyzes(theFunction, theStatementNodes);
+
+ if (!theFunction.fnode.requiresActivation()) {
+ /*
+ * Now that we know which local vars are in fact always
+ * Numbers, we re-write the tree to take advantage of
+ * that. Any arithmetic or assignment op involving just
+ * Number typed vars is marked so that the codegen will
+ * generate non-object code.
+ */
+ parameterUsedInNumberContext = false;
+ for (int i = 0; i < theStatementNodes.length; i++) {
+ rewriteForNumberVariables(theStatementNodes[i]);
+ }
+ theFunction.setParameterNumberContext(parameterUsedInNumberContext);
+ }
+
+ }
+
+
+/*
+ Each directCall parameter is passed as a pair of values - an object
+ and a double. The value passed depends on the type of value available at
+ the call site. If a double is available, the object in java/lang/Void.TYPE
+ is passed as the object value, and if an object value is available, then
+ 0.0 is passed as the double value.
+
+ The receiving routine always tests the object value before proceeding.
+ If the parameter is being accessed in a 'Number Context' then the code
+ sequence is :
+ if ("parameter_objectValue" == java/lang/Void.TYPE)
+ ...fine..., use the parameter_doubleValue
+ else
+ toNumber(parameter_objectValue)
+
+ and if the parameter is being referenced in an Object context, the code is
+ if ("parameter_objectValue" == java/lang/Void.TYPE)
+ new Double(parameter_doubleValue)
+ else
+ ...fine..., use the parameter_objectValue
+
+ If the receiving code never uses the doubleValue, it is converted on
+ entry to a Double instead.
+*/
+
+
+/*
+ We're referencing a node in a Number context (i.e. we'd prefer it
+ was a double value). If the node is a parameter in a directCall
+ function, mark it as being referenced in this context.
+*/
+ private void markDCPNumberContext(Node n)
+ {
+ if (inDirectCallFunction && n.getType() == Token.GETVAR) {
+ int varIndex = theFunction.getVarIndex(n);
+ if (theFunction.isParameter(varIndex)) {
+ parameterUsedInNumberContext = true;
+ }
+ }
+ }
+
+ private boolean convertParameter(Node n)
+ {
+ if (inDirectCallFunction && n.getType() == Token.GETVAR) {
+ int varIndex = theFunction.getVarIndex(n);
+ if (theFunction.isParameter(varIndex)) {
+ n.removeProp(Node.ISNUMBER_PROP);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private int rewriteForNumberVariables(Node n)
+ {
+ switch (n.getType()) {
+ case Token.EXPR_VOID : {
+ Node child = n.getFirstChild();
+ int type = rewriteForNumberVariables(child);
+ if (type == NumberType)
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NoType;
+ }
+ case Token.NUMBER :
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+
+ case Token.GETVAR :
+ {
+ int varIndex = theFunction.getVarIndex(n);
+ if (inDirectCallFunction
+ && theFunction.isParameter(varIndex))
+ {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ else if (theFunction.isNumberVar(varIndex)) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ return NoType;
+ }
+
+ case Token.INC :
+ case Token.DEC : {
+ Node child = n.getFirstChild();
+ // "child" will be GETVAR or GETPROP or GETELEM
+ if (child.getType() == Token.GETVAR) {
+ if (rewriteForNumberVariables(child) == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ markDCPNumberContext(child);
+ return NumberType;
+ }
+ return NoType;
+ }
+ else if (child.getType() == Token.GETELEM) {
+ return rewriteForNumberVariables(child);
+ }
+ return NoType;
+ }
+ case Token.SETVAR : {
+ Node lChild = n.getFirstChild();
+ Node rChild = lChild.getNext();
+ int rType = rewriteForNumberVariables(rChild);
+ int varIndex = theFunction.getVarIndex(n);
+ if (inDirectCallFunction
+ && theFunction.isParameter(varIndex))
+ {
+ if (rType == NumberType) {
+ if (!convertParameter(rChild)) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ markDCPNumberContext(rChild);
+ return NoType;
+ }
+ else
+ return rType;
+ }
+ else if (theFunction.isNumberVar(varIndex)) {
+ if (rType != NumberType) {
+ n.removeChild(rChild);
+ n.addChildToBack(
+ new Node(Token.TO_DOUBLE, rChild));
+ }
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ markDCPNumberContext(rChild);
+ return NumberType;
+ }
+ else {
+ if (rType == NumberType) {
+ if (!convertParameter(rChild)) {
+ n.removeChild(rChild);
+ n.addChildToBack(
+ new Node(Token.TO_OBJECT, rChild));
+ }
+ }
+ return NoType;
+ }
+ }
+ case Token.LE :
+ case Token.LT :
+ case Token.GE :
+ case Token.GT : {
+ Node lChild = n.getFirstChild();
+ Node rChild = lChild.getNext();
+ int lType = rewriteForNumberVariables(lChild);
+ int rType = rewriteForNumberVariables(rChild);
+ markDCPNumberContext(lChild);
+ markDCPNumberContext(rChild);
+
+ if (convertParameter(lChild)) {
+ if (convertParameter(rChild)) {
+ return NoType;
+ } else if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
+ }
+ }
+ else if (convertParameter(rChild)) {
+ if (lType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
+ }
+ }
+ else {
+ if (lType == NumberType) {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ }
+ else {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
+ }
+ }
+ else {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
+ }
+ }
+ }
+ // we actually build a boolean value
+ return NoType;
+ }
+
+ case Token.ADD : {
+ Node lChild = n.getFirstChild();
+ Node rChild = lChild.getNext();
+ int lType = rewriteForNumberVariables(lChild);
+ int rType = rewriteForNumberVariables(rChild);
+
+
+ if (convertParameter(lChild)) {
+ if (convertParameter(rChild)) {
+ return NoType;
+ }
+ else {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
+ }
+ }
+ }
+ else {
+ if (convertParameter(rChild)) {
+ if (lType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
+ }
+ }
+ else {
+ if (lType == NumberType) {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ else {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
+ }
+ }
+ else {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP,
+ Node.RIGHT);
+ }
+ }
+ }
+ }
+ return NoType;
+ }
+
+ case Token.BITXOR :
+ case Token.BITOR :
+ case Token.BITAND :
+ case Token.RSH :
+ case Token.LSH :
+ case Token.SUB :
+ case Token.MUL :
+ case Token.DIV :
+ case Token.MOD : {
+ Node lChild = n.getFirstChild();
+ Node rChild = lChild.getNext();
+ int lType = rewriteForNumberVariables(lChild);
+ int rType = rewriteForNumberVariables(rChild);
+ markDCPNumberContext(lChild);
+ markDCPNumberContext(rChild);
+ if (lType == NumberType) {
+ if (rType == NumberType) {
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ else {
+ if (!convertParameter(rChild)) {
+ n.removeChild(rChild);
+ n.addChildToBack(
+ new Node(Token.TO_DOUBLE, rChild));
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ }
+ return NumberType;
+ }
+ }
+ else {
+ if (rType == NumberType) {
+ if (!convertParameter(lChild)) {
+ n.removeChild(lChild);
+ n.addChildToFront(
+ new Node(Token.TO_DOUBLE, lChild));
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ }
+ return NumberType;
+ }
+ else {
+ if (!convertParameter(lChild)) {
+ n.removeChild(lChild);
+ n.addChildToFront(
+ new Node(Token.TO_DOUBLE, lChild));
+ }
+ if (!convertParameter(rChild)) {
+ n.removeChild(rChild);
+ n.addChildToBack(
+ new Node(Token.TO_DOUBLE, rChild));
+ }
+ n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
+ return NumberType;
+ }
+ }
+ }
+ case Token.SETELEM :
+ case Token.SETELEM_OP : {
+ Node arrayBase = n.getFirstChild();
+ Node arrayIndex = arrayBase.getNext();
+ Node rValue = arrayIndex.getNext();
+ int baseType = rewriteForNumberVariables(arrayBase);
+ if (baseType == NumberType) {// can never happen ???
+ if (!convertParameter(arrayBase)) {
+ n.removeChild(arrayBase);
+ n.addChildToFront(
+ new Node(Token.TO_OBJECT, arrayBase));
+ }
+ }
+ int indexType = rewriteForNumberVariables(arrayIndex);
+ if (indexType == NumberType) {
+ // setting the ISNUMBER_PROP signals the codegen
+ // to use the OptRuntime.setObjectIndex that takes
+ // a double index
+ n.putIntProp(Node.ISNUMBER_PROP, Node.LEFT);
+ markDCPNumberContext(arrayIndex);
+ }
+ int rValueType = rewriteForNumberVariables(rValue);
+ if (rValueType == NumberType) {
+ if (!convertParameter(rValue)) {
+ n.removeChild(rValue);
+ n.addChildToBack(
+ new Node(Token.TO_OBJECT, rValue));
+ }
+ }
+ return NoType;
+ }
+ case Token.GETELEM : {
+ Node arrayBase = n.getFirstChild();
+ Node arrayIndex = arrayBase.getNext();
+ int baseType = rewriteForNumberVariables(arrayBase);
+ if (baseType == NumberType) {// can never happen ???
+ if (!convertParameter(arrayBase)) {
+ n.removeChild(arrayBase);
+ n.addChildToFront(
+ new Node(Token.TO_OBJECT, arrayBase));
+ }
+ }
+ int indexType = rewriteForNumberVariables(arrayIndex);
+ if (indexType == NumberType) {
+ if (!convertParameter(arrayIndex)) {
+ // setting the ISNUMBER_PROP signals the codegen
+ // to use the OptRuntime.getObjectIndex that takes
+ // a double index
+ n.putIntProp(Node.ISNUMBER_PROP, Node.RIGHT);
+ }
+ }
+ return NoType;
+ }
+ case Token.CALL :
+ {
+ Node child = n.getFirstChild(); // the function node
+ if (child.getType() == Token.GETELEM) {
+ // Optimization of x[0]() is not supported
+ // so bypass GETELEM optimization that
+ // rewriteForNumberVariables would trigger
+ rewriteAsObjectChildren(child, child.getFirstChild());
+ } else {
+ rewriteForNumberVariables(child);
+ }
+ child = child.getNext(); // the first arg
+
+ OptFunctionNode target
+ = (OptFunctionNode)n.getProp(Node.DIRECTCALL_PROP);
+ if (target != null) {
+/*
+ we leave each child as a Number if it can be. The codegen will
+ handle moving the pairs of parameters.
+*/
+ while (child != null) {
+ int type = rewriteForNumberVariables(child);
+ if (type == NumberType) {
+ markDCPNumberContext(child);
+ }
+ child = child.getNext();
+ }
+ } else {
+ rewriteAsObjectChildren(n, child);
+ }
+ return NoType;
+ }
+ default : {
+ rewriteAsObjectChildren(n, n.getFirstChild());
+ return NoType;
+ }
+ }
+ }
+
+ private void rewriteAsObjectChildren(Node n, Node child)
+ {
+ // Force optimized children to be objects
+ while (child != null) {
+ Node nextChild = child.getNext();
+ int type = rewriteForNumberVariables(child);
+ if (type == NumberType) {
+ if (!convertParameter(child)) {
+ n.removeChild(child);
+ Node nuChild = new Node(Token.TO_OBJECT, child);
+ if (nextChild == null)
+ n.addChildToBack(nuChild);
+ else
+ n.addChildBefore(nuChild, nextChild);
+ }
+ }
+ child = nextChild;
+ }
+ }
+
+ private static void buildStatementList_r(Node node, ObjArray statements)
+ {
+ int type = node.getType();
+ if (type == Token.BLOCK
+ || type == Token.LOCAL_BLOCK
+ || type == Token.LOOP
+ || type == Token.FUNCTION)
+ {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ buildStatementList_r(child, statements);
+ child = child.getNext();
+ }
+ } else {
+ statements.add(node);
+ }
+ }
+
+ private boolean inDirectCallFunction;
+ OptFunctionNode theFunction;
+ private boolean parameterUsedInNumberContext;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java
new file mode 100644
index 0000000..a893841
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExp.java
@@ -0,0 +1,2782 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Brendan Eich
+ * Matthias Radestock
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.regexp;
+
+import java.io.Serializable;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.IdFunctionObject;
+import org.mozilla.javascript.IdScriptableObject;
+import org.mozilla.javascript.Kit;
+import org.mozilla.javascript.ScriptRuntime;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+
+/**
+ * This class implements the RegExp native object.
+ *
+ * Revision History:
+ * Implementation in C by Brendan Eich
+ * Initial port to Java by Norris Boyd from jsregexp.c version 1.36
+ * Merged up to version 1.38, which included Unicode support.
+ * Merged bug fixes in version 1.39.
+ * Merged JSFUN13_BRANCH changes up to 1.32.2.13
+ *
+ * @author Brendan Eich
+ * @author Norris Boyd
+ */
+
+
+
+public class NativeRegExp extends IdScriptableObject implements Function
+{
+ static final long serialVersionUID = 4965263491464903264L;
+
+ private static final Object REGEXP_TAG = new Object();
+
+ public static final int JSREG_GLOB = 0x1; // 'g' flag: global
+ public static final int JSREG_FOLD = 0x2; // 'i' flag: fold
+ public static final int JSREG_MULTILINE = 0x4; // 'm' flag: multiline
+
+ //type of match to perform
+ public static final int TEST = 0;
+ public static final int MATCH = 1;
+ public static final int PREFIX = 2;
+
+ private static final boolean debug = false;
+
+ private static final byte REOP_EMPTY = 0; /* match rest of input against rest of r.e. */
+ private static final byte REOP_ALT = 1; /* alternative subexpressions in kid and next */
+ private static final byte REOP_BOL = 2; /* beginning of input (or line if multiline) */
+ private static final byte REOP_EOL = 3; /* end of input (or line if multiline) */
+ private static final byte REOP_WBDRY = 4; /* match "" at word boundary */
+ private static final byte REOP_WNONBDRY = 5; /* match "" at word non-boundary */
+ private static final byte REOP_QUANT = 6; /* quantified atom: atom{1,2} */
+ private static final byte REOP_STAR = 7; /* zero or more occurrences of kid */
+ private static final byte REOP_PLUS = 8; /* one or more occurrences of kid */
+ private static final byte REOP_OPT = 9; /* optional subexpression in kid */
+ private static final byte REOP_LPAREN = 10; /* left paren bytecode: kid is u.num'th sub-regexp */
+ private static final byte REOP_RPAREN = 11; /* right paren bytecode */
+ private static final byte REOP_DOT = 12; /* stands for any character */
+// private static final byte REOP_CCLASS = 13; /* character class: [a-f] */
+ private static final byte REOP_DIGIT = 14; /* match a digit char: [0-9] */
+ private static final byte REOP_NONDIGIT = 15; /* match a non-digit char: [^0-9] */
+ private static final byte REOP_ALNUM = 16; /* match an alphanumeric char: [0-9a-z_A-Z] */
+ private static final byte REOP_NONALNUM = 17; /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
+ private static final byte REOP_SPACE = 18; /* match a whitespace char */
+ private static final byte REOP_NONSPACE = 19; /* match a non-whitespace char */
+ private static final byte REOP_BACKREF = 20; /* back-reference (e.g., \1) to a parenthetical */
+ private static final byte REOP_FLAT = 21; /* match a flat string */
+ private static final byte REOP_FLAT1 = 22; /* match a single char */
+ private static final byte REOP_JUMP = 23; /* for deoptimized closure loops */
+// private static final byte REOP_DOTSTAR = 24; /* optimize .* to use a single opcode */
+// private static final byte REOP_ANCHOR = 25; /* like .* but skips left context to unanchored r.e. */
+// private static final byte REOP_EOLONLY = 26; /* $ not preceded by any pattern */
+// private static final byte REOP_UCFLAT = 27; /* flat Unicode string; len immediate counts chars */
+ private static final byte REOP_UCFLAT1 = 28; /* single Unicode char */
+// private static final byte REOP_UCCLASS = 29; /* Unicode character class, vector of chars to match */
+// private static final byte REOP_NUCCLASS = 30; /* negated Unicode character class */
+// private static final byte REOP_BACKREFi = 31; /* case-independent REOP_BACKREF */
+ private static final byte REOP_FLATi = 32; /* case-independent REOP_FLAT */
+ private static final byte REOP_FLAT1i = 33; /* case-independent REOP_FLAT1 */
+// private static final byte REOP_UCFLATi = 34; /* case-independent REOP_UCFLAT */
+ private static final byte REOP_UCFLAT1i = 35; /* case-independent REOP_UCFLAT1 */
+// private static final byte REOP_ANCHOR1 = 36; /* first-char discriminating REOP_ANCHOR */
+// private static final byte REOP_NCCLASS = 37; /* negated 8-bit character class */
+// private static final byte REOP_DOTSTARMIN = 38; /* ungreedy version of REOP_DOTSTAR */
+// private static final byte REOP_LPARENNON = 39; /* non-capturing version of REOP_LPAREN */
+// private static final byte REOP_RPARENNON = 40; /* non-capturing version of REOP_RPAREN */
+ private static final byte REOP_ASSERT = 41; /* zero width positive lookahead assertion */
+ private static final byte REOP_ASSERT_NOT = 42; /* zero width negative lookahead assertion */
+ private static final byte REOP_ASSERTTEST = 43; /* sentinel at end of assertion child */
+ private static final byte REOP_ASSERTNOTTEST = 44; /* sentinel at end of !assertion child */
+ private static final byte REOP_MINIMALSTAR = 45; /* non-greedy version of * */
+ private static final byte REOP_MINIMALPLUS = 46; /* non-greedy version of + */
+ private static final byte REOP_MINIMALOPT = 47; /* non-greedy version of ? */
+ private static final byte REOP_MINIMALQUANT = 48; /* non-greedy version of {} */
+ private static final byte REOP_ENDCHILD = 49; /* sentinel at end of quantifier child */
+ private static final byte REOP_CLASS = 50; /* character class with index */
+ private static final byte REOP_REPEAT = 51; /* directs execution of greedy quantifier */
+ private static final byte REOP_MINIMALREPEAT = 52; /* directs execution of non-greedy quantifier */
+ private static final byte REOP_END = 53;
+
+
+
+ public static void init(Context cx, Scriptable scope, boolean sealed)
+ {
+
+ NativeRegExp proto = new NativeRegExp();
+ proto.re = (RECompiled)compileRE(cx, "", null, false);
+ proto.activatePrototypeMap(MAX_PROTOTYPE_ID);
+ proto.setParentScope(scope);
+ proto.setPrototype(getObjectPrototype(scope));
+
+ NativeRegExpCtor ctor = new NativeRegExpCtor();
+ // Bug #324006: ECMA-262 15.10.6.1 says "The initial value of
+ // RegExp.prototype.constructor is the builtin RegExp constructor."
+ proto.put("constructor", proto, ctor);
+
+ ScriptRuntime.setFunctionProtoAndParent(ctor, scope);
+
+ ctor.setImmunePrototypeProperty(proto);
+
+ if (sealed) {
+ proto.sealObject();
+ ctor.sealObject();
+ }
+
+ defineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM);
+ }
+
+ NativeRegExp(Scriptable scope, Object regexpCompiled)
+ {
+ this.re = (RECompiled)regexpCompiled;
+ this.lastIndex = 0;
+ ScriptRuntime.setObjectProtoAndParent(this, scope);
+ }
+
+ public String getClassName()
+ {
+ return "RegExp";
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ return execSub(cx, scope, args, MATCH);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ return (Scriptable)execSub(cx, scope, args, MATCH);
+ }
+
+ Scriptable compile(Context cx, Scriptable scope, Object[] args)
+ {
+ if (args.length > 0 && args[0] instanceof NativeRegExp) {
+ if (args.length > 1 && args[1] != Undefined.instance) {
+ // report error
+ throw ScriptRuntime.typeError0("msg.bad.regexp.compile");
+ }
+ NativeRegExp thatObj = (NativeRegExp) args[0];
+ this.re = thatObj.re;
+ this.lastIndex = thatObj.lastIndex;
+ return this;
+ }
+ String s = args.length == 0 ? "" : ScriptRuntime.toString(args[0]);
+ String global = args.length > 1 && args[1] != Undefined.instance
+ ? ScriptRuntime.toString(args[1])
+ : null;
+ this.re = (RECompiled)compileRE(cx, s, global, false);
+ this.lastIndex = 0;
+ return this;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append('/');
+ if (re.source.length != 0) {
+ buf.append(re.source);
+ } else {
+ // See bugzilla 226045
+ buf.append("(?:)");
+ }
+ buf.append('/');
+ if ((re.flags & JSREG_GLOB) != 0)
+ buf.append('g');
+ if ((re.flags & JSREG_FOLD) != 0)
+ buf.append('i');
+ if ((re.flags & JSREG_MULTILINE) != 0)
+ buf.append('m');
+ return buf.toString();
+ }
+
+ NativeRegExp() { }
+
+ private static RegExpImpl getImpl(Context cx)
+ {
+ return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
+ }
+
+ private Object execSub(Context cx, Scriptable scopeObj,
+ Object[] args, int matchType)
+ {
+ RegExpImpl reImpl = getImpl(cx);
+ String str;
+ if (args.length == 0) {
+ str = reImpl.input;
+ if (str == null) {
+ reportError("msg.no.re.input.for", toString());
+ }
+ } else {
+ str = ScriptRuntime.toString(args[0]);
+ }
+ double d = ((re.flags & JSREG_GLOB) != 0) ? lastIndex : 0;
+
+ Object rval;
+ if (d < 0 || str.length() < d) {
+ lastIndex = 0;
+ rval = null;
+ }
+ else {
+ int indexp[] = { (int)d };
+ rval = executeRegExp(cx, scopeObj, reImpl, str, indexp, matchType);
+ if ((re.flags & JSREG_GLOB) != 0) {
+ lastIndex = (rval == null || rval == Undefined.instance)
+ ? 0 : indexp[0];
+ }
+ }
+ return rval;
+ }
+
+ static Object compileRE(Context cx, String str, String global, boolean flat)
+ {
+ RECompiled regexp = new RECompiled();
+ regexp.source = str.toCharArray();
+ int length = str.length();
+
+ int flags = 0;
+ if (global != null) {
+ for (int i = 0; i < global.length(); i++) {
+ char c = global.charAt(i);
+ if (c == 'g') {
+ flags |= JSREG_GLOB;
+ } else if (c == 'i') {
+ flags |= JSREG_FOLD;
+ } else if (c == 'm') {
+ flags |= JSREG_MULTILINE;
+ } else {
+ reportError("msg.invalid.re.flag", String.valueOf(c));
+ }
+ }
+ }
+ regexp.flags = flags;
+
+ CompilerState state = new CompilerState(cx, regexp.source, length, flags);
+ if (flat && length > 0) {
+if (debug) {
+System.out.println("flat = \"" + str + "\"");
+}
+ state.result = new RENode(REOP_FLAT);
+ state.result.chr = state.cpbegin[0];
+ state.result.length = length;
+ state.result.flatIndex = 0;
+ state.progLength += 5;
+ }
+ else
+ if (!parseDisjunction(state))
+ return null;
+
+ regexp.program = new byte[state.progLength + 1];
+ if (state.classCount != 0) {
+ regexp.classList = new RECharSet[state.classCount];
+ regexp.classCount = state.classCount;
+ }
+ int endPC = emitREBytecode(state, regexp, 0, state.result);
+ regexp.program[endPC++] = REOP_END;
+
+if (debug) {
+System.out.println("Prog. length = " + endPC);
+for (int i = 0; i < endPC; i++) {
+ System.out.print(regexp.program[i]);
+ if (i < (endPC - 1)) System.out.print(", ");
+}
+System.out.println();
+}
+ regexp.parenCount = state.parenCount;
+
+ // If re starts with literal, init anchorCh accordingly
+ switch (regexp.program[0]) {
+ case REOP_UCFLAT1:
+ case REOP_UCFLAT1i:
+ regexp.anchorCh = (char)getIndex(regexp.program, 1);
+ break;
+ case REOP_FLAT1:
+ case REOP_FLAT1i:
+ regexp.anchorCh = (char)(regexp.program[1] & 0xFF);
+ break;
+ case REOP_FLAT:
+ case REOP_FLATi:
+ int k = getIndex(regexp.program, 1);
+ regexp.anchorCh = regexp.source[k];
+ break;
+ }
+
+if (debug) {
+if (regexp.anchorCh >= 0) {
+ System.out.println("Anchor ch = '" + (char)regexp.anchorCh + "'");
+}
+}
+ return regexp;
+ }
+
+ static boolean isDigit(char c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ private static boolean isWord(char c)
+ {
+ return Character.isLetter(c) || isDigit(c) || c == '_';
+ }
+
+ private static boolean isLineTerm(char c)
+ {
+ return ScriptRuntime.isJSLineTerminator(c);
+ }
+
+ private static boolean isREWhiteSpace(int c)
+ {
+ return (c == '\u0020' || c == '\u0009'
+ || c == '\n' || c == '\r'
+ || c == 0x2028 || c == 0x2029
+ || c == '\u000C' || c == '\u000B'
+ || c == '\u00A0'
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR);
+ }
+
+ /*
+ *
+ * 1. If IgnoreCase is false, return ch.
+ * 2. Let u be ch converted to upper case as if by calling
+ * String.prototype.toUpperCase on the one-character string ch.
+ * 3. If u does not consist of a single character, return ch.
+ * 4. Let cu be u's character.
+ * 5. If ch's code point value is greater than or equal to decimal 128 and cu's
+ * code point value is less than decimal 128, then return ch.
+ * 6. Return cu.
+ */
+ private static char upcase(char ch)
+ {
+ if (ch < 128) {
+ if ('a' <= ch && ch <= 'z') {
+ return (char)(ch + ('A' - 'a'));
+ }
+ return ch;
+ }
+ char cu = Character.toUpperCase(ch);
+ if ((ch >= 128) && (cu < 128)) return ch;
+ return cu;
+ }
+
+ private static char downcase(char ch)
+ {
+ if (ch < 128) {
+ if ('A' <= ch && ch <= 'Z') {
+ return (char)(ch + ('a' - 'A'));
+ }
+ return ch;
+ }
+ char cl = Character.toLowerCase(ch);
+ if ((ch >= 128) && (cl < 128)) return ch;
+ return cl;
+ }
+
+/*
+ * Validates and converts hex ascii value.
+ */
+ private static int toASCIIHexDigit(int c)
+ {
+ if (c < '0')
+ return -1;
+ if (c <= '9') {
+ return c - '0';
+ }
+ c |= 0x20;
+ if ('a' <= c && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ return -1;
+ }
+
+/*
+ * Top-down regular expression grammar, based closely on Perl4.
+ *
+ * regexp: altern A regular expression is one or more
+ * altern '|' regexp alternatives separated by vertical bar.
+ */
+ private static boolean parseDisjunction(CompilerState state)
+ {
+ if (!parseAlternative(state))
+ return false;
+ char[] source = state.cpbegin;
+ int index = state.cp;
+ if (index != source.length && source[index] == '|') {
+ RENode altResult;
+ ++state.cp;
+ altResult = new RENode(REOP_ALT);
+ altResult.kid = state.result;
+ if (!parseDisjunction(state))
+ return false;
+ altResult.kid2 = state.result;
+ state.result = altResult;
+ /* ALT, <next>, ..., JUMP, <end> ... JUMP <end> */
+ state.progLength += 9;
+ }
+ return true;
+ }
+
+/*
+ * altern: item An alternative is one or more items,
+ * item altern concatenated together.
+ */
+ private static boolean parseAlternative(CompilerState state)
+ {
+ RENode headTerm = null;
+ RENode tailTerm = null;
+ char[] source = state.cpbegin;
+ while (true) {
+ if (state.cp == state.cpend || source[state.cp] == '|'
+ || (state.parenNesting != 0 && source[state.cp] == ')'))
+ {
+ if (headTerm == null) {
+ state.result = new RENode(REOP_EMPTY);
+ }
+ else
+ state.result = headTerm;
+ return true;
+ }
+ if (!parseTerm(state))
+ return false;
+ if (headTerm == null)
+ headTerm = state.result;
+ else {
+ if (tailTerm == null) {
+ headTerm.next = state.result;
+ tailTerm = state.result;
+ while (tailTerm.next != null) tailTerm = tailTerm.next;
+ }
+ else {
+ tailTerm.next = state.result;
+ tailTerm = tailTerm.next;
+ while (tailTerm.next != null) tailTerm = tailTerm.next;
+ }
+ }
+ }
+ }
+
+ /* calculate the total size of the bitmap required for a class expression */
+ private static boolean
+ calculateBitmapSize(CompilerState state, RENode target, char[] src,
+ int index, int end)
+ {
+ char rangeStart = 0;
+ char c;
+ int n;
+ int nDigits;
+ int i;
+ int max = 0;
+ boolean inRange = false;
+
+ target.bmsize = 0;
+
+ if (index == end)
+ return true;
+
+ if (src[index] == '^')
+ ++index;
+
+ while (index != end) {
+ int localMax = 0;
+ nDigits = 2;
+ switch (src[index]) {
+ case '\\':
+ ++index;
+ c = src[index++];
+ switch (c) {
+ case 'b':
+ localMax = 0x8;
+ break;
+ case 'f':
+ localMax = 0xC;
+ break;
+ case 'n':
+ localMax = 0xA;
+ break;
+ case 'r':
+ localMax = 0xD;
+ break;
+ case 't':
+ localMax = 0x9;
+ break;
+ case 'v':
+ localMax = 0xB;
+ break;
+ case 'c':
+ if (((index + 1) < end) && Character.isLetter(src[index + 1]))
+ localMax = (char)(src[index++] & 0x1F);
+ else
+ localMax = '\\';
+ break;
+ case 'u':
+ nDigits += 2;
+ // fall thru...
+ case 'x':
+ n = 0;
+ for (i = 0; (i < nDigits) && (index < end); i++) {
+ c = src[index++];
+ n = Kit.xDigitToInt(c, n);
+ if (n < 0) {
+ // Back off to accepting the original
+ // '\' as a literal
+ index -= (i + 1);
+ n = '\\';
+ break;
+ }
+ }
+ localMax = n;
+ break;
+ case 'd':
+ if (inRange) {
+ reportError("msg.bad.range", "");
+ return false;
+ }
+ localMax = '9';
+ break;
+ case 'D':
+ case 's':
+ case 'S':
+ case 'w':
+ case 'W':
+ if (inRange) {
+ reportError("msg.bad.range", "");
+ return false;
+ }
+ target.bmsize = 65535;
+ return true;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ /*
+ * This is a non-ECMA extension - decimal escapes (in this
+ * case, octal!) are supposed to be an error inside class
+ * ranges, but supported here for backwards compatibility.
+ *
+ */
+ n = (c - '0');
+ c = src[index];
+ if ('0' <= c && c <= '7') {
+ index++;
+ n = 8 * n + (c - '0');
+ c = src[index];
+ if ('0' <= c && c <= '7') {
+ index++;
+ i = 8 * n + (c - '0');
+ if (i <= 0377)
+ n = i;
+ else
+ index--;
+ }
+ }
+ localMax = n;
+ break;
+
+ default:
+ localMax = c;
+ break;
+ }
+ break;
+ default:
+ localMax = src[index++];
+ break;
+ }
+ if (inRange) {
+ if (rangeStart > localMax) {
+ reportError("msg.bad.range", "");
+ return false;
+ }
+ inRange = false;
+ }
+ else {
+ if (index < (end - 1)) {
+ if (src[index] == '-') {
+ ++index;
+ inRange = true;
+ rangeStart = (char)localMax;
+ continue;
+ }
+ }
+ }
+ if ((state.flags & JSREG_FOLD) != 0){
+ char cu = upcase((char)localMax);
+ char cd = downcase((char)localMax);
+ localMax = (cu >= cd) ? cu : cd;
+ }
+ if (localMax > max)
+ max = localMax;
+ }
+ target.bmsize = max;
+ return true;
+ }
+
+ /*
+ * item: assertion An item is either an assertion or
+ * quantatom a quantified atom.
+ *
+ * assertion: '^' Assertions match beginning of string
+ * (or line if the class static property
+ * RegExp.multiline is true).
+ * '$' End of string (or line if the class
+ * static property RegExp.multiline is
+ * true).
+ * '\b' Word boundary (between \w and \W).
+ * '\B' Word non-boundary.
+ *
+ * quantatom: atom An unquantified atom.
+ * quantatom '{' n ',' m '}'
+ * Atom must occur between n and m times.
+ * quantatom '{' n ',' '}' Atom must occur at least n times.
+ * quantatom '{' n '}' Atom must occur exactly n times.
+ * quantatom '*' Zero or more times (same as {0,}).
+ * quantatom '+' One or more times (same as {1,}).
+ * quantatom '?' Zero or one time (same as {0,1}).
+ *
+ * any of which can be optionally followed by '?' for ungreedy
+ *
+ * atom: '(' regexp ')' A parenthesized regexp (what matched
+ * can be addressed using a backreference,
+ * see '\' n below).
+ * '.' Matches any char except '\n'.
+ * '[' classlist ']' A character class.
+ * '[' '^' classlist ']' A negated character class.
+ * '\f' Form Feed.
+ * '\n' Newline (Line Feed).
+ * '\r' Carriage Return.
+ * '\t' Horizontal Tab.
+ * '\v' Vertical Tab.
+ * '\d' A digit (same as [0-9]).
+ * '\D' A non-digit.
+ * '\w' A word character, [0-9a-z_A-Z].
+ * '\W' A non-word character.
+ * '\s' A whitespace character, [ \b\f\n\r\t\v].
+ * '\S' A non-whitespace character.
+ * '\' n A backreference to the nth (n decimal
+ * and positive) parenthesized expression.
+ * '\' octal An octal escape sequence (octal must be
+ * two or three digits long, unless it is
+ * 0 for the null character).
+ * '\x' hex A hex escape (hex must be two digits).
+ * '\c' ctrl A control character, ctrl is a letter.
+ * '\' literalatomchar Any character except one of the above
+ * that follow '\' in an atom.
+ * otheratomchar Any character not first among the other
+ * atom right-hand sides.
+ */
+
+ private static void doFlat(CompilerState state, char c)
+ {
+ state.result = new RENode(REOP_FLAT);
+ state.result.chr = c;
+ state.result.length = 1;
+ state.result.flatIndex = -1;
+ state.progLength += 3;
+ }
+
+ private static int
+ getDecimalValue(char c, CompilerState state, int maxValue,
+ String overflowMessageId)
+ {
+ boolean overflow = false;
+ int start = state.cp;
+ char[] src = state.cpbegin;
+ int value = c - '0';
+ for (; state.cp != state.cpend; ++state.cp) {
+ c = src[state.cp];
+ if (!isDigit(c)) {
+ break;
+ }
+ if (!overflow) {
+ int digit = c - '0';
+ if (value < (maxValue - digit) / 10) {
+ value = value * 10 + digit;
+ } else {
+ overflow = true;
+ value = maxValue;
+ }
+ }
+ }
+ if (overflow) {
+ reportError(overflowMessageId,
+ String.valueOf(src, start, state.cp - start));
+ }
+ return value;
+ }
+
+ private static boolean
+ parseTerm(CompilerState state)
+ {
+ char[] src = state.cpbegin;
+ char c = src[state.cp++];
+ int nDigits = 2;
+ int parenBaseCount = state.parenCount;
+ int num, tmp;
+ RENode term;
+ int termStart;
+
+ switch (c) {
+ /* assertions and atoms */
+ case '^':
+ state.result = new RENode(REOP_BOL);
+ state.progLength++;
+ return true;
+ case '$':
+ state.result = new RENode(REOP_EOL);
+ state.progLength++;
+ return true;
+ case '\\':
+ if (state.cp < state.cpend) {
+ c = src[state.cp++];
+ switch (c) {
+ /* assertion escapes */
+ case 'b' :
+ state.result = new RENode(REOP_WBDRY);
+ state.progLength++;
+ return true;
+ case 'B':
+ state.result = new RENode(REOP_WNONBDRY);
+ state.progLength++;
+ return true;
+ /* Decimal escape */
+ case '0':
+/*
+ * Under 'strict' ECMA 3, we interpret \0 as NUL and don't accept octal.
+ * However, (XXX and since Rhino doesn't have a 'strict' mode) we'll just
+ * behave the old way for compatibility reasons.
+ * (see http://bugzilla.mozilla.org/show_bug.cgi?id=141078)
+ *
+ */
+ reportWarning(state.cx, "msg.bad.backref", "");
+ /* octal escape */
+ num = 0;
+ while (state.cp < state.cpend) {
+ c = src[state.cp];
+ if ((c >= '0') && (c <= '7')) {
+ state.cp++;
+ tmp = 8 * num + (c - '0');
+ if (tmp > 0377)
+ break;
+ num = tmp;
+ }
+ else
+ break;
+ }
+ c = (char)(num);
+ doFlat(state, c);
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ termStart = state.cp - 1;
+ num = getDecimalValue(c, state, 0xFFFF,
+ "msg.overlarge.backref");
+ if (num > state.parenCount)
+ reportWarning(state.cx, "msg.bad.backref", "");
+ /*
+ * n > 9 or > count of parentheses,
+ * then treat as octal instead.
+ */
+ if ((num > 9) && (num > state.parenCount)) {
+ state.cp = termStart;
+ num = 0;
+ while (state.cp < state.cpend) {
+ c = src[state.cp];
+ if ((c >= '0') && (c <= '7')) {
+ state.cp++;
+ tmp = 8 * num + (c - '0');
+ if (tmp > 0377)
+ break;
+ num = tmp;
+ }
+ else
+ break;
+ }
+ c = (char)(num);
+ doFlat(state, c);
+ break;
+ }
+ /* otherwise, it's a back-reference */
+ state.result = new RENode(REOP_BACKREF);
+ state.result.parenIndex = num - 1;
+ state.progLength += 3;
+ break;
+ /* Control escape */
+ case 'f':
+ c = 0xC;
+ doFlat(state, c);
+ break;
+ case 'n':
+ c = 0xA;
+ doFlat(state, c);
+ break;
+ case 'r':
+ c = 0xD;
+ doFlat(state, c);
+ break;
+ case 't':
+ c = 0x9;
+ doFlat(state, c);
+ break;
+ case 'v':
+ c = 0xB;
+ doFlat(state, c);
+ break;
+ /* Control letter */
+ case 'c':
+ if (((state.cp + 1) < state.cpend) &&
+ Character.isLetter(src[state.cp + 1]))
+ c = (char)(src[state.cp++] & 0x1F);
+ else {
+ /* back off to accepting the original '\' as a literal */
+ --state.cp;
+ c = '\\';
+ }
+ doFlat(state, c);
+ break;
+ /* UnicodeEscapeSequence */
+ case 'u':
+ nDigits += 2;
+ // fall thru...
+ /* HexEscapeSequence */
+ case 'x':
+ {
+ int n = 0;
+ int i;
+ for (i = 0; (i < nDigits)
+ && (state.cp < state.cpend); i++) {
+ c = src[state.cp++];
+ n = Kit.xDigitToInt(c, n);
+ if (n < 0) {
+ // Back off to accepting the original
+ // 'u' or 'x' as a literal
+ state.cp -= (i + 2);
+ n = src[state.cp++];
+ break;
+ }
+ }
+ c = (char)(n);
+ }
+ doFlat(state, c);
+ break;
+ /* Character class escapes */
+ case 'd':
+ state.result = new RENode(REOP_DIGIT);
+ state.progLength++;
+ break;
+ case 'D':
+ state.result = new RENode(REOP_NONDIGIT);
+ state.progLength++;
+ break;
+ case 's':
+ state.result = new RENode(REOP_SPACE);
+ state.progLength++;
+ break;
+ case 'S':
+ state.result = new RENode(REOP_NONSPACE);
+ state.progLength++;
+ break;
+ case 'w':
+ state.result = new RENode(REOP_ALNUM);
+ state.progLength++;
+ break;
+ case 'W':
+ state.result = new RENode(REOP_NONALNUM);
+ state.progLength++;
+ break;
+ /* IdentityEscape */
+ default:
+ state.result = new RENode(REOP_FLAT);
+ state.result.chr = c;
+ state.result.length = 1;
+ state.result.flatIndex = state.cp - 1;
+ state.progLength += 3;
+ break;
+ }
+ break;
+ }
+ else {
+ /* a trailing '\' is an error */
+ reportError("msg.trail.backslash", "");
+ return false;
+ }
+ case '(': {
+ RENode result = null;
+ termStart = state.cp;
+ if (state.cp + 1 < state.cpend && src[state.cp] == '?'
+ && ((c = src[state.cp + 1]) == '=' || c == '!' || c == ':'))
+ {
+ state.cp += 2;
+ if (c == '=') {
+ result = new RENode(REOP_ASSERT);
+ /* ASSERT, <next>, ... ASSERTTEST */
+ state.progLength += 4;
+ } else if (c == '!') {
+ result = new RENode(REOP_ASSERT_NOT);
+ /* ASSERTNOT, <next>, ... ASSERTNOTTEST */
+ state.progLength += 4;
+ }
+ } else {
+ result = new RENode(REOP_LPAREN);
+ /* LPAREN, <index>, ... RPAREN, <index> */
+ state.progLength += 6;
+ result.parenIndex = state.parenCount++;
+ }
+ ++state.parenNesting;
+ if (!parseDisjunction(state))
+ return false;
+ if (state.cp == state.cpend || src[state.cp] != ')') {
+ reportError("msg.unterm.paren", "in regular expression"/*APPJET*/);
+ return false;
+ }
+ ++state.cp;
+ --state.parenNesting;
+ if (result != null) {
+ result.kid = state.result;
+ state.result = result;
+ }
+ break;
+ }
+ case ')':
+ reportError("msg.re.unmatched.right.paren", "");
+ return false;
+ case '[':
+ state.result = new RENode(REOP_CLASS);
+ termStart = state.cp;
+ state.result.startIndex = termStart;
+ while (true) {
+ if (state.cp == state.cpend) {
+ reportError("msg.unterm.class", "");
+ return false;
+ }
+ if (src[state.cp] == '\\')
+ state.cp++;
+ else {
+ if (src[state.cp] == ']') {
+ state.result.kidlen = state.cp - termStart;
+ break;
+ }
+ }
+ state.cp++;
+ }
+ state.result.index = state.classCount++;
+ /*
+ * Call calculateBitmapSize now as we want any errors it finds
+ * to be reported during the parse phase, not at execution.
+ */
+ if (!calculateBitmapSize(state, state.result, src, termStart, state.cp++))
+ return false;
+ state.progLength += 3; /* CLASS, <index> */
+ break;
+
+ case '.':
+ state.result = new RENode(REOP_DOT);
+ state.progLength++;
+ break;
+ case '*':
+ case '+':
+ case '?':
+ reportError("msg.bad.quant", String.valueOf(src[state.cp - 1]));
+ return false;
+ default:
+ state.result = new RENode(REOP_FLAT);
+ state.result.chr = c;
+ state.result.length = 1;
+ state.result.flatIndex = state.cp - 1;
+ state.progLength += 3;
+ break;
+ }
+
+ term = state.result;
+ if (state.cp == state.cpend) {
+ return true;
+ }
+ boolean hasQ = false;
+ switch (src[state.cp]) {
+ case '+':
+ state.result = new RENode(REOP_QUANT);
+ state.result.min = 1;
+ state.result.max = -1;
+ /* <PLUS>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
+ state.progLength += 8;
+ hasQ = true;
+ break;
+ case '*':
+ state.result = new RENode(REOP_QUANT);
+ state.result.min = 0;
+ state.result.max = -1;
+ /* <STAR>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
+ state.progLength += 8;
+ hasQ = true;
+ break;
+ case '?':
+ state.result = new RENode(REOP_QUANT);
+ state.result.min = 0;
+ state.result.max = 1;
+ /* <OPT>, <parencount>, <parenindex>, <next> ... <ENDCHILD> */
+ state.progLength += 8;
+ hasQ = true;
+ break;
+ case '{': /* balance '}' */
+ {
+ int min = 0;
+ int max = -1;
+ int leftCurl = state.cp;
+
+ /* For Perl etc. compatibility, if quntifier does not match
+ * \{\d+(,\d*)?\} exactly back off from it
+ * being a quantifier, and chew it up as a literal
+ * atom next time instead.
+ */
+
+ c = src[++state.cp];
+ if (isDigit(c)) {
+ ++state.cp;
+ min = getDecimalValue(c, state, 0xFFFF,
+ "msg.overlarge.min");
+ c = src[state.cp];
+ if (c == ',') {
+ c = src[++state.cp];
+ if (isDigit(c)) {
+ ++state.cp;
+ max = getDecimalValue(c, state, 0xFFFF,
+ "msg.overlarge.max");
+ c = src[state.cp];
+ if (min > max) {
+ reportError("msg.max.lt.min",
+ String.valueOf(src[state.cp]));
+ return false;
+ }
+ }
+ } else {
+ max = min;
+ }
+ /* balance '{' */
+ if (c == '}') {
+ state.result = new RENode(REOP_QUANT);
+ state.result.min = min;
+ state.result.max = max;
+ // QUANT, <min>, <max>, <parencount>,
+ // <parenindex>, <next> ... <ENDCHILD>
+ state.progLength += 12;
+ hasQ = true;
+ }
+ }
+ if (!hasQ) {
+ state.cp = leftCurl;
+ }
+ break;
+ }
+ }
+ if (!hasQ)
+ return true;
+
+ ++state.cp;
+ state.result.kid = term;
+ state.result.parenIndex = parenBaseCount;
+ state.result.parenCount = state.parenCount - parenBaseCount;
+ if ((state.cp < state.cpend) && (src[state.cp] == '?')) {
+ ++state.cp;
+ state.result.greedy = false;
+ }
+ else
+ state.result.greedy = true;
+ return true;
+ }
+
+ private static void resolveForwardJump(byte[] array, int from, int pc)
+ {
+ if (from > pc) throw Kit.codeBug();
+ addIndex(array, from, pc - from);
+ }
+
+ private static int getOffset(byte[] array, int pc)
+ {
+ return getIndex(array, pc);
+ }
+
+ private static int addIndex(byte[] array, int pc, int index)
+ {
+ if (index < 0) throw Kit.codeBug();
+ if (index > 0xFFFF)
+ throw Context.reportRuntimeError("Too complex regexp");
+ array[pc] = (byte)(index >> 8);
+ array[pc + 1] = (byte)(index);
+ return pc + 2;
+ }
+
+ private static int getIndex(byte[] array, int pc)
+ {
+ return ((array[pc] & 0xFF) << 8) | (array[pc + 1] & 0xFF);
+ }
+
+ private static final int OFFSET_LEN = 2;
+ private static final int INDEX_LEN = 2;
+
+ private static int
+ emitREBytecode(CompilerState state, RECompiled re, int pc, RENode t)
+ {
+ RENode nextAlt;
+ int nextAltFixup, nextTermFixup;
+ byte[] program = re.program;
+
+ while (t != null) {
+ program[pc++] = t.op;
+ switch (t.op) {
+ case REOP_EMPTY:
+ --pc;
+ break;
+ case REOP_ALT:
+ nextAlt = t.kid2;
+ nextAltFixup = pc; /* address of next alternate */
+ pc += OFFSET_LEN;
+ pc = emitREBytecode(state, re, pc, t.kid);
+ program[pc++] = REOP_JUMP;
+ nextTermFixup = pc; /* address of following term */
+ pc += OFFSET_LEN;
+ resolveForwardJump(program, nextAltFixup, pc);
+ pc = emitREBytecode(state, re, pc, nextAlt);
+
+ program[pc++] = REOP_JUMP;
+ nextAltFixup = pc;
+ pc += OFFSET_LEN;
+
+ resolveForwardJump(program, nextTermFixup, pc);
+ resolveForwardJump(program, nextAltFixup, pc);
+ break;
+ case REOP_FLAT:
+ /*
+ * Consecutize FLAT's if possible.
+ */
+ if (t.flatIndex != -1) {
+ while ((t.next != null) && (t.next.op == REOP_FLAT)
+ && ((t.flatIndex + t.length)
+ == t.next.flatIndex)) {
+ t.length += t.next.length;
+ t.next = t.next.next;
+ }
+ }
+ if ((t.flatIndex != -1) && (t.length > 1)) {
+ if ((state.flags & JSREG_FOLD) != 0)
+ program[pc - 1] = REOP_FLATi;
+ else
+ program[pc - 1] = REOP_FLAT;
+ pc = addIndex(program, pc, t.flatIndex);
+ pc = addIndex(program, pc, t.length);
+ }
+ else {
+ if (t.chr < 256) {
+ if ((state.flags & JSREG_FOLD) != 0)
+ program[pc - 1] = REOP_FLAT1i;
+ else
+ program[pc - 1] = REOP_FLAT1;
+ program[pc++] = (byte)(t.chr);
+ }
+ else {
+ if ((state.flags & JSREG_FOLD) != 0)
+ program[pc - 1] = REOP_UCFLAT1i;
+ else
+ program[pc - 1] = REOP_UCFLAT1;
+ pc = addIndex(program, pc, t.chr);
+ }
+ }
+ break;
+ case REOP_LPAREN:
+ pc = addIndex(program, pc, t.parenIndex);
+ pc = emitREBytecode(state, re, pc, t.kid);
+ program[pc++] = REOP_RPAREN;
+ pc = addIndex(program, pc, t.parenIndex);
+ break;
+ case REOP_BACKREF:
+ pc = addIndex(program, pc, t.parenIndex);
+ break;
+ case REOP_ASSERT:
+ nextTermFixup = pc;
+ pc += OFFSET_LEN;
+ pc = emitREBytecode(state, re, pc, t.kid);
+ program[pc++] = REOP_ASSERTTEST;
+ resolveForwardJump(program, nextTermFixup, pc);
+ break;
+ case REOP_ASSERT_NOT:
+ nextTermFixup = pc;
+ pc += OFFSET_LEN;
+ pc = emitREBytecode(state, re, pc, t.kid);
+ program[pc++] = REOP_ASSERTNOTTEST;
+ resolveForwardJump(program, nextTermFixup, pc);
+ break;
+ case REOP_QUANT:
+ if ((t.min == 0) && (t.max == -1))
+ program[pc - 1] = (t.greedy) ? REOP_STAR : REOP_MINIMALSTAR;
+ else
+ if ((t.min == 0) && (t.max == 1))
+ program[pc - 1] = (t.greedy) ? REOP_OPT : REOP_MINIMALOPT;
+ else
+ if ((t.min == 1) && (t.max == -1))
+ program[pc - 1] = (t.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;
+ else {
+ if (!t.greedy) program[pc - 1] = REOP_MINIMALQUANT;
+ pc = addIndex(program, pc, t.min);
+ // max can be -1 which addIndex does not accept
+ pc = addIndex(program, pc, t.max + 1);
+ }
+ pc = addIndex(program, pc, t.parenCount);
+ pc = addIndex(program, pc, t.parenIndex);
+ nextTermFixup = pc;
+ pc += OFFSET_LEN;
+ pc = emitREBytecode(state, re, pc, t.kid);
+ program[pc++] = REOP_ENDCHILD;
+ resolveForwardJump(program, nextTermFixup, pc);
+ break;
+ case REOP_CLASS:
+ pc = addIndex(program, pc, t.index);
+ re.classList[t.index] = new RECharSet(t.bmsize, t.startIndex,
+ t.kidlen);
+ break;
+ default:
+ break;
+ }
+ t = t.next;
+ }
+ return pc;
+ }
+
+ private static void
+ pushProgState(REGlobalData gData, int min, int max,
+ REBackTrackData backTrackLastToSave,
+ int continuation_pc, int continuation_op)
+ {
+ gData.stateStackTop = new REProgState(gData.stateStackTop, min, max,
+ gData.cp, backTrackLastToSave,
+ continuation_pc,
+ continuation_op);
+ }
+
+ private static REProgState
+ popProgState(REGlobalData gData)
+ {
+ REProgState state = gData.stateStackTop;
+ gData.stateStackTop = state.previous;
+ return state;
+ }
+
+ private static void
+ pushBackTrackState(REGlobalData gData, byte op, int target)
+ {
+ gData.backTrackStackTop = new REBackTrackData(gData, op, target);
+ }
+
+ /*
+ * Consecutive literal characters.
+ */
+ private static boolean
+ flatNMatcher(REGlobalData gData, int matchChars,
+ int length, char[] chars, int end)
+ {
+ if ((gData.cp + length) > end)
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (gData.regexp.source[matchChars + i] != chars[gData.cp + i]) {
+ return false;
+ }
+ }
+ gData.cp += length;
+ return true;
+ }
+
+ private static boolean
+ flatNIMatcher(REGlobalData gData, int matchChars,
+ int length, char[] chars, int end)
+ {
+ if ((gData.cp + length) > end)
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (upcase(gData.regexp.source[matchChars + i])
+ != upcase(chars[gData.cp + i]))
+ {
+ return false;
+ }
+ }
+ gData.cp += length;
+ return true;
+ }
+
+ /*
+ 1. Evaluate DecimalEscape to obtain an EscapeValue E.
+ 2. If E is not a character then go to step 6.
+ 3. Let ch be E's character.
+ 4. Let A be a one-element RECharSet containing the character ch.
+ 5. Call CharacterSetMatcher(A, false) and return its Matcher result.
+ 6. E must be an integer. Let n be that integer.
+ 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.
+ 8. Return an internal Matcher closure that takes two arguments, a State x
+ and a Continuation c, and performs the following:
+ 1. Let cap be x's captures internal array.
+ 2. Let s be cap[n].
+ 3. If s is undefined, then call c(x) and return its result.
+ 4. Let e be x's endIndex.
+ 5. Let len be s's length.
+ 6. Let f be e+len.
+ 7. If f>InputLength, return failure.
+ 8. If there exists an integer i between 0 (inclusive) and len (exclusive)
+ such that Canonicalize(s[i]) is not the same character as
+ Canonicalize(Input [e+i]), then return failure.
+ 9. Let y be the State (f, cap).
+ 10. Call c(y) and return its result.
+ */
+ private static boolean
+ backrefMatcher(REGlobalData gData, int parenIndex,
+ char[] chars, int end)
+ {
+ int len;
+ int i;
+ int parenContent = gData.parens_index(parenIndex);
+ if (parenContent == -1)
+ return true;
+
+ len = gData.parens_length(parenIndex);
+ if ((gData.cp + len) > end)
+ return false;
+
+ if ((gData.regexp.flags & JSREG_FOLD) != 0) {
+ for (i = 0; i < len; i++) {
+ if (upcase(chars[parenContent + i]) != upcase(chars[gData.cp + i]))
+ return false;
+ }
+ }
+ else {
+ for (i = 0; i < len; i++) {
+ if (chars[parenContent + i] != chars[gData.cp + i])
+ return false;
+ }
+ }
+ gData.cp += len;
+ return true;
+ }
+
+
+ /* Add a single character to the RECharSet */
+ private static void
+ addCharacterToCharSet(RECharSet cs, char c)
+ {
+ int byteIndex = (c / 8);
+ if (c > cs.length)
+ throw new RuntimeException();
+ cs.bits[byteIndex] |= 1 << (c & 0x7);
+ }
+
+
+ /* Add a character range, c1 to c2 (inclusive) to the RECharSet */
+ private static void
+ addCharacterRangeToCharSet(RECharSet cs, char c1, char c2)
+ {
+ int i;
+
+ int byteIndex1 = (c1 / 8);
+ int byteIndex2 = (c2 / 8);
+
+ if ((c2 > cs.length) || (c1 > c2))
+ throw new RuntimeException();
+
+ c1 &= 0x7;
+ c2 &= 0x7;
+
+ if (byteIndex1 == byteIndex2) {
+ cs.bits[byteIndex1] |= ((0xFF) >> (7 - (c2 - c1))) << c1;
+ }
+ else {
+ cs.bits[byteIndex1] |= 0xFF << c1;
+ for (i = byteIndex1 + 1; i < byteIndex2; i++)
+ cs.bits[i] = (byte)0xFF;
+ cs.bits[byteIndex2] |= (0xFF) >> (7 - c2);
+ }
+ }
+
+ /* Compile the source of the class into a RECharSet */
+ private static void
+ processCharSet(REGlobalData gData, RECharSet charSet)
+ {
+ synchronized (charSet) {
+ if (!charSet.converted) {
+ processCharSetImpl(gData, charSet);
+ charSet.converted = true;
+ }
+ }
+ }
+
+
+ private static void
+ processCharSetImpl(REGlobalData gData, RECharSet charSet)
+ {
+ int src = charSet.startIndex;
+ int end = src + charSet.strlength;
+
+ char rangeStart = 0, thisCh;
+ int byteLength;
+ char c;
+ int n;
+ int nDigits;
+ int i;
+ boolean inRange = false;
+
+ charSet.sense = true;
+ byteLength = (charSet.length / 8) + 1;
+ charSet.bits = new byte[byteLength];
+
+ if (src == end)
+ return;
+
+ if (gData.regexp.source[src] == '^') {
+ charSet.sense = false;
+ ++src;
+ }
+
+ while (src != end) {
+ nDigits = 2;
+ switch (gData.regexp.source[src]) {
+ case '\\':
+ ++src;
+ c = gData.regexp.source[src++];
+ switch (c) {
+ case 'b':
+ thisCh = 0x8;
+ break;
+ case 'f':
+ thisCh = 0xC;
+ break;
+ case 'n':
+ thisCh = 0xA;
+ break;
+ case 'r':
+ thisCh = 0xD;
+ break;
+ case 't':
+ thisCh = 0x9;
+ break;
+ case 'v':
+ thisCh = 0xB;
+ break;
+ case 'c':
+ if (((src + 1) < end) && isWord(gData.regexp.source[src + 1]))
+ thisCh = (char)(gData.regexp.source[src++] & 0x1F);
+ else {
+ --src;
+ thisCh = '\\';
+ }
+ break;
+ case 'u':
+ nDigits += 2;
+ // fall thru
+ case 'x':
+ n = 0;
+ for (i = 0; (i < nDigits) && (src < end); i++) {
+ c = gData.regexp.source[src++];
+ int digit = toASCIIHexDigit(c);
+ if (digit < 0) {
+ /* back off to accepting the original '\'
+ * as a literal
+ */
+ src -= (i + 1);
+ n = '\\';
+ break;
+ }
+ n = (n << 4) | digit;
+ }
+ thisCh = (char)(n);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ /*
+ * This is a non-ECMA extension - decimal escapes (in this
+ * case, octal!) are supposed to be an error inside class
+ * ranges, but supported here for backwards compatibility.
+ *
+ */
+ n = (c - '0');
+ c = gData.regexp.source[src];
+ if ('0' <= c && c <= '7') {
+ src++;
+ n = 8 * n + (c - '0');
+ c = gData.regexp.source[src];
+ if ('0' <= c && c <= '7') {
+ src++;
+ i = 8 * n + (c - '0');
+ if (i <= 0377)
+ n = i;
+ else
+ src--;
+ }
+ }
+ thisCh = (char)(n);
+ break;
+
+ case 'd':
+ addCharacterRangeToCharSet(charSet, '0', '9');
+ continue; /* don't need range processing */
+ case 'D':
+ addCharacterRangeToCharSet(charSet, (char)0, (char)('0' - 1));
+ addCharacterRangeToCharSet(charSet, (char)('9' + 1),
+ (char)(charSet.length));
+ continue;
+ case 's':
+ for (i = charSet.length; i >= 0; i--)
+ if (isREWhiteSpace(i))
+ addCharacterToCharSet(charSet, (char)(i));
+ continue;
+ case 'S':
+ for (i = charSet.length; i >= 0; i--)
+ if (!isREWhiteSpace(i))
+ addCharacterToCharSet(charSet, (char)(i));
+ continue;
+ case 'w':
+ for (i = charSet.length; i >= 0; i--)
+ if (isWord((char)i))
+ addCharacterToCharSet(charSet, (char)(i));
+ continue;
+ case 'W':
+ for (i = charSet.length; i >= 0; i--)
+ if (!isWord((char)i))
+ addCharacterToCharSet(charSet, (char)(i));
+ continue;
+ default:
+ thisCh = c;
+ break;
+
+ }
+ break;
+
+ default:
+ thisCh = gData.regexp.source[src++];
+ break;
+
+ }
+ if (inRange) {
+ if ((gData.regexp.flags & JSREG_FOLD) != 0) {
+ addCharacterRangeToCharSet(charSet,
+ upcase(rangeStart),
+ upcase(thisCh));
+ addCharacterRangeToCharSet(charSet,
+ downcase(rangeStart),
+ downcase(thisCh));
+ } else {
+ addCharacterRangeToCharSet(charSet, rangeStart, thisCh);
+ }
+ inRange = false;
+ }
+ else {
+ if ((gData.regexp.flags & JSREG_FOLD) != 0) {
+ addCharacterToCharSet(charSet, upcase(thisCh));
+ addCharacterToCharSet(charSet, downcase(thisCh));
+ } else {
+ addCharacterToCharSet(charSet, thisCh);
+ }
+ if (src < (end - 1)) {
+ if (gData.regexp.source[src] == '-') {
+ ++src;
+ inRange = true;
+ rangeStart = thisCh;
+ }
+ }
+ }
+ }
+ }
+
+
+ /*
+ * Initialize the character set if it this is the first call.
+ * Test the bit - if the ^ flag was specified, non-inclusion is a success
+ */
+ private static boolean
+ classMatcher(REGlobalData gData, RECharSet charSet, char ch)
+ {
+ if (!charSet.converted) {
+ processCharSet(gData, charSet);
+ }
+
+ int byteIndex = ch / 8;
+ if (charSet.sense) {
+ if ((charSet.length == 0) ||
+ ( (ch > charSet.length)
+ || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) ))
+ return false;
+ } else {
+ if (! ((charSet.length == 0) ||
+ ( (ch > charSet.length)
+ || ((charSet.bits[byteIndex] & (1 << (ch & 0x7))) == 0) )))
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean
+ executeREBytecode(REGlobalData gData, char[] chars, int end)
+ {
+ int pc = 0;
+ byte program[] = gData.regexp.program;
+ int currentContinuation_op;
+ int currentContinuation_pc;
+ boolean result = false;
+
+ currentContinuation_pc = 0;
+ currentContinuation_op = REOP_END;
+if (debug) {
+System.out.println("Input = \"" + new String(chars) + "\", start at " + gData.cp);
+}
+ int op = program[pc++];
+ for (;;) {
+if (debug) {
+System.out.println("Testing at " + gData.cp + ", op = " + op);
+}
+ switch (op) {
+ case REOP_EMPTY:
+ result = true;
+ break;
+ case REOP_BOL:
+ if (gData.cp != 0) {
+ if (gData.multiline ||
+ ((gData.regexp.flags & JSREG_MULTILINE) != 0)) {
+ if (!isLineTerm(chars[gData.cp - 1])) {
+ result = false;
+ break;
+ }
+ }
+ else {
+ result = false;
+ break;
+ }
+ }
+ result = true;
+ break;
+ case REOP_EOL:
+ if (gData.cp != end) {
+ if (gData.multiline ||
+ ((gData.regexp.flags & JSREG_MULTILINE) != 0)) {
+ if (!isLineTerm(chars[gData.cp])) {
+ result = false;
+ break;
+ }
+ }
+ else {
+ result = false;
+ break;
+ }
+ }
+ result = true;
+ break;
+ case REOP_WBDRY:
+ result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1]))
+ ^ !((gData.cp < end) && isWord(chars[gData.cp])));
+ break;
+ case REOP_WNONBDRY:
+ result = ((gData.cp == 0 || !isWord(chars[gData.cp - 1]))
+ ^ ((gData.cp < end) && isWord(chars[gData.cp])));
+ break;
+ case REOP_DOT:
+ result = (gData.cp != end && !isLineTerm(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_DIGIT:
+ result = (gData.cp != end && isDigit(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_NONDIGIT:
+ result = (gData.cp != end && !isDigit(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_SPACE:
+ result = (gData.cp != end && isREWhiteSpace(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_NONSPACE:
+ result = (gData.cp != end && !isREWhiteSpace(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_ALNUM:
+ result = (gData.cp != end && isWord(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_NONALNUM:
+ result = (gData.cp != end && !isWord(chars[gData.cp]));
+ if (result) {
+ gData.cp++;
+ }
+ break;
+ case REOP_FLAT:
+ {
+ int offset = getIndex(program, pc);
+ pc += INDEX_LEN;
+ int length = getIndex(program, pc);
+ pc += INDEX_LEN;
+ result = flatNMatcher(gData, offset, length, chars, end);
+ }
+ break;
+ case REOP_FLATi:
+ {
+ int offset = getIndex(program, pc);
+ pc += INDEX_LEN;
+ int length = getIndex(program, pc);
+ pc += INDEX_LEN;
+ result = flatNIMatcher(gData, offset, length, chars, end);
+ }
+ break;
+ case REOP_FLAT1:
+ {
+ char matchCh = (char)(program[pc++] & 0xFF);
+ result = (gData.cp != end && chars[gData.cp] == matchCh);
+ if (result) {
+ gData.cp++;
+ }
+ }
+ break;
+ case REOP_FLAT1i:
+ {
+ char matchCh = (char)(program[pc++] & 0xFF);
+ result = (gData.cp != end
+ && upcase(chars[gData.cp]) == upcase(matchCh));
+ if (result) {
+ gData.cp++;
+ }
+ }
+ break;
+ case REOP_UCFLAT1:
+ {
+ char matchCh = (char)getIndex(program, pc);
+ pc += INDEX_LEN;
+ result = (gData.cp != end && chars[gData.cp] == matchCh);
+ if (result) {
+ gData.cp++;
+ }
+ }
+ break;
+ case REOP_UCFLAT1i:
+ {
+ char matchCh = (char)getIndex(program, pc);
+ pc += INDEX_LEN;
+ result = (gData.cp != end
+ && upcase(chars[gData.cp]) == upcase(matchCh));
+ if (result) {
+ gData.cp++;
+ }
+ }
+ break;
+ case REOP_ALT:
+ {
+ int nextpc;
+ byte nextop;
+ pushProgState(gData, 0, 0, null,
+ currentContinuation_pc,
+ currentContinuation_op);
+ nextpc = pc + getOffset(program, pc);
+ nextop = program[nextpc++];
+ pushBackTrackState(gData, nextop, nextpc);
+ pc += INDEX_LEN;
+ op = program[pc++];
+ }
+ continue;
+
+ case REOP_JUMP:
+ {
+ int offset;
+ REProgState state = popProgState(gData);
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ offset = getOffset(program, pc);
+ pc += offset;
+ op = program[pc++];
+ }
+ continue;
+
+
+ case REOP_LPAREN:
+ {
+ int parenIndex = getIndex(program, pc);
+ pc += INDEX_LEN;
+ gData.set_parens(parenIndex, gData.cp, 0);
+ op = program[pc++];
+ }
+ continue;
+ case REOP_RPAREN:
+ {
+ int cap_index;
+ int parenIndex = getIndex(program, pc);
+ pc += INDEX_LEN;
+ cap_index = gData.parens_index(parenIndex);
+ gData.set_parens(parenIndex, cap_index,
+ gData.cp - cap_index);
+ if (parenIndex > gData.lastParen)
+ gData.lastParen = parenIndex;
+ op = program[pc++];
+ }
+ continue;
+ case REOP_BACKREF:
+ {
+ int parenIndex = getIndex(program, pc);
+ pc += INDEX_LEN;
+ result = backrefMatcher(gData, parenIndex, chars, end);
+ }
+ break;
+
+ case REOP_CLASS:
+ {
+ int index = getIndex(program, pc);
+ pc += INDEX_LEN;
+ if (gData.cp != end) {
+ if (classMatcher(gData, gData.regexp.classList[index],
+ chars[gData.cp]))
+ {
+ gData.cp++;
+ result = true;
+ break;
+ }
+ }
+ result = false;
+ }
+ break;
+
+ case REOP_ASSERT:
+ case REOP_ASSERT_NOT:
+ {
+ byte testOp;
+ pushProgState(gData, 0, 0, gData.backTrackStackTop,
+ currentContinuation_pc,
+ currentContinuation_op);
+ if (op == REOP_ASSERT) {
+ testOp = REOP_ASSERTTEST;
+ } else {
+ testOp = REOP_ASSERTNOTTEST;
+ }
+ pushBackTrackState(gData, testOp,
+ pc + getOffset(program, pc));
+ pc += INDEX_LEN;
+ op = program[pc++];
+ }
+ continue;
+
+ case REOP_ASSERTTEST:
+ case REOP_ASSERTNOTTEST:
+ {
+ REProgState state = popProgState(gData);
+ gData.cp = state.index;
+ gData.backTrackStackTop = state.backTrack;
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ if (result) {
+ if (op == REOP_ASSERTTEST) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else {
+ if (op == REOP_ASSERTTEST) {
+ // Do nothing
+ } else {
+ result = true;
+ }
+ }
+ }
+ break;
+
+ case REOP_STAR:
+ case REOP_PLUS:
+ case REOP_OPT:
+ case REOP_QUANT:
+ case REOP_MINIMALSTAR:
+ case REOP_MINIMALPLUS:
+ case REOP_MINIMALOPT:
+ case REOP_MINIMALQUANT:
+ {
+ int min, max;
+ boolean greedy = false;
+ switch (op) {
+ case REOP_STAR:
+ greedy = true;
+ // fallthrough
+ case REOP_MINIMALSTAR:
+ min = 0;
+ max = -1;
+ break;
+ case REOP_PLUS:
+ greedy = true;
+ // fallthrough
+ case REOP_MINIMALPLUS:
+ min = 1;
+ max = -1;
+ break;
+ case REOP_OPT:
+ greedy = true;
+ // fallthrough
+ case REOP_MINIMALOPT:
+ min = 0;
+ max = 1;
+ break;
+ case REOP_QUANT:
+ greedy = true;
+ // fallthrough
+ case REOP_MINIMALQUANT:
+ min = getOffset(program, pc);
+ pc += INDEX_LEN;
+ // See comments in emitREBytecode for " - 1" reason
+ max = getOffset(program, pc) - 1;
+ pc += INDEX_LEN;
+ break;
+ default:
+ throw Kit.codeBug();
+ }
+ pushProgState(gData, min, max, null,
+ currentContinuation_pc,
+ currentContinuation_op);
+ if (greedy) {
+ currentContinuation_op = REOP_REPEAT;
+ currentContinuation_pc = pc;
+ pushBackTrackState(gData, REOP_REPEAT, pc);
+ /* Step over <parencount>, <parenindex> & <next> */
+ pc += 3 * INDEX_LEN;
+ op = program[pc++];
+ } else {
+ if (min != 0) {
+ currentContinuation_op = REOP_MINIMALREPEAT;
+ currentContinuation_pc = pc;
+ /* <parencount> <parenindex> & <next> */
+ pc += 3 * INDEX_LEN;
+ op = program[pc++];
+ } else {
+ pushBackTrackState(gData, REOP_MINIMALREPEAT, pc);
+ popProgState(gData);
+ pc += 2 * INDEX_LEN; // <parencount> & <parenindex>
+ pc = pc + getOffset(program, pc);
+ op = program[pc++];
+ }
+ }
+ }
+ continue;
+
+ case REOP_ENDCHILD:
+ // Use the current continuation.
+ pc = currentContinuation_pc;
+ op = currentContinuation_op;
+ continue;
+
+ case REOP_REPEAT:
+ {
+ REProgState state = popProgState(gData);
+ if (!result) {
+ //
+ // There's been a failure, see if we have enough
+ // children.
+ //
+ if (state.min == 0)
+ result = true;
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ pc += 2 * INDEX_LEN; /* <parencount> & <parenindex> */
+ pc = pc + getOffset(program, pc);
+ break;
+ }
+ else {
+ if (state.min == 0 && gData.cp == state.index) {
+ // matched an empty string, that'll get us nowhere
+ result = false;
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ pc += 2 * INDEX_LEN;
+ pc = pc + getOffset(program, pc);
+ break;
+ }
+ int new_min = state.min, new_max = state.max;
+ if (new_min != 0) new_min--;
+ if (new_max != -1) new_max--;
+ if (new_max == 0) {
+ result = true;
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ pc += 2 * INDEX_LEN;
+ pc = pc + getOffset(program, pc);
+ break;
+ }
+ pushProgState(gData, new_min, new_max, null,
+ state.continuation_pc,
+ state.continuation_op);
+ currentContinuation_op = REOP_REPEAT;
+ currentContinuation_pc = pc;
+ pushBackTrackState(gData, REOP_REPEAT, pc);
+ int parenCount = getIndex(program, pc);
+ pc += INDEX_LEN;
+ int parenIndex = getIndex(program, pc);
+ pc += 2 * INDEX_LEN;
+ op = program[pc++];
+ for (int k = 0; k < parenCount; k++) {
+ gData.set_parens(parenIndex + k, -1, 0);
+ }
+ }
+ }
+ continue;
+
+ case REOP_MINIMALREPEAT:
+ {
+ REProgState state = popProgState(gData);
+ if (!result) {
+ //
+ // Non-greedy failure - try to consume another child.
+ //
+ if (state.max == -1 || state.max > 0) {
+ pushProgState(gData, state.min, state.max, null,
+ state.continuation_pc,
+ state.continuation_op);
+ currentContinuation_op = REOP_MINIMALREPEAT;
+ currentContinuation_pc = pc;
+ int parenCount = getIndex(program, pc);
+ pc += INDEX_LEN;
+ int parenIndex = getIndex(program, pc);
+ pc += 2 * INDEX_LEN;
+ for (int k = 0; k < parenCount; k++) {
+ gData.set_parens(parenIndex + k, -1, 0);
+ }
+ op = program[pc++];
+ continue;
+ } else {
+ // Don't need to adjust pc since we're going to pop.
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ break;
+ }
+ } else {
+ if (state.min == 0 && gData.cp == state.index) {
+ // Matched an empty string, that'll get us nowhere.
+ result = false;
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ break;
+ }
+ int new_min = state.min, new_max = state.max;
+ if (new_min != 0) new_min--;
+ if (new_max != -1) new_max--;
+ pushProgState(gData, new_min, new_max, null,
+ state.continuation_pc,
+ state.continuation_op);
+ if (new_min != 0) {
+ currentContinuation_op = REOP_MINIMALREPEAT;
+ currentContinuation_pc = pc;
+ int parenCount = getIndex(program, pc);
+ pc += INDEX_LEN;
+ int parenIndex = getIndex(program, pc);
+ pc += 2 * INDEX_LEN;
+ for (int k = 0; k < parenCount; k++) {
+ gData.set_parens(parenIndex + k, -1, 0);
+ }
+ op = program[pc++];
+ } else {
+ currentContinuation_pc = state.continuation_pc;
+ currentContinuation_op = state.continuation_op;
+ pushBackTrackState(gData, REOP_MINIMALREPEAT, pc);
+ popProgState(gData);
+ pc += 2 * INDEX_LEN;
+ pc = pc + getOffset(program, pc);
+ op = program[pc++];
+ }
+ continue;
+ }
+ }
+
+ case REOP_END:
+ return true;
+
+ default:
+ throw Kit.codeBug();
+
+ }
+ /*
+ * If the match failed and there's a backtrack option, take it.
+ * Otherwise this is a complete and utter failure.
+ */
+ if (!result) {
+ REBackTrackData backTrackData = gData.backTrackStackTop;
+ if (backTrackData != null) {
+ gData.backTrackStackTop = backTrackData.previous;
+
+ gData.lastParen = backTrackData.lastParen;
+
+ // XXX: If backTrackData will no longer be used, then
+ // there is no need to clone backTrackData.parens
+ if (backTrackData.parens != null) {
+ gData.parens = backTrackData.parens.clone();
+ }
+
+ gData.cp = backTrackData.cp;
+
+ gData.stateStackTop = backTrackData.stateStackTop;
+
+ currentContinuation_op
+ = gData.stateStackTop.continuation_op;
+ currentContinuation_pc
+ = gData.stateStackTop.continuation_pc;
+ pc = backTrackData.continuation_pc;
+ op = backTrackData.continuation_op;
+ continue;
+ }
+ else
+ return false;
+ }
+
+ op = program[pc++];
+ }
+
+ }
+
+ private static boolean
+ matchRegExp(REGlobalData gData, RECompiled re,
+ char[] chars, int start, int end, boolean multiline)
+ {
+ if (re.parenCount != 0) {
+ gData.parens = new long[re.parenCount];
+ } else {
+ gData.parens = null;
+ }
+
+ gData.backTrackStackTop = null;
+
+ gData.stateStackTop = null;
+
+ gData.multiline = multiline;
+ gData.regexp = re;
+ gData.lastParen = 0;
+
+ int anchorCh = gData.regexp.anchorCh;
+ //
+ // have to include the position beyond the last character
+ // in order to detect end-of-input/line condition
+ //
+ for (int i = start; i <= end; ++i) {
+ //
+ // If the first node is a literal match, step the index into
+ // the string until that match is made, or fail if it can't be
+ // found at all.
+ //
+ if (anchorCh >= 0) {
+ for (;;) {
+ if (i == end) {
+ return false;
+ }
+ char matchCh = chars[i];
+ if (matchCh == anchorCh ||
+ ((gData.regexp.flags & JSREG_FOLD) != 0
+ && upcase(matchCh) == upcase((char)anchorCh)))
+ {
+ break;
+ }
+ ++i;
+ }
+ }
+ gData.cp = i;
+ for (int j = 0; j < re.parenCount; j++) {
+ gData.set_parens(j, -1, 0);
+ }
+ boolean result = executeREBytecode(gData, chars, end);
+
+ gData.backTrackStackTop = null;
+ gData.stateStackTop = null;
+ if (result) {
+ gData.skipped = i - start;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * indexp is assumed to be an array of length 1
+ */
+ Object executeRegExp(Context cx, Scriptable scopeObj, RegExpImpl res,
+ String str, int indexp[], int matchType)
+ {
+ REGlobalData gData = new REGlobalData();
+
+ int start = indexp[0];
+ char[] charArray = str.toCharArray();
+ int end = charArray.length;
+ if (start > end)
+ start = end;
+ //
+ // Call the recursive matcher to do the real work.
+ //
+ boolean matches = matchRegExp(gData, re, charArray, start, end,
+ res.multiline);
+ if (!matches) {
+ if (matchType != PREFIX) return null;
+ return Undefined.instance;
+ }
+ int index = gData.cp;
+ int i = index;
+ indexp[0] = i;
+ int matchlen = i - (start + gData.skipped);
+ int ep = index;
+ index -= matchlen;
+ Object result;
+ Scriptable obj;
+
+ if (matchType == TEST) {
+ /*
+ * Testing for a match and updating cx.regExpImpl: don't allocate
+ * an array object, do return true.
+ */
+ result = Boolean.TRUE;
+ obj = null;
+ }
+ else {
+ /*
+ * The array returned on match has element 0 bound to the matched
+ * string, elements 1 through re.parenCount bound to the paren
+ * matches, an index property telling the length of the left context,
+ * and an input property referring to the input string.
+ */
+ Scriptable scope = getTopLevelScope(scopeObj);
+ result = ScriptRuntime.newObject(cx, scope, "Array", null);
+ obj = (Scriptable) result;
+
+ String matchstr = new String(charArray, index, matchlen);
+ obj.put(0, obj, matchstr);
+ }
+
+ if (re.parenCount == 0) {
+ res.parens = null;
+ res.lastParen = SubString.emptySubString;
+ } else {
+ SubString parsub = null;
+ int num;
+ res.parens = new SubString[re.parenCount];
+ for (num = 0; num < re.parenCount; num++) {
+ int cap_index = gData.parens_index(num);
+ String parstr;
+ if (cap_index != -1) {
+ int cap_length = gData.parens_length(num);
+ parsub = new SubString(charArray, cap_index, cap_length);
+ res.parens[num] = parsub;
+ if (matchType == TEST) continue;
+ parstr = parsub.toString();
+ obj.put(num+1, obj, parstr);
+ }
+ else {
+ if (matchType != TEST)
+ obj.put(num+1, obj, Undefined.instance);
+ }
+ }
+ res.lastParen = parsub;
+ }
+
+ if (! (matchType == TEST)) {
+ /*
+ * Define the index and input properties last for better for/in loop
+ * order (so they come after the elements).
+ */
+ obj.put("index", obj, new Integer(start + gData.skipped));
+ obj.put("input", obj, str);
+ }
+
+ if (res.lastMatch == null) {
+ res.lastMatch = new SubString();
+ res.leftContext = new SubString();
+ res.rightContext = new SubString();
+ }
+ res.lastMatch.charArray = charArray;
+ res.lastMatch.index = index;
+ res.lastMatch.length = matchlen;
+
+ res.leftContext.charArray = charArray;
+ if (cx.getLanguageVersion() == Context.VERSION_1_2) {
+ /*
+ * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
+ * in scalar contexts, and unintentionally for the string.match "list"
+ * psuedo-context. On "hi there bye", the following would result:
+ *
+ * Language while(/ /g){print("$`");} s/ /$`/g
+ * perl4.036 "hi", "there" "hihitherehi therebye"
+ * perl5 "hi", "hi there" "hihitherehi therebye"
+ * js1.2 "hi", "there" "hihitheretherebye"
+ *
+ * Insofar as JS1.2 always defined $` as "left context from the last
+ * match" for global regexps, it was more consistent than perl4.
+ */
+ res.leftContext.index = start;
+ res.leftContext.length = gData.skipped;
+ } else {
+ /*
+ * For JS1.3 and ECMAv2, emulate Perl5 exactly:
+ *
+ * js1.3 "hi", "hi there" "hihitherehi therebye"
+ */
+ res.leftContext.index = 0;
+ res.leftContext.length = start + gData.skipped;
+ }
+
+ res.rightContext.charArray = charArray;
+ res.rightContext.index = ep;
+ res.rightContext.length = end - ep;
+
+ return result;
+ }
+
+ int getFlags()
+ {
+ return re.flags;
+ }
+
+ private static void reportWarning(Context cx, String messageId, String arg)
+ {
+ if (cx.hasFeature(Context.FEATURE_STRICT_MODE)) {
+ String msg = ScriptRuntime.getMessage1(messageId, arg);
+ Context.reportWarning(msg);
+ }
+ }
+
+ private static void reportError(String messageId, String arg)
+ {
+ String msg = ScriptRuntime.getMessage1(messageId, arg);
+ throw ScriptRuntime.constructError("SyntaxError", msg);
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_lastIndex = 1,
+ Id_source = 2,
+ Id_global = 3,
+ Id_ignoreCase = 4,
+ Id_multiline = 5,
+
+ MAX_INSTANCE_ID = 5;
+
+ protected int getMaxInstanceId()
+ {
+ return MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:16:24 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==6) {
+ c=s.charAt(0);
+ if (c=='g') { X="global";id=Id_global; }
+ else if (c=='s') { X="source";id=Id_source; }
+ }
+ else if (s_length==9) {
+ c=s.charAt(0);
+ if (c=='l') { X="lastIndex";id=Id_lastIndex; }
+ else if (c=='m') { X="multiline";id=Id_multiline; }
+ }
+ else if (s_length==10) { X="ignoreCase";id=Id_ignoreCase; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+// #/string_id_map#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_lastIndex:
+ attr = PERMANENT | DONTENUM;
+ break;
+ case Id_source:
+ case Id_global:
+ case Id_ignoreCase:
+ case Id_multiline:
+ attr = PERMANENT | READONLY | DONTENUM;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, id);
+ }
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id) {
+ case Id_lastIndex: return "lastIndex";
+ case Id_source: return "source";
+ case Id_global: return "global";
+ case Id_ignoreCase: return "ignoreCase";
+ case Id_multiline: return "multiline";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id) {
+ case Id_lastIndex:
+ return ScriptRuntime.wrapNumber(lastIndex);
+ case Id_source:
+ return new String(re.source);
+ case Id_global:
+ return ScriptRuntime.wrapBoolean((re.flags & JSREG_GLOB) != 0);
+ case Id_ignoreCase:
+ return ScriptRuntime.wrapBoolean((re.flags & JSREG_FOLD) != 0);
+ case Id_multiline:
+ return ScriptRuntime.wrapBoolean((re.flags & JSREG_MULTILINE) != 0);
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ if (id == Id_lastIndex) {
+ lastIndex = ScriptRuntime.toNumber(value);
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_compile: arity=1; s="compile"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ case Id_exec: arity=1; s="exec"; break;
+ case Id_test: arity=1; s="test"; break;
+ case Id_prefix: arity=1; s="prefix"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(REGEXP_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(REGEXP_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_compile:
+ return realThis(thisObj, f).compile(cx, scope, args);
+
+ case Id_toString:
+ case Id_toSource:
+ return realThis(thisObj, f).toString();
+
+ case Id_exec:
+ return realThis(thisObj, f).execSub(cx, scope, args, MATCH);
+
+ case Id_test: {
+ Object x = realThis(thisObj, f).execSub(cx, scope, args, TEST);
+ return Boolean.TRUE.equals(x) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ case Id_prefix:
+ return realThis(thisObj, f).execSub(cx, scope, args, PREFIX);
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static NativeRegExp realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if (!(thisObj instanceof NativeRegExp))
+ throw incompatibleCallError(f);
+ return (NativeRegExp)thisObj;
+ }
+
+// #string_id_map#
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-05-09 08:16:24 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 4: c=s.charAt(0);
+ if (c=='e') { X="exec";id=Id_exec; }
+ else if (c=='t') { X="test";id=Id_test; }
+ break L;
+ case 6: X="prefix";id=Id_prefix; break L;
+ case 7: X="compile";id=Id_compile; break L;
+ case 8: c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+
+ private static final int
+ Id_compile = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ Id_exec = 4,
+ Id_test = 5,
+ Id_prefix = 6,
+
+ MAX_PROTOTYPE_ID = 6;
+
+// #/string_id_map#
+
+ private RECompiled re;
+ double lastIndex; /* index after last match, for //g iterator */
+
+} // class NativeRegExp
+
+class RECompiled implements Serializable
+{
+ static final long serialVersionUID = -6144956577595844213L;
+
+ char []source; /* locked source string, sans // */
+ int parenCount; /* number of parenthesized submatches */
+ int flags; /* flags */
+ byte[] program; /* regular expression bytecode */
+ int classCount; /* count [...] bitmaps */
+ RECharSet[] classList; /* list of [...] bitmaps */
+ int anchorCh = -1; /* if >= 0, then re starts with this literal char */
+}
+
+class RENode {
+
+ RENode(byte op)
+ {
+ this.op = op;
+ }
+
+ byte op; /* r.e. op bytecode */
+ RENode next; /* next in concatenation order */
+ RENode kid; /* first operand */
+
+ RENode kid2; /* second operand */
+ int num; /* could be a number */
+ int parenIndex; /* or a parenthesis index */
+
+ /* or a range */
+ int min;
+ int max;
+ int parenCount;
+ boolean greedy;
+
+ /* or a character class */
+ int startIndex;
+ int kidlen; /* length of string at kid, in chars */
+ int bmsize; /* bitmap size, based on max char code */
+ int index; /* index into class list */
+
+ /* or a literal sequence */
+ char chr; /* of one character */
+ int length; /* or many (via the index) */
+ int flatIndex; /* which is -1 if not sourced */
+
+}
+
+class CompilerState {
+
+ CompilerState(Context cx, char[] source, int length, int flags)
+ {
+ this.cx = cx;
+ this.cpbegin = source;
+ this.cp = 0;
+ this.cpend = length;
+ this.flags = flags;
+ this.parenCount = 0;
+ this.classCount = 0;
+ this.progLength = 0;
+ }
+
+ Context cx;
+ char cpbegin[];
+ int cpend;
+ int cp;
+ int flags;
+ int parenCount;
+ int parenNesting;
+ int classCount; /* number of [] encountered */
+ int progLength; /* estimated bytecode length */
+ RENode result;
+}
+
+class REProgState
+{
+ REProgState(REProgState previous, int min, int max, int index,
+ REBackTrackData backTrack,
+ int continuation_pc, int continuation_op)
+ {
+ this.previous = previous;
+ this.min = min;
+ this.max = max;
+ this.index = index;
+ this.continuation_op = continuation_op;
+ this.continuation_pc = continuation_pc;
+ this.backTrack = backTrack;
+ }
+
+ REProgState previous; // previous state in stack
+
+ int min; /* current quantifier min */
+ int max; /* current quantifier max */
+ int index; /* progress in text */
+ int continuation_op;
+ int continuation_pc;
+ REBackTrackData backTrack; // used by ASSERT_ to recover state
+}
+
+class REBackTrackData {
+
+ REBackTrackData(REGlobalData gData, int op, int pc)
+ {
+ previous = gData.backTrackStackTop;
+ continuation_op = op;
+ continuation_pc = pc;
+ lastParen = gData.lastParen;
+ if (gData.parens != null) {
+ parens = gData.parens.clone();
+ }
+ cp = gData.cp;
+ stateStackTop = gData.stateStackTop;
+ }
+
+ REBackTrackData previous;
+
+ int continuation_op; /* where to backtrack to */
+ int continuation_pc;
+ int lastParen;
+ long[] parens; /* parenthesis captures */
+ int cp; /* char buffer index */
+ REProgState stateStackTop; /* state of op that backtracked */
+}
+
+class REGlobalData {
+ boolean multiline;
+ RECompiled regexp; /* the RE in execution */
+ int lastParen; /* highest paren set so far */
+ int skipped; /* chars skipped anchoring this r.e. */
+
+ int cp; /* char buffer index */
+ long[] parens; /* parens captures */
+
+ REProgState stateStackTop; /* stack of state of current ancestors */
+
+ REBackTrackData backTrackStackTop; /* last matched-so-far position */
+
+
+ /**
+ * Get start of parenthesis capture contents, -1 for empty.
+ */
+ int parens_index(int i)
+ {
+ return (int)(parens[i]);
+ }
+
+ /**
+ * Get length of parenthesis capture contents.
+ */
+ int parens_length(int i)
+ {
+ return (int)(parens[i] >>> 32);
+ }
+
+ void set_parens(int i, int index, int length)
+ {
+ parens[i] = (index & 0xffffffffL) | ((long)length << 32);
+ }
+
+}
+
+/*
+ * This struct holds a bitmap representation of a class from a regexp.
+ * There's a list of these referenced by the classList field in the NativeRegExp
+ * struct below. The initial state has startIndex set to the offset in the
+ * original regexp source of the beginning of the class contents. The first
+ * use of the class converts the source representation into a bitmap.
+ *
+ */
+final class RECharSet implements Serializable
+{
+ static final long serialVersionUID = 7931787979395898394L;
+
+ RECharSet(int length, int startIndex, int strlength)
+ {
+ this.length = length;
+ this.startIndex = startIndex;
+ this.strlength = strlength;
+ }
+
+ int length;
+ int startIndex;
+ int strlength;
+
+ volatile transient boolean converted;
+ volatile transient boolean sense;
+ volatile transient byte[] bits;
+}
+
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java
new file mode 100644
index 0000000..808d62d
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java
@@ -0,0 +1,289 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Brendan Eich
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.regexp;
+
+import org.mozilla.javascript.*;
+
+/**
+ * This class implements the RegExp constructor native object.
+ *
+ * Revision History:
+ * Implementation in C by Brendan Eich
+ * Initial port to Java by Norris Boyd from jsregexp.c version 1.36
+ * Merged up to version 1.38, which included Unicode support.
+ * Merged bug fixes in version 1.39.
+ * Merged JSFUN13_BRANCH changes up to 1.32.2.11
+ *
+ * @author Brendan Eich
+ * @author Norris Boyd
+ */
+class NativeRegExpCtor extends BaseFunction
+{
+ static final long serialVersionUID = -5733330028285400526L;
+
+ NativeRegExpCtor()
+ {
+ }
+
+ public String getFunctionName()
+ {
+ return "RegExp";
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args)
+ {
+ if (args.length > 0 && args[0] instanceof NativeRegExp &&
+ (args.length == 1 || args[1] == Undefined.instance))
+ {
+ return args[0];
+ }
+ return construct(cx, scope, args);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args)
+ {
+ NativeRegExp re = new NativeRegExp();
+ re.compile(cx, scope, args);
+ ScriptRuntime.setObjectProtoAndParent(re, scope);
+ return re;
+ }
+
+ private static RegExpImpl getImpl()
+ {
+ Context cx = Context.getCurrentContext();
+ return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_multiline = 1,
+ Id_STAR = 2, // #string=$*#
+
+ Id_input = 3,
+ Id_UNDERSCORE = 4, // #string=$_#
+
+ Id_lastMatch = 5,
+ Id_AMPERSAND = 6, // #string=$&#
+
+ Id_lastParen = 7,
+ Id_PLUS = 8, // #string=$+#
+
+ Id_leftContext = 9,
+ Id_BACK_QUOTE = 10, // #string=$`#
+
+ Id_rightContext = 11,
+ Id_QUOTE = 12, // #string=$'#
+
+ DOLLAR_ID_BASE = 12;
+
+ private static final int
+ Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1#
+ Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2#
+ Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3#
+ Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4#
+ Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5#
+ Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6#
+ Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7#
+ Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8#
+ Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9#
+
+ MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s) {
+ int id;
+// #generated# Last update: 2001-05-24 16:09:31 GMT+02:00
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: switch (s.charAt(1)) {
+ case '&': if (s.charAt(0)=='$') {id=Id_AMPERSAND; break L0;} break L;
+ case '\'': if (s.charAt(0)=='$') {id=Id_QUOTE; break L0;} break L;
+ case '*': if (s.charAt(0)=='$') {id=Id_STAR; break L0;} break L;
+ case '+': if (s.charAt(0)=='$') {id=Id_PLUS; break L0;} break L;
+ case '1': if (s.charAt(0)=='$') {id=Id_DOLLAR_1; break L0;} break L;
+ case '2': if (s.charAt(0)=='$') {id=Id_DOLLAR_2; break L0;} break L;
+ case '3': if (s.charAt(0)=='$') {id=Id_DOLLAR_3; break L0;} break L;
+ case '4': if (s.charAt(0)=='$') {id=Id_DOLLAR_4; break L0;} break L;
+ case '5': if (s.charAt(0)=='$') {id=Id_DOLLAR_5; break L0;} break L;
+ case '6': if (s.charAt(0)=='$') {id=Id_DOLLAR_6; break L0;} break L;
+ case '7': if (s.charAt(0)=='$') {id=Id_DOLLAR_7; break L0;} break L;
+ case '8': if (s.charAt(0)=='$') {id=Id_DOLLAR_8; break L0;} break L;
+ case '9': if (s.charAt(0)=='$') {id=Id_DOLLAR_9; break L0;} break L;
+ case '_': if (s.charAt(0)=='$') {id=Id_UNDERSCORE; break L0;} break L;
+ case '`': if (s.charAt(0)=='$') {id=Id_BACK_QUOTE; break L0;} break L;
+ } break L;
+ case 5: X="input";id=Id_input; break L;
+ case 9: c=s.charAt(4);
+ if (c=='M') { X="lastMatch";id=Id_lastMatch; }
+ else if (c=='P') { X="lastParen";id=Id_lastParen; }
+ else if (c=='i') { X="multiline";id=Id_multiline; }
+ break L;
+ case 11: X="leftContext";id=Id_leftContext; break L;
+ case 12: X="rightContext";id=Id_rightContext; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_multiline:
+ case Id_STAR:
+ case Id_input:
+ case Id_UNDERSCORE:
+ attr = PERMANENT;
+ break;
+ default:
+ attr = PERMANENT | READONLY;
+ break;
+ }
+
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ int shifted = id - super.getMaxInstanceId();
+ if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
+ switch (shifted) {
+ case Id_multiline: return "multiline";
+ case Id_STAR: return "$*";
+
+ case Id_input: return "input";
+ case Id_UNDERSCORE: return "$_";
+
+ case Id_lastMatch: return "lastMatch";
+ case Id_AMPERSAND: return "$&";
+
+ case Id_lastParen: return "lastParen";
+ case Id_PLUS: return "$+";
+
+ case Id_leftContext: return "leftContext";
+ case Id_BACK_QUOTE: return "$`";
+
+ case Id_rightContext: return "rightContext";
+ case Id_QUOTE: return "$'";
+ }
+ // Must be one of $1..$9, convert to 0..8
+ int substring_number = shifted - DOLLAR_ID_BASE - 1;
+ char[] buf = { '$', (char)('1' + substring_number) };
+ return new String(buf);
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ int shifted = id - super.getMaxInstanceId();
+ if (1 <= shifted && shifted <= MAX_INSTANCE_ID) {
+ RegExpImpl impl = getImpl();
+ Object stringResult;
+ switch (shifted) {
+ case Id_multiline:
+ case Id_STAR:
+ return ScriptRuntime.wrapBoolean(impl.multiline);
+
+ case Id_input:
+ case Id_UNDERSCORE:
+ stringResult = impl.input;
+ break;
+
+ case Id_lastMatch:
+ case Id_AMPERSAND:
+ stringResult = impl.lastMatch;
+ break;
+
+ case Id_lastParen:
+ case Id_PLUS:
+ stringResult = impl.lastParen;
+ break;
+
+ case Id_leftContext:
+ case Id_BACK_QUOTE:
+ stringResult = impl.leftContext;
+ break;
+
+ case Id_rightContext:
+ case Id_QUOTE:
+ stringResult = impl.rightContext;
+ break;
+
+ default:
+ {
+ // Must be one of $1..$9, convert to 0..8
+ int substring_number = shifted - DOLLAR_ID_BASE - 1;
+ stringResult = impl.getParenSubString(substring_number);
+ break;
+ }
+ }
+ return (stringResult == null) ? "" : stringResult.toString();
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value)
+ {
+ int shifted = id - super.getMaxInstanceId();
+ switch (shifted) {
+ case Id_multiline:
+ case Id_STAR:
+ getImpl().multiline = ScriptRuntime.toBoolean(value);
+ return;
+
+ case Id_input:
+ case Id_UNDERSCORE:
+ getImpl().input = ScriptRuntime.toString(value);
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java
new file mode 100644
index 0000000..4b0a303
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/RegExpImpl.java
@@ -0,0 +1,541 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.regexp;
+
+import org.mozilla.javascript.*;
+
+/**
+ *
+ */
+public class RegExpImpl implements RegExpProxy {
+
+ public boolean isRegExp(Scriptable obj) {
+ return obj instanceof NativeRegExp;
+ }
+
+ public Object compileRegExp(Context cx, String source, String flags)
+ {
+ return NativeRegExp.compileRE(cx, source, flags, false);
+ }
+
+ public Scriptable wrapRegExp(Context cx, Scriptable scope,
+ Object compiled)
+ {
+ return new NativeRegExp(scope, compiled);
+ }
+
+ public Object action(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args,
+ int actionType)
+ {
+ GlobData data = new GlobData();
+ data.mode = actionType;
+
+ switch (actionType) {
+ case RA_MATCH:
+ {
+ Object rval;
+ data.optarg = 1;
+ rval = matchOrReplace(cx, scope, thisObj, args,
+ this, data, false);
+ return data.arrayobj == null ? rval : data.arrayobj;
+ }
+
+ case RA_SEARCH:
+ data.optarg = 1;
+ return matchOrReplace(cx, scope, thisObj, args,
+ this, data, false);
+
+ case RA_REPLACE:
+ {
+ Object arg1 = args.length < 2 ? Undefined.instance : args[1];
+ String repstr = null;
+ Function lambda = null;
+ if (arg1 instanceof Function) {
+ lambda = (Function) arg1;
+ } else {
+ repstr = ScriptRuntime.toString(arg1);
+ }
+
+ data.optarg = 2;
+ data.lambda = lambda;
+ data.repstr = repstr;
+ data.dollar = repstr == null ? -1 : repstr.indexOf('$');
+ data.charBuf = null;
+ data.leftIndex = 0;
+ Object val = matchOrReplace(cx, scope, thisObj, args,
+ this, data, true);
+ SubString rc = this.rightContext;
+
+ if (data.charBuf == null) {
+ if (data.global || val == null
+ || !val.equals(Boolean.TRUE))
+ {
+ /* Didn't match even once. */
+ return data.str;
+ }
+ SubString lc = this.leftContext;
+ replace_glob(data, cx, scope, this, lc.index, lc.length);
+ }
+ data.charBuf.append(rc.charArray, rc.index, rc.length);
+ return data.charBuf.toString();
+ }
+
+ default:
+ throw Kit.codeBug();
+ }
+ }
+
+ /**
+ * Analog of C match_or_replace.
+ */
+ private static Object matchOrReplace(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args,
+ RegExpImpl reImpl,
+ GlobData data, boolean forceFlat)
+ {
+ NativeRegExp re;
+
+ String str = ScriptRuntime.toString(thisObj);
+ data.str = str;
+ Scriptable topScope = ScriptableObject.getTopLevelScope(scope);
+
+ if (args.length == 0) {
+ Object compiled = NativeRegExp.compileRE(cx, "", "", false);
+ re = new NativeRegExp(topScope, compiled);
+ } else if (args[0] instanceof NativeRegExp) {
+ re = (NativeRegExp) args[0];
+ } else {
+ String src = ScriptRuntime.toString(args[0]);
+ String opt;
+ if (data.optarg < args.length) {
+ args[0] = src;
+ opt = ScriptRuntime.toString(args[data.optarg]);
+ } else {
+ opt = null;
+ }
+ Object compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat);
+ re = new NativeRegExp(topScope, compiled);
+ }
+ data.regexp = re;
+
+ data.global = (re.getFlags() & NativeRegExp.JSREG_GLOB) != 0;
+ int[] indexp = { 0 };
+ Object result = null;
+ if (data.mode == RA_SEARCH) {
+ result = re.executeRegExp(cx, scope, reImpl,
+ str, indexp, NativeRegExp.TEST);
+ if (result != null && result.equals(Boolean.TRUE))
+ result = new Integer(reImpl.leftContext.length);
+ else
+ result = new Integer(-1);
+ } else if (data.global) {
+ re.lastIndex = 0;
+ for (int count = 0; indexp[0] <= str.length(); count++) {
+ result = re.executeRegExp(cx, scope, reImpl,
+ str, indexp, NativeRegExp.TEST);
+ if (result == null || !result.equals(Boolean.TRUE))
+ break;
+ if (data.mode == RA_MATCH) {
+ match_glob(data, cx, scope, count, reImpl);
+ } else {
+ if (data.mode != RA_REPLACE) Kit.codeBug();
+ SubString lastMatch = reImpl.lastMatch;
+ int leftIndex = data.leftIndex;
+ int leftlen = lastMatch.index - leftIndex;
+ data.leftIndex = lastMatch.index + lastMatch.length;
+ replace_glob(data, cx, scope, reImpl, leftIndex, leftlen);
+ }
+ if (reImpl.lastMatch.length == 0) {
+ if (indexp[0] == str.length())
+ break;
+ indexp[0]++;
+ }
+ }
+ } else {
+ result = re.executeRegExp(cx, scope, reImpl, str, indexp,
+ ((data.mode == RA_REPLACE)
+ ? NativeRegExp.TEST
+ : NativeRegExp.MATCH));
+ }
+
+ return result;
+ }
+
+
+
+ public int find_split(Context cx, Scriptable scope, String target,
+ String separator, Scriptable reObj,
+ int[] ip, int[] matchlen,
+ boolean[] matched, String[][] parensp)
+ {
+ int i = ip[0];
+ int length = target.length();
+ int result;
+
+ int version = cx.getLanguageVersion();
+ NativeRegExp re = (NativeRegExp) reObj;
+ again:
+ while (true) { // imitating C label
+ /* JS1.2 deviated from Perl by never matching at end of string. */
+ int ipsave = ip[0]; // reuse ip to save object creation
+ ip[0] = i;
+ Object ret = re.executeRegExp(cx, scope, this, target, ip,
+ NativeRegExp.TEST);
+ if (ret != Boolean.TRUE) {
+ // Mismatch: ensure our caller advances i past end of string.
+ ip[0] = ipsave;
+ matchlen[0] = 1;
+ matched[0] = false;
+ return length;
+ }
+ i = ip[0];
+ ip[0] = ipsave;
+ matched[0] = true;
+
+ SubString sep = this.lastMatch;
+ matchlen[0] = sep.length;
+ if (matchlen[0] == 0) {
+ /*
+ * Empty string match: never split on an empty
+ * match at the start of a find_split cycle. Same
+ * rule as for an empty global match in
+ * match_or_replace.
+ */
+ if (i == ip[0]) {
+ /*
+ * "Bump-along" to avoid sticking at an empty
+ * match, but don't bump past end of string --
+ * our caller must do that by adding
+ * sep->length to our return value.
+ */
+ if (i == length) {
+ if (version == Context.VERSION_1_2) {
+ matchlen[0] = 1;
+ result = i;
+ }
+ else
+ result = -1;
+ break;
+ }
+ i++;
+ continue again; // imitating C goto
+ }
+ }
+ // PR_ASSERT((size_t)i >= sep->length);
+ result = i - matchlen[0];
+ break;
+ }
+ int size = (parens == null) ? 0 : parens.length;
+ parensp[0] = new String[size];
+ for (int num = 0; num < size; num++) {
+ SubString parsub = getParenSubString(num);
+ parensp[0][num] = parsub.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Analog of REGEXP_PAREN_SUBSTRING in C jsregexp.h.
+ * Assumes zero-based; i.e., for $3, i==2
+ */
+ SubString getParenSubString(int i)
+ {
+ if (parens != null && i < parens.length) {
+ SubString parsub = parens[i];
+ if (parsub != null) {
+ return parsub;
+ }
+ }
+ return SubString.emptySubString;
+ }
+
+ /*
+ * Analog of match_glob() in jsstr.c
+ */
+ private static void match_glob(GlobData mdata, Context cx,
+ Scriptable scope, int count,
+ RegExpImpl reImpl)
+ {
+ if (mdata.arrayobj == null) {
+ Scriptable s = ScriptableObject.getTopLevelScope(scope);
+ mdata.arrayobj = ScriptRuntime.newObject(cx, s, "Array", null);
+ }
+ SubString matchsub = reImpl.lastMatch;
+ String matchstr = matchsub.toString();
+ mdata.arrayobj.put(count, mdata.arrayobj, matchstr);
+ }
+
+ /*
+ * Analog of replace_glob() in jsstr.c
+ */
+ private static void replace_glob(GlobData rdata, Context cx,
+ Scriptable scope, RegExpImpl reImpl,
+ int leftIndex, int leftlen)
+ {
+ int replen;
+ String lambdaStr;
+ if (rdata.lambda != null) {
+ // invoke lambda function with args lastMatch, $1, $2, ... $n,
+ // leftContext.length, whole string.
+ SubString[] parens = reImpl.parens;
+ int parenCount = (parens == null) ? 0 : parens.length;
+ Object[] args = new Object[parenCount + 3];
+ args[0] = reImpl.lastMatch.toString();
+ for (int i=0; i < parenCount; i++) {
+ SubString sub = parens[i];
+ if (sub != null) {
+ args[i+1] = sub.toString();
+ } else {
+ args[i+1] = Undefined.instance;
+ }
+ }
+ args[parenCount+1] = new Integer(reImpl.leftContext.length);
+ args[parenCount+2] = rdata.str;
+ // This is a hack to prevent expose of reImpl data to
+ // JS function which can run new regexps modifing
+ // regexp that are used later by the engine.
+ // TODO: redesign is necessary
+ if (reImpl != ScriptRuntime.getRegExpProxy(cx)) Kit.codeBug();
+ RegExpImpl re2 = new RegExpImpl();
+ re2.multiline = reImpl.multiline;
+ re2.input = reImpl.input;
+ ScriptRuntime.setRegExpProxy(cx, re2);
+ try {
+ Scriptable parent = ScriptableObject.getTopLevelScope(scope);
+ Object result = rdata.lambda.call(cx, parent, parent, args);
+ lambdaStr = ScriptRuntime.toString(result);
+ } finally {
+ ScriptRuntime.setRegExpProxy(cx, reImpl);
+ }
+ replen = lambdaStr.length();
+ } else {
+ lambdaStr = null;
+ replen = rdata.repstr.length();
+ if (rdata.dollar >= 0) {
+ int[] skip = new int[1];
+ int dp = rdata.dollar;
+ do {
+ SubString sub = interpretDollar(cx, reImpl, rdata.repstr,
+ dp, skip);
+ if (sub != null) {
+ replen += sub.length - skip[0];
+ dp += skip[0];
+ } else {
+ ++dp;
+ }
+ dp = rdata.repstr.indexOf('$', dp);
+ } while (dp >= 0);
+ }
+ }
+
+ int growth = leftlen + replen + reImpl.rightContext.length;
+ StringBuffer charBuf = rdata.charBuf;
+ if (charBuf == null) {
+ charBuf = new StringBuffer(growth);
+ rdata.charBuf = charBuf;
+ } else {
+ charBuf.ensureCapacity(rdata.charBuf.length() + growth);
+ }
+
+ charBuf.append(reImpl.leftContext.charArray, leftIndex, leftlen);
+ if (rdata.lambda != null) {
+ charBuf.append(lambdaStr);
+ } else {
+ do_replace(rdata, cx, reImpl);
+ }
+ }
+
+ private static SubString interpretDollar(Context cx, RegExpImpl res,
+ String da, int dp, int[] skip)
+ {
+ char dc;
+ int num, tmp;
+
+ if (da.charAt(dp) != '$') Kit.codeBug();
+
+ /* Allow a real backslash (literal "\\") to escape "$1" etc. */
+ int version = cx.getLanguageVersion();
+ if (version != Context.VERSION_DEFAULT
+ && version <= Context.VERSION_1_4)
+ {
+ if (dp > 0 && da.charAt(dp - 1) == '\\')
+ return null;
+ }
+ int daL = da.length();
+ if (dp + 1 >= daL)
+ return null;
+ /* Interpret all Perl match-induced dollar variables. */
+ dc = da.charAt(dp + 1);
+ if (NativeRegExp.isDigit(dc)) {
+ int cp;
+ if (version != Context.VERSION_DEFAULT
+ && version <= Context.VERSION_1_4)
+ {
+ if (dc == '0')
+ return null;
+ /* Check for overflow to avoid gobbling arbitrary decimal digits. */
+ num = 0;
+ cp = dp;
+ while (++cp < daL && NativeRegExp.isDigit(dc = da.charAt(cp)))
+ {
+ tmp = 10 * num + (dc - '0');
+ if (tmp < num)
+ break;
+ num = tmp;
+ }
+ }
+ else { /* ECMA 3, 1-9 or 01-99 */
+ int parenCount = (res.parens == null) ? 0 : res.parens.length;
+ num = dc - '0';
+ if (num > parenCount)
+ return null;
+ cp = dp + 2;
+ if ((dp + 2) < daL) {
+ dc = da.charAt(dp + 2);
+ if (NativeRegExp.isDigit(dc)) {
+ tmp = 10 * num + (dc - '0');
+ if (tmp <= parenCount) {
+ cp++;
+ num = tmp;
+ }
+ }
+ }
+ if (num == 0) return null; /* $0 or $00 is not valid */
+ }
+ /* Adjust num from 1 $n-origin to 0 array-index-origin. */
+ num--;
+ skip[0] = cp - dp;
+ return res.getParenSubString(num);
+ }
+
+ skip[0] = 2;
+ switch (dc) {
+ case '$':
+ return new SubString("$");
+ case '&':
+ return res.lastMatch;
+ case '+':
+ return res.lastParen;
+ case '`':
+ if (version == Context.VERSION_1_2) {
+ /*
+ * JS1.2 imitated the Perl4 bug where left context at each step
+ * in an iterative use of a global regexp started from last match,
+ * not from the start of the target string. But Perl4 does start
+ * $` at the beginning of the target string when it is used in a
+ * substitution, so we emulate that special case here.
+ */
+ res.leftContext.index = 0;
+ res.leftContext.length = res.lastMatch.index;
+ }
+ return res.leftContext;
+ case '\'':
+ return res.rightContext;
+ }
+ return null;
+ }
+
+ /**
+ * Analog of do_replace in jsstr.c
+ */
+ private static void do_replace(GlobData rdata, Context cx,
+ RegExpImpl regExpImpl)
+ {
+ StringBuffer charBuf = rdata.charBuf;
+ int cp = 0;
+ String da = rdata.repstr;
+ int dp = rdata.dollar;
+ if (dp != -1) {
+ int[] skip = new int[1];
+ do {
+ int len = dp - cp;
+ charBuf.append(da.substring(cp, dp));
+ cp = dp;
+ SubString sub = interpretDollar(cx, regExpImpl, da,
+ dp, skip);
+ if (sub != null) {
+ len = sub.length;
+ if (len > 0) {
+ charBuf.append(sub.charArray, sub.index, len);
+ }
+ cp += skip[0];
+ dp += skip[0];
+ } else {
+ ++dp;
+ }
+ dp = da.indexOf('$', dp);
+ } while (dp >= 0);
+ }
+ int daL = da.length();
+ if (daL > cp) {
+ charBuf.append(da.substring(cp, daL));
+ }
+ }
+
+ String input; /* input string to match (perl $_, GC root) */
+ boolean multiline; /* whether input contains newlines (perl $*) */
+ SubString[] parens; /* Vector of SubString; last set of parens
+ matched (perl $1, $2) */
+ SubString lastMatch; /* last string matched (perl $&) */
+ SubString lastParen; /* last paren matched (perl $+) */
+ SubString leftContext; /* input to left of last match (perl $`) */
+ SubString rightContext; /* input to right of last match (perl $') */
+}
+
+
+final class GlobData
+{
+ int mode; /* input: return index, match object, or void */
+ int optarg; /* input: index of optional flags argument */
+ boolean global; /* output: whether regexp was global */
+ String str; /* output: 'this' parameter object as string */
+ NativeRegExp regexp;/* output: regexp parameter object private data */
+
+ // match-specific data
+
+ Scriptable arrayobj;
+
+ // replace-specific data
+
+ Function lambda; /* replacement function object or null */
+ String repstr; /* replacement string */
+ int dollar = -1; /* -1 or index of first $ in repstr */
+ StringBuffer charBuf; /* result characters, null initially */
+ int leftIndex; /* leftContext index, always 0 for JS1.2 */
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java
new file mode 100644
index 0000000..00905ca
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/regexp/SubString.java
@@ -0,0 +1,75 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.regexp;
+
+class SubString {
+
+ public SubString()
+ {
+ }
+
+ public SubString(String str)
+ {
+ index = 0;
+ charArray = str.toCharArray();
+ length = str.length();
+ }
+
+ public SubString(char[] source, int start, int len)
+ {
+ // there must be a better way of doing this??
+ index = 0;
+ length = len;
+ charArray = new char[len];
+ for (int j = 0; j < len; j++)
+ charArray[j] = source[start + j];
+ }
+
+ public String toString() {
+ return charArray == null
+ ? ""
+ : new String(charArray, index, length);
+ }
+
+ static final SubString emptySubString = new SubString();
+
+ char[] charArray;
+ int index;
+ int length;
+}
+
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties
new file mode 100644
index 0000000..fd869c1
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages.properties
@@ -0,0 +1,778 @@
+#
+# Default JavaScript messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released
+# May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Norris Boyd
+# Bob Jervis
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This is replaced during jar assembly from property string
+# and should not be translated
+implementation.version = @IMPLEMENTATION.VERSION@
+
+#
+# To add JavaScript error messages for a particular locale, create a
+# new Messages_[locale].properties file, where [locale] is the Java
+# string abbreviation for that locale. For example, JavaScript
+# messages for the Polish locale should be located in
+# Messages_pl.properties, and messages for the Italian Swiss locale
+# should be located in Messages_it_CH.properties. Message properties
+# files should be accessible through the classpath under
+# org.mozilla.javascript.resources
+#
+# See:
+# java.util.ResourceBundle
+# java.text.MessageFormat
+#
+
+# SomeJavaClassWhereUsed
+
+# Codegen
+msg.dup.parms =\
+ Duplicate parameter name "{0}".
+
+msg.too.big.jump =\
+ Program too complex: too big jump offset.
+
+msg.too.big.index =\
+ Program too complex: internal index exceeds 64K limit.
+
+msg.while.compiling.fn =\
+ Encountered code generation error while compiling function "{0}": {1}
+
+msg.while.compiling.script =\
+ Encountered code generation error while compiling script: {0}
+
+# Context
+msg.ctor.not.found =\
+ Constructor for "{0}" not found.
+
+msg.not.ctor =\
+ "{0}" is not a constructor.
+
+# FunctionObject
+msg.varargs.ctor =\
+ Method or constructor "{0}" must be static with the signature \
+ "(Context cx, Object[] args, Function ctorObj, boolean inNewExpr)" \
+ to define a variable arguments constructor.
+
+msg.varargs.fun =\
+ Method "{0}" must be static with the signature \
+ "(Context cx, Scriptable thisObj, Object[] args, Function funObj)" \
+ to define a variable arguments function.
+
+msg.incompat.call =\
+ Method "{0}" called on incompatible object.
+
+msg.bad.parms =\
+ Unsupported parameter type "{0}" in method "{1}".
+
+msg.bad.method.return =\
+ Unsupported return type "{0}" in method "{1}".
+
+msg.bad.ctor.return =\
+ Construction of objects of type "{0}" is not supported.
+
+msg.no.overload =\
+ Method "{0}" occurs multiple times in class "{1}".
+
+msg.method.not.found =\
+ Method "{0}" not found in "{1}".
+
+# IRFactory
+
+msg.bad.for.in.lhs =\
+ Invalid left-hand side of for..in loop.
+
+msg.mult.index =\
+ Only one variable allowed in for..in loop.
+
+msg.bad.for.in.destruct =\
+ Left hand side of for..in loop must be an array of length 2 to accept \
+ key/value pair.
+
+msg.cant.convert =\
+ Can''t convert to type "{0}".
+
+msg.bad.assign.left =\
+ Invalid assignment left-hand side.
+
+msg.bad.decr =\
+ Invalid decerement operand.
+
+msg.bad.incr =\
+ Invalid increment operand.
+
+msg.bad.yield =\
+ yield must be in a function.
+
+msg.yield.parenthesized =\
+ yield expression must be parenthesized.
+
+# NativeGlobal
+msg.cant.call.indirect =\
+ Function "{0}" must be called directly, and not by way of a \
+ function of another name.
+
+msg.eval.nonstring =\
+ Calling eval() with anything other than a primitive string value will \
+ simply return the value. Is this what you intended?
+
+msg.eval.nonstring.strict =\
+ Calling eval() with anything other than a primitive string value is not \
+ allowed in strict mode.
+
+msg.bad.destruct.op =\
+ Invalid destructuring assignment operator
+
+# NativeCall
+msg.only.from.new =\
+ "{0}" may only be invoked from a "new" expression.
+
+msg.deprec.ctor =\
+ The "{0}" constructor is deprecated.
+
+# NativeFunction
+msg.no.function.ref.found =\
+ no source found to decompile function reference {0}
+
+msg.arg.isnt.array =\
+ second argument to Function.prototype.apply must be an array
+
+# NativeGlobal
+msg.bad.esc.mask =\
+ invalid string escape mask
+
+# NativeJavaClass
+msg.cant.instantiate =\
+ error instantiating ({0}): class {1} is interface or abstract
+
+msg.bad.ctor.sig =\
+ Found constructor with wrong signature: \
+ {0} calling {1} with signature {2}
+
+msg.not.java.obj =\
+ Expected argument to getClass() to be a Java object.
+
+msg.no.java.ctor =\
+ Java constructor for "{0}" with arguments "{1}" not found.
+
+# NativeJavaMethod
+msg.method.ambiguous =\
+ The choice of Java method {0}.{1} matching JavaScript argument types ({2}) is ambiguous; \
+ candidate methods are: {3}
+
+msg.constructor.ambiguous =\
+ The choice of Java constructor {0} matching JavaScript argument types ({1}) is ambiguous; \
+ candidate constructors are: {2}
+
+# NativeJavaObject
+msg.conversion.not.allowed =\
+ Cannot convert {0} to {1}
+
+msg.no.empty.interface.conversion =\
+ Cannot convert {0} to interface {1} with no methods
+
+msg.no.function.interface.conversion =\
+ Cannot convert function {0} to interface since it contains methods with \
+ different signatures
+
+# NativeJavaPackage
+msg.not.classloader =\
+ Constructor for "Packages" expects argument of type java.lang.Classloader
+
+# NativeRegExp
+msg.bad.quant =\
+ Invalid quantifier {0}
+
+msg.overlarge.backref =\
+ Overly large back reference {0}
+
+msg.overlarge.min =\
+ Overly large minimum {0}
+
+msg.overlarge.max =\
+ Overly large maximum {0}
+
+msg.zero.quant =\
+ Zero quantifier {0}
+
+msg.max.lt.min =\
+ Maximum {0} less than minimum
+
+msg.unterm.quant =\
+ Unterminated quantifier {0}
+
+msg.unterm.paren =\
+ Unterminated parenthetical {0}
+
+msg.unterm.class =\
+ Unterminated character class {0}
+
+msg.bad.range =\
+ Invalid range in character class.
+
+msg.trail.backslash =\
+ Trailing \\ in regular expression.
+
+msg.re.unmatched.right.paren =\
+ unmatched ) in regular expression.
+
+msg.no.regexp =\
+ Regular expressions are not available.
+
+msg.bad.backref =\
+ back-reference exceeds number of capturing parentheses.
+
+msg.bad.regexp.compile =\
+ Only one argument may be specified if the first argument to \
+ RegExp.prototype.compile is a RegExp object.
+
+# Parser
+msg.got.syntax.errors = \
+ Compilation produced {0} syntax errors.
+
+msg.var.redecl =\
+ TypeError: redeclaration of var {0}.
+
+msg.const.redecl =\
+ TypeError: redeclaration of const {0}.
+
+msg.let.redecl =\
+ TypeError: redeclaration of variable {0}.
+
+msg.parm.redecl =\
+ TypeError: redeclaration of formal parameter {0}.
+
+msg.fn.redecl =\
+ TypeError: redeclaration of function {0}.
+
+# NodeTransformer
+msg.dup.label =\
+ duplicated label
+
+msg.undef.label =\
+ undefined label
+
+msg.bad.break =\
+ unlabelled break must be inside loop or switch
+
+msg.continue.outside =\
+ continue must be inside loop
+
+msg.continue.nonloop =\
+ continue can only use labeles of iteration statements
+
+msg.bad.throw.eol =\
+ Line terminator is not allowed between the throw keyword and throw \
+ expression.
+
+msg.no.paren.parms =\
+ missing ( before function parameters.
+
+msg.no.parm =\
+ missing formal parameter
+
+msg.no.paren.after.parms =\
+ missing ) after formal parameters
+
+msg.no.brace.body =\
+ missing '{' before function body
+
+msg.no.brace.after.body =\
+ missing } after function body
+
+msg.no.paren.cond =\
+ missing ( before condition
+
+msg.no.paren.after.cond =\
+ missing ) after condition
+
+msg.no.semi.stmt =\
+ missing ; before statement
+
+msg.no.name.after.dot =\
+ missing name after . operator
+
+msg.no.name.after.coloncolon =\
+ missing name after :: operator
+
+msg.no.name.after.dotdot =\
+ missing name after .. operator
+
+msg.no.name.after.xmlAttr =\
+ missing name after .@
+
+msg.no.bracket.index =\
+ missing ] in index expression
+
+msg.no.paren.switch =\
+ missing ( before switch expression
+
+msg.no.paren.after.switch =\
+ missing ) after switch expression
+
+msg.no.brace.switch =\
+ missing '{' before switch body
+
+msg.bad.switch =\
+ invalid switch statement
+
+msg.no.colon.case =\
+ missing : after case expression
+
+msg.double.switch.default =\
+ double default label in the switch statement
+
+msg.no.while.do =\
+ missing while after do-loop body
+
+msg.no.paren.for =\
+ missing ( after for
+
+msg.no.semi.for =\
+ missing ; after for-loop initializer
+
+msg.no.semi.for.cond =\
+ missing ; after for-loop condition
+
+msg.in.after.for.name =\
+ missing in after for
+
+msg.no.paren.for.ctrl =\
+ missing ) after for-loop control
+
+msg.no.paren.with =\
+ missing ( before with-statement object
+
+msg.no.paren.after.with =\
+ missing ) after with-statement object
+
+msg.no.paren.after.let =\
+ missing ( after let
+
+msg.no.paren.let =\
+ missing ) after variable list
+
+msg.no.curly.let =\
+ missing } after let statement
+
+msg.bad.return =\
+ invalid return
+
+msg.no.brace.block =\
+ missing } in compound statement
+
+msg.bad.label =\
+ invalid label
+
+msg.bad.var =\
+ missing variable name
+
+msg.bad.var.init =\
+ invalid variable initialization
+
+msg.no.colon.cond =\
+ missing : in conditional expression
+
+msg.no.paren.arg =\
+ missing ) after argument list
+
+msg.no.bracket.arg =\
+ missing ] after element list
+
+msg.bad.prop =\
+ invalid property id
+
+msg.no.colon.prop =\
+ missing : after property id
+
+msg.no.brace.prop =\
+ missing } after property list
+
+msg.no.paren =\
+ missing ) in parenthetical
+
+msg.reserved.id =\
+ identifier is a reserved word
+
+msg.no.paren.catch =\
+ missing ( before catch-block condition
+
+msg.bad.catchcond =\
+ invalid catch block condition
+
+msg.catch.unreachable =\
+ any catch clauses following an unqualified catch are unreachable
+
+msg.no.brace.try =\
+ missing '{' before try block
+
+msg.no.brace.catchblock =\
+ missing '{' before catch-block body
+
+msg.try.no.catchfinally =\
+ ''try'' without ''catch'' or ''finally''
+
+msg.no.return.value =\
+ function {0} does not always return a value
+
+msg.anon.no.return.value =\
+ anonymous function does not always return a value
+
+msg.return.inconsistent =\
+ return statement is inconsistent with previous usage
+
+msg.generator.returns =\
+ TypeError: generator function {0} returns a value
+
+msg.anon.generator.returns =\
+ TypeError: anonymous generator function returns a value
+
+msg.syntax =\
+ syntax error
+
+msg.unexpected.eof =\
+ Unexpected end of file
+
+msg.XML.bad.form =\
+ illegally formed XML syntax
+
+msg.XML.not.available =\
+ XML runtime not available
+
+msg.too.deep.parser.recursion =\
+ Too deep recursion while parsing
+
+msg.no.side.effects =\
+ Code has no side effects
+
+msg.extra.trailing.comma =\
+ Trailing comma is not legal in an ECMA-262 object initializer
+
+msg.equal.as.assign =\
+ Test for equality (==) mistyped as assignment (=)?
+
+msg.var.hides.arg =\
+ Variable {0} hides argument
+
+msg.destruct.assign.no.init =\
+ Missing = in destructuring declaration
+
+# ScriptRuntime
+msg.no.properties =\
+ {0} has no properties.
+
+msg.invalid.iterator =\
+ Invalid iterator value
+
+msg.iterator.primitive =\
+ __iterator__ returned a primitive value
+
+msg.assn.create.strict =\
+ Assignment to undeclared variable {0}
+
+msg.ref.undefined.prop =\
+ Reference to undefined property "{0}"
+
+msg.prop.not.found =\
+ Property {0} not found.
+
+msg.invalid.type =\
+ Invalid JavaScript value of type {0}
+
+msg.primitive.expected =\
+ Primitive type expected (had {0} instead)
+
+msg.namespace.expected =\
+ Namespace object expected to left of :: (found {0} instead)
+
+msg.null.to.object =\
+ Cannot convert null to an object.
+
+msg.undef.to.object =\
+ Cannot convert undefined to an object.
+
+msg.cyclic.value =\
+ Cyclic {0} value not allowed.
+
+msg.is.not.defined =\
+ "{0}" is not defined.
+
+msg.undef.prop.read =\
+ Cannot read property "{1}" from {0}
+
+msg.undef.prop.write =\
+ Cannot set property "{1}" of {0} to "{2}"
+
+msg.undef.prop.delete =\
+ Cannot delete property "{1}" of {0}
+
+msg.undef.method.call =\
+ Cannot call method "{1}" of {0}
+
+msg.undef.with =\
+ Cannot apply "with" to {0}
+
+msg.isnt.function =\
+ {0} is not a function, it is {1}.
+
+msg.isnt.function.in =\
+ Cannot call property {0} in object {1}. It is not a function, it is "{2}".
+
+msg.function.not.found =\
+ Cannot find function {0}.
+
+msg.function.not.found.in =\
+ Cannot find function {0} in object {1}.
+
+msg.isnt.xml.object =\
+ {0} is not an xml object.
+
+msg.no.ref.to.get =\
+ {0} is not a reference to read reference value.
+
+msg.no.ref.to.set =\
+ {0} is not a reference to set reference value to {1}.
+
+msg.no.ref.from.function =\
+ Function {0} can not be used as the left-hand side of assignment \
+ or as an operand of ++ or -- operator.
+
+msg.bad.default.value =\
+ Object''s getDefaultValue() method returned an object.
+
+msg.instanceof.not.object = \
+ Can''t use instanceof on a non-object.
+
+msg.instanceof.bad.prototype = \
+ ''prototype'' property of {0} is not an object.
+
+msg.bad.radix = \
+ illegal radix {0}.
+
+# ScriptableObject
+msg.default.value =\
+ Cannot find default value for object.
+
+msg.zero.arg.ctor =\
+ Cannot load class "{0}" which has no zero-parameter constructor.
+
+msg.ctor.multiple.parms =\
+ Can''t define constructor or class {0} since more than one \
+ constructor has multiple parameters.
+
+msg.extend.scriptable =\
+ {0} must extend ScriptableObject in order to define property {1}.
+
+msg.bad.getter.parms =\
+ In order to define a property, getter {0} must have zero parameters \
+ or a single ScriptableObject parameter.
+
+msg.obj.getter.parms =\
+ Expected static or delegated getter {0} to take a ScriptableObject parameter.
+
+msg.getter.static =\
+ Getter and setter must both be static or neither be static.
+
+msg.setter.return =\
+ Setter must have void return type: {0}
+
+msg.setter2.parms =\
+ Two-parameter setter must take a ScriptableObject as its first parameter.
+
+msg.setter1.parms =\
+ Expected single parameter setter for {0}
+
+msg.setter2.expected =\
+ Expected static or delegated setter {0} to take two parameters.
+
+msg.setter.parms =\
+ Expected either one or two parameters for setter.
+
+msg.setter.bad.type =\
+ Unsupported parameter type "{0}" in setter "{1}".
+
+msg.add.sealed =\
+ Cannot add a property to a sealed object: {0}.
+
+msg.remove.sealed =\
+ Cannot remove a property from a sealed object: {0}.
+
+msg.modify.sealed =\
+ Cannot modify a property of a sealed object: {0}.
+
+msg.modify.readonly =\
+ Cannot modify readonly property: {0}.
+
+# TokenStream
+msg.missing.exponent =\
+ missing exponent
+
+msg.caught.nfe =\
+ number format error
+
+msg.unterminated.string.lit =\
+ unterminated string literal
+
+msg.unterminated.mstring.appjet =\
+ unterminated multi-line string literal
+
+msg.unterminated.comment =\
+ unterminated comment
+
+msg.unterminated.re.lit =\
+ unterminated regular expression literal
+
+msg.invalid.re.flag =\
+ invalid flag after regular expression
+
+msg.no.re.input.for =\
+ no input for {0}
+
+msg.illegal.character =\
+ illegal character
+
+msg.illegal.character.appjet =\
+ illegal character: {0}
+
+msg.invalid.escape =\
+ invalid Unicode escape sequence
+
+msg.bad.namespace =\
+ not a valid default namespace statement. \
+ Syntax is: default xml namespace = EXPRESSION;
+
+# TokensStream warnings
+msg.bad.octal.literal =\
+ illegal octal literal digit {0}; interpreting it as a decimal digit
+
+msg.reserved.keyword =\
+ illegal usage of future reserved keyword {0}; interpreting it as ordinary identifier
+
+# LiveConnect errors
+msg.java.internal.field.type =\
+ Internal error: type conversion of {0} to assign to {1} on {2} failed.
+
+msg.java.conversion.implicit_method =\
+ Can''t find converter method "{0}" on class {1}.
+
+msg.java.method.assign =\
+ Java method "{0}" cannot be assigned to.
+
+msg.java.internal.private =\
+ Internal error: attempt to access private/protected field "{0}".
+
+msg.java.no_such_method =\
+ Can''t find method {0}.
+
+msg.script.is.not.constructor =\
+ Script objects are not constructors.
+
+msg.nonjava.method =\
+ Java method "{0}" was invoked with {1} as "this" value that can not be converted to Java type {2}.
+
+msg.java.member.not.found =\
+ Java class "{0}" has no public instance field or method named "{1}".
+
+msg.java.array.index.out.of.bounds =\
+ Array index {0} is out of bounds [0..{1}].
+
+msg.java.array.member.not.found =\
+ Java arrays have no public instance fields or methods named "{0}".
+
+msg.pkg.int =\
+ Java package names may not be numbers.
+
+msg.access.prohibited =\
+ Access to Java class "{0}" is prohibited.
+
+# ImporterTopLevel
+msg.ambig.import =\
+ Ambiguous import: "{0}" and and "{1}".
+
+msg.not.pkg =\
+ Function importPackage must be called with a package; had "{0}" instead.
+
+msg.not.class =\
+ Function importClass must be called with a class; had "{0}" instead.
+
+msg.not.class.not.pkg =\
+ "{0}" is neither a class nor a package.
+
+msg.prop.defined =\
+ Cannot import "{0}" since a property by that name is already defined.
+
+#JavaAdapter
+msg.adapter.zero.args =\
+ JavaAdapter requires at least one argument.
+
+msg.not.java.class.arg = \
+Argument {0} is not Java class: {1}.
+
+#JavaAdapter
+msg.only.one.super = \
+Only one class may be extended by a JavaAdapter. Had {0} and {1}.
+
+
+# Arrays
+msg.arraylength.bad =\
+ Inappropriate array length.
+
+# Arrays
+msg.arraylength.too.big =\
+ Array length {0} exceeds supported capacity limit.
+
+# URI
+msg.bad.uri =\
+ Malformed URI sequence.
+
+# Number
+msg.bad.precision =\
+ Precision {0} out of range.
+
+# NativeGenerator
+msg.send.newborn =\
+ Attempt to send value to newborn generator
+
+msg.already.exec.gen =\
+ Already executing generator
+
+msg.StopIteration.invalid =\
+ StopIteration may not be changed to an arbitrary object.
+
+# Interpreter
+msg.yield.closing =\
+ Yield from closing generator
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties
new file mode 100644
index 0000000..fc87c97
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/resources/Messages_fr.properties
@@ -0,0 +1,329 @@
+#
+# French JavaScript messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Aviva Inc. code, released
+# March 5, 2004.
+#
+# The Initial Developer of the Original Code is
+# Aviva Inc.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Eugene Aresteanu
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+msg.dup.parms =\
+ Le nom de param\u00E8tre "{0}" existe d\u00E9j\u00E0.
+msg.too.big.jump =\
+ Programme trop complexe : d\u00E9calage de saut trop important
+msg.too.big.index =\
+ Programme trop complexe : l''indice interne d\u00E9passe la limite de 64 ko
+msg.ctor.not.found =\
+ Le constructeur de "{0}" est introuvable
+msg.not.ctor =\
+ {0} n''est pas un constructeur
+msg.varargs.ctor =\
+ La m\u00E9thode ou le constructeur "{0}" doit \u00EAtre statique avec la signature "(Context cx, arguments Object[], Function ctorObj, boolean inNewExpr)" pour d\u00E9finir un constructeur d''arguments de variable.
+msg.varargs.fun =\
+ La m\u00E9thode "{0}" doit \u00EAtre statique avec la signature "(Context cx, Scriptable thisObj, arguments Object[], Function funObj)" pour d\u00E9finir une fonction d''arguments de variable
+msg.incompat.call =\
+ La m\u00E9thode "{0}" a \u00E9t\u00E9 appel\u00E9e dans un objet non compatible
+msg.bad.parms =\
+ Les param\u00E8tres de la m\u00E9thode sont incorrects pour "{0}"
+msg.no.overload =\
+ La m\u00E9thode "{0}" appara\u00EEt plusieurs fois dans la classe "{1}"
+msg.method.not.found =\
+ La m\u00E9thode "{0}" est introuvable dans "{1}"
+msg.bad.for.in.lhs =\
+ La partie gauche de la boucle for..in est incorrecte
+msg.bad.lhs.assign =\
+ La partie gauche de l''affectation est incorrecte
+msg.mult.index =\
+ Une seule variable est autoris\u00E9e dans la boucle for..in
+msg.cant.convert =\
+ La conversion en type "{0}" est impossible
+msg.cant.call.indirect =\
+ La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire d''une fonction portant un autre nom
+msg.eval.nonstring =\
+ Si vous appelez la fonction eval() avec une valeur qui n''appartient pas \u00E0 une cha\u00EEne primitive, c''est la valeur en question qui est renvoy\u00E9e. \u00E9tait-ce votre intention ?
+msg.only.from.new =\
+ {0} ne peut \u00EAtre appel\u00E9e qu''\u00E0 partir d''une "nouvelle" expression.
+msg.deprec.ctor =\
+ Le constructeur "{0}" est d\u00E9conseill\u00E9
+msg.no.function.ref.found =\
+ aucune source n''a \u00E9t\u00E9 trouv\u00E9e pour d\u00E9compiler la r\u00E9f\u00E9rence de fonction {0}
+msg.arg.isnt.array =\
+ le second argument de la m\u00E9thode Function.prototype.apply doit \u00EAtre un tableau
+msg.bad.esc.mask =\
+ le masque d''\u00E9chappement de cha\u00EEne est incorrect
+msg.cant.instantiate =\
+ erreur lors de l''instanciation ({0}) : la classe {1} est une classe interface ou abstract
+msg.bad.ctor.sig =\
+ Un constructeur avec une signature incorrecte a \u00E9t\u00E9 d\u00E9tect\u00E9 : {0} qui appelle {1} avec la signature {2}
+msg.not.java.obj =\
+ L''argument attendu pour la fonction getClass() doit \u00EAtre un objet Java
+msg.no.java.ctor =\
+ Le constructeur Java de "{0}" avec les arguments "{1}" est introuvable
+msg.method.ambiguous =\
+ Le choix de la m\u00E9thode Java {0}.{1} correspondant aux types d''argument JavaScript ({2}) est ambigu. Les m\u00E9thodes propos\u00E9es sont les suivantes : {3}
+msg.constructor.ambiguous =\
+ Le choix du constructeur Java {0} correspondant aux types d''argument JavaScript ({1}) est ambigu. Les constructeurs propos\u00E9s sont les suivants : {2}
+msg.conversion.not.allowed =\
+ Impossible de convertir {0} en {1}
+msg.not.classloader =\
+ Le constructeur de "Packages" attend un argument de type java.lang.Classloader
+msg.bad.quant =\
+ Le quantificateur {0} est incorrect
+msg.overlarge.max =\
+ Le maximum {0} est trop important
+msg.zero.quant =\
+ Le quantificateur {0} est nul
+msg.max.lt.min =\
+ Le maximum {0} est inf\u00E9rieur au minimum
+msg.unterm.quant =\
+ Le quantificateur {0} n''a pas de limite
+msg.unterm.paren =\
+ Les parenth\u00E8ses {0} n''ont pas de limite
+msg.unterm.class =\
+ La classe de caract\u00E8res {0} n''a pas de limite
+msg.bad.range =\
+ La classe de caract\u00E8res contient une plage de valeurs incorrecte
+msg.trail.backslash =\
+ \\ au d\u00E9but d''une expression r\u00E9guli\u00E8re
+msg.no.regexp =\
+ Les expressions r\u00E9guli\u00E8res ne sont pas disponibles
+msg.bad.backref =\
+ la r\u00E9f\u00E9rence ant\u00E9rieure d\u00E9passe le nombre de parenth\u00E8ses de capture
+msg.dup.label =\
+ Le libell\u00E9 {0} existe d\u00E9j\u00E0
+msg.undef.label =\
+ Le libell\u00E9 {0} n''est pas d\u00E9fini
+msg.bad.break =\
+ Le saut non libell\u00E9 doit se trouver dans la boucle ou dans l''aiguillage
+msg.continue.outside =\
+ continue doit se trouver dans la boucle
+msg.continue.nonloop =\
+ Il n''est possible de continuer que dans l''instruction d''it\u00E9ration libell\u00E9e
+msg.fn.redecl =\
+ La fonction "{0}" a \u00E9t\u00E9 de nouveau d\u00E9clar\u00E9e. La d\u00E9finition pr\u00E9c\u00E9dente sera ignor\u00E9e
+msg.no.paren.parms =\
+ il manque ''('' avant les param\u00E8tres de la fonction
+msg.no.parm =\
+ il manque un param\u00E8tre de forme
+msg.no.paren.after.parms =\
+ il manque '')'' apr\u00E8s les param\u00E8tres de forme
+msg.no.brace.body =\
+ il manque '{' avant le corps d''une fonction
+msg.no.brace.after.body =\
+ il manque ''}'' apr\u00E8s le corps d''une fonction
+msg.no.paren.cond =\
+ il manque ''('' avant une condition
+msg.no.paren.after.cond =\
+ il manque '')'' apr\u00E8s une condition
+msg.no.semi.stmt =\
+ il manque '';'' avant une instruction
+msg.no.name.after.dot =\
+ il manque un nom apr\u00E8s un op\u00E9rateur ''.''
+msg.no.bracket.index =\
+ il manque '']'' dans l''expression de l''indice
+msg.no.paren.switch =\
+ il manque ''('' avant l''expression d''un aiguillage
+msg.no.paren.after.switch =\
+ il manque '')'' apr\u00E8s l''expression d''un aiguillage
+msg.no.brace.switch =\
+ il manque '{' avant le corps d''un aiguillage
+msg.bad.switch =\
+ l''instruction d''aiguillage est incorrecte
+msg.no.colon.case =\
+ il manque '':'' apr\u00E8s l''expression d''un cas
+msg.no.while.do =\
+ il manque ''while'' apr\u00E8s le corps d''une boucle do-loop
+msg.no.paren.for =\
+ il manque ''('' apr\u00E8s for
+msg.no.semi.for =\
+ Il manque '';'' apr\u00E8s l''initialiseur for-loop
+msg.no.semi.for.cond =\
+ il manque '';'' apr\u00E8s la condition for-loop
+msg.no.paren.for.ctrl =\
+ il manque '')'' apr\u00E8s le contrôle for-loop
+msg.no.paren.with =\
+ il manque ''('' avant un objet with-statement
+msg.no.paren.after.with =\
+ il manque '')'' apr\u00E8s un objet with-statement
+msg.bad.return =\
+ la valeur renvoy\u00E9e est incorrecte
+msg.no.brace.block =\
+ il manque ''}'' dans une instruction compos\u00E9e
+msg.bad.label =\
+ le libell\u00E9 est incorrect
+msg.bad.var =\
+ il manque un nom de variable
+msg.bad.var.init =\
+ l''initialisation de la variable est incorrecte
+msg.no.colon.cond =\
+ il manque '':'' dans une expression conditionnelle
+msg.no.paren.arg =\
+ il manque '')'' apr\u00E8s une liste d''arguments
+msg.no.bracket.arg =\
+ il manque '']'' apr\u00E8s une liste d''\u00E9l\u00E9ments
+msg.bad.prop =\
+ l''identifiant de propri\u00E9t\u00E9 est incorrect
+msg.no.colon.prop =\
+ il manque '':'' apr\u00E8s un identifiant de propri\u00E9t\u00E9
+msg.no.brace.prop =\
+ il manque ''}'' apr\u00E8s une liste de propri\u00E9t\u00E9s
+msg.no.paren =\
+ il manque '')'' dans des parenth\u00E8ses
+msg.reserved.id =\
+ l''identifiant est un mot r\u00E9serv\u00E9
+msg.no.paren.catch =\
+ il manque ''('' avant une condition catch-block
+msg.bad.catchcond =\
+ la condition catch-block est incorrecte
+msg.catch.unreachable =\
+ aucune clause catch suivant une interception non qualifi\u00E9e ne peut \u00EAtre atteinte
+msg.no.brace.catchblock =\
+ il manque '{' avant le corps catch-block
+msg.try.no.catchfinally =\
+ ''try'' a \u00E9t\u00E9 d\u00E9tect\u00E9 sans ''catch'' ni ''finally''
+msg.syntax =\
+ erreur de syntaxe
+msg.assn.create =\
+ Une variable va \u00EAtre cr\u00E9\u00E9e en raison de l''affectation \u00E0 un ''{0}'' non d\u00E9fini. Ajoutez une instruction de variable \u00E0 la port\u00E9e sup\u00E9rieure pour que cet avertissement ne soit plus affich\u00E9
+msg.prop.not.found =\
+ La propri\u00E9t\u00E9 est introuvable
+msg.invalid.type =\
+ Valeur JavaScript de type {0} incorrecte
+msg.primitive.expected =\
+ Un type primitif \u00E9tait attendu (et non {0})
+msg.null.to.object =\
+ Il est impossible de convertir la valeur null en objet
+msg.undef.to.object =\
+ Il est impossible de convertir une valeur non d\u00E9finie en objet
+msg.cyclic.value =\
+ La valeur cyclique {0} n''est pas autoris\u00E9e
+msg.is.not.defined =\
+ "{0}" n''est pas d\u00E9fini
+msg.isnt.function =\
+ {0} n''est pas une fonction, est un {1}
+msg.bad.default.value =\
+ La m\u00E9thode getDefaultValue() de l''objet a renvoy\u00E9 un objet
+msg.instanceof.not.object =\
+ Il est impossible d''utiliser une instance d''un \u00E9l\u00E9ment autre qu''un objet
+msg.instanceof.bad.prototype =\
+ La propri\u00E9t\u00E9 ''prototype'' de {0} n''est pas un objet
+msg.bad.radix =\
+ la base {0} n''est pas autoris\u00E9e
+msg.default.value =\
+ La valeur par d\u00E9faut de l''objet est introuvable
+msg.zero.arg.ctor =\
+ Il est impossible de charger la classe "{0}", qui ne poss\u00E8de pas de constructeur de param\u00E8tre z\u00E9ro
+msg.multiple.ctors =\
+ Les m\u00E9thodes {0} et {1} ont \u00E9t\u00E9 d\u00E9tect\u00E9es alors qu''il est impossible d''utiliser plusieurs m\u00E9thodes constructor
+msg.ctor.multiple.parms =\
+ Il est impossible de d\u00E9finir le constructeur ou la classe {0} car plusieurs constructeurs poss\u00E8dent plusieurs param\u00E8tres
+msg.extend.scriptable =\
+ {0} doit \u00E9tendre ScriptableObject afin de d\u00E9finir la propri\u00E9t\u00E9 {1}
+msg.bad.getter.parms =\
+ Pour d\u00E9finir une propri\u00E9t\u00E9, la m\u00E9thode d''obtention {0} doit avoir des param\u00E8tres z\u00E9ro ou un seul param\u00E8tre ScriptableObject
+msg.obj.getter.parms =\
+ La m\u00E9thode d''obtention statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser un param\u00E8tre ScriptableObject
+msg.getter.static =\
+ La m\u00E9thode d''obtention et la m\u00E9thode de d\u00E9finition doivent toutes deux avoir le m\u00EAme \u00E9tat (statique ou non)
+msg.setter2.parms =\
+ La m\u00E9thode de d\u00E9finition \u00E0 deux param\u00E8tres doit utiliser un param\u00E8tre ScriptableObject comme premier param\u00E8tre
+msg.setter1.parms =\
+ Une m\u00E9thode d''obtention \u00E0 param\u00E8tre unique est attendue pour {0}
+msg.setter2.expected =\
+ La m\u00E9thode de d\u00E9finition statique ou d\u00E9l\u00E9gu\u00E9e {0} doit utiliser deux param\u00E8tres
+msg.setter.parms =\
+ Un ou deux param\u00E8tres sont attendus pour la m\u00E9thode de d\u00E9finition
+msg.add.sealed =\
+ Il est impossible d''ajouter une propri\u00E9t\u00E9 \u00E0 un objet ferm\u00E9
+msg.remove.sealed =\
+ Il est impossible de supprimer une propri\u00E9t\u00E9 d''un objet ferm\u00E9
+msg.token.replaces.pushback =\
+ le jeton de non-obtention {0} remplace le jeton de renvoi {1}
+msg.missing.exponent =\
+ il manque un exposant
+msg.caught.nfe =\
+ erreur de format de nombre : {0}
+msg.unterminated.string.lit =\
+ le litt\u00E9ral de la cha\u00EEne n''a pas de limite
+msg.unterminated.comment =\
+ le commentaire n''a pas de limite
+msg.unterminated.re.lit =\
+ le litt\u00E9ral de l''expression r\u00E9guli\u00E8re n''a pas de limite
+msg.invalid.re.flag =\
+ une expression r\u00E9guli\u00E8re est suivie d''un indicateur incorrect
+msg.no.re.input.for =\
+ il n''y a pas d''entr\u00E9e pour {0}
+msg.illegal.character =\
+ caract\u00E8re non autoris\u00E9
+msg.invalid.escape =\
+ la s\u00E9quence d''\u00E9chappement Unicode est incorrecte
+msg.bad.octal.literal =\
+ le chiffre octal du litt\u00E9ral, {0}, n''est pas autoris\u00E9 et sera interpr\u00E9t\u00E9 comme un chiffre d\u00E9cimal
+msg.reserved.keyword =\
+ l''utilisation du futur mot-cl\u00E9 r\u00E9serv\u00E9 {0} n''est pas autoris\u00E9e et celui-ci sera interpr\u00E9t\u00E9 comme un identifiant ordinaire
+msg.undefined =\
+ La valeur non d\u00E9finie ne poss\u00E8de pas de propri\u00E9t\u00E9
+msg.java.internal.field.type =\
+ Erreur interne : la conversion de type de {0} afin d''affecter {1} \u00E0 {2} a \u00E9chou\u00E9
+msg.java.conversion.implicit_method =\
+ La m\u00E9thode de conversion "{0}" est introuvable dans la classe {1}
+sg.java.method.assign =\
+ La m\u00E9thode Java "{0}" ne peut pas \u00EAtre affect\u00E9e \u00E0
+msg.java.internal.private =\
+ Erreur interne : une tentative d''acc\u00E9der \u00E0 un champ "{0}" priv\u00E9/prot\u00E9g\u00E9 a \u00E9t\u00E9 d\u00E9tect\u00E9e
+msg.java.no_such_method =\
+ La m\u00E9thode ''{0}'' est introuvable
+msg.script.is.not.constructor =\
+ Les objets Script ne sont pas des constructeurs
+msg.nonjava.method =\
+ La m\u00E9thode Java "{0}" a \u00E9t\u00E9 appel\u00E9e avec une valeur ''this'' qui n''est pas un objet Java
+msg.java.member.not.found =\
+ La classe Java "{0}" ne poss\u00E8de aucun champ ou aucune m\u00E9thode d''instance publique appel\u00E9 "{1}"
+msg.java.array.index.out.of.bounds =\
+ Array index {0} is out of bounds [0..{1}].
+msg.pkg.int =\
+ Les noms de package Java ne peuvent pas \u00EAtre des nombres
+msg.ambig.import =\
+ Importation ambigu\u00EB : "{0}" et "{1}"
+msg.not.pkg =\
+ La fonction importPackage doit \u00EAtre appel\u00E9e avec un package et non avec "{0}"
+msg.not.class =\
+ La fonction importClass doit \u00EAtre appel\u00E9e avec une classe et non avec "{0}"
+msg.prop.defined =\
+ Il est impossible d''importer "{0}" car une propri\u00E9t\u00E9 portant le m\u00EAme nom a d\u00E9j\u00E0 \u00E9t\u00E9 d\u00E9finie
+sg.arraylength.bad =\
+ La longueur du tableau n''est pas appropri\u00E9e
+msg.bad.uri =\
+ La s\u00E9quence URI n''est pas form\u00E9e correctement
+msg.bad.precision =\
+ La pr\u00E9cision {0} ne se trouve pas dans la plage de valeurs
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java
new file mode 100644
index 0000000..476ff69
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableInputStream.java
@@ -0,0 +1,112 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino serialization code, released
+ * Sept. 25, 2001.
+ *
+ * The Initial Developer of the Original Code is
+ * Norris Boyd.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Igor Bukanov
+ * Attila Szegedi
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// API class
+
+package org.mozilla.javascript.serialize;
+
+import java.io.*;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class ScriptableInputStream is used to read in a JavaScript
+ * object or function previously serialized with a ScriptableOutputStream.
+ * References to names in the exclusion list
+ * replaced with references to the top-level scope specified during
+ * creation of the ScriptableInputStream.
+ *
+ * @author Norris Boyd
+ */
+
+public class ScriptableInputStream extends ObjectInputStream {
+
+ /**
+ * Create a ScriptableInputStream.
+ * @param in the InputStream to read from.
+ * @param scope the top-level scope to create the object in.
+ */
+ public ScriptableInputStream(InputStream in, Scriptable scope)
+ throws IOException
+ {
+ super(in);
+ this.scope = scope;
+ enableResolveObject(true);
+ Context cx = Context.getCurrentContext();
+ if (cx != null) {
+ this.classLoader = cx.getApplicationClassLoader();
+ }
+ }
+
+ protected Class resolveClass(ObjectStreamClass desc)
+ throws IOException, ClassNotFoundException
+ {
+ String name = desc.getName();
+ if (classLoader != null) {
+ try {
+ return classLoader.loadClass(name);
+ } catch (ClassNotFoundException ex) {
+ // fall through to default loading
+ }
+ }
+ return super.resolveClass(desc);
+ }
+
+ protected Object resolveObject(Object obj)
+ throws IOException
+ {
+ if (obj instanceof ScriptableOutputStream.PendingLookup) {
+ String name = ((ScriptableOutputStream.PendingLookup)obj).getName();
+ obj = ScriptableOutputStream.lookupQualifiedName(scope, name);
+ if (obj == Scriptable.NOT_FOUND) {
+ throw new IOException("Object " + name + " not found upon " +
+ "deserialization.");
+ }
+ }else if (obj instanceof UniqueTag) {
+ obj = ((UniqueTag)obj).readResolve();
+ }else if (obj instanceof Undefined) {
+ obj = ((Undefined)obj).readResolve();
+ }
+ return obj;
+ }
+
+ private Scriptable scope;
+ private ClassLoader classLoader;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
new file mode 100644
index 0000000..5ba0d74
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/serialize/ScriptableOutputStream.java
@@ -0,0 +1,207 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino serialization code, released
+ * Sept. 25, 2001.
+ *
+ * The Initial Developer of the Original Code is
+ * Norris Boyd.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Attila Szegedi
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.serialize;
+
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.io.*;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class ScriptableOutputStream is an ObjectOutputStream used
+ * to serialize JavaScript objects and functions. Note that
+ * compiled functions currently cannot be serialized, only
+ * interpreted functions. The top-level scope containing the
+ * object is not written out, but is instead replaced with
+ * another top-level object when the ScriptableInputStream
+ * reads in this object. Also, object corresponding to names
+ * added to the exclude list are not written out but instead
+ * are looked up during deserialization. This approach avoids
+ * the creation of duplicate copies of standard objects
+ * during deserialization.
+ *
+ * @author Norris Boyd
+ */
+
+// API class
+
+public class ScriptableOutputStream extends ObjectOutputStream {
+
+ /**
+ * ScriptableOutputStream constructor.
+ * Creates a ScriptableOutputStream for use in serializing
+ * JavaScript objects. Calls excludeStandardObjectNames.
+ *
+ * @param out the OutputStream to write to.
+ * @param scope the scope containing the object.
+ */
+ public ScriptableOutputStream(OutputStream out, Scriptable scope)
+ throws IOException
+ {
+ super(out);
+ this.scope = scope;
+ table = new Hashtable(31);
+ table.put(scope, "");
+ enableReplaceObject(true);
+ excludeStandardObjectNames();
+ }
+
+ /**
+ * Adds a qualified name to the list of object to be excluded from
+ * serialization. Names excluded from serialization are looked up
+ * in the new scope and replaced upon deserialization.
+ * @param name a fully qualified name (of the form "a.b.c", where
+ * "a" must be a property of the top-level object). The object
+ * need not exist, in which case the name is ignored.
+ * @throws IllegalArgumentException if the object is not a
+ * {@link Scriptable}.
+ */
+ public void addOptionalExcludedName(String name) {
+ Object obj = lookupQualifiedName(scope, name);
+ if(obj != null && obj != UniqueTag.NOT_FOUND) {
+ if (!(obj instanceof Scriptable)) {
+ throw new IllegalArgumentException(
+ "Object for excluded name " + name +
+ " is not a Scriptable, it is " +
+ obj.getClass().getName());
+ }
+ table.put(obj, name);
+ }
+ }
+
+ /**
+ * Adds a qualified name to the list of object to be excluded from
+ * serialization. Names excluded from serialization are looked up
+ * in the new scope and replaced upon deserialization.
+ * @param name a fully qualified name (of the form "a.b.c", where
+ * "a" must be a property of the top-level object)
+ * @throws IllegalArgumentException if the object is not found or is not
+ * a {@link Scriptable}.
+ */
+ public void addExcludedName(String name) {
+ Object obj = lookupQualifiedName(scope, name);
+ if (!(obj instanceof Scriptable)) {
+ throw new IllegalArgumentException("Object for excluded name " +
+ name + " not found.");
+ }
+ table.put(obj, name);
+ }
+
+ /**
+ * Returns true if the name is excluded from serialization.
+ */
+ public boolean hasExcludedName(String name) {
+ return table.get(name) != null;
+ }
+
+ /**
+ * Removes a name from the list of names to exclude.
+ */
+ public void removeExcludedName(String name) {
+ table.remove(name);
+ }
+
+ /**
+ * Adds the names of the standard objects and their
+ * prototypes to the list of excluded names.
+ */
+ public void excludeStandardObjectNames() {
+ String[] names = { "Object", "Object.prototype",
+ "Function", "Function.prototype",
+ "String", "String.prototype",
+ "Math", // no Math.prototype
+ "Array", "Array.prototype",
+ "Error", "Error.prototype",
+ "Number", "Number.prototype",
+ "Date", "Date.prototype",
+ "RegExp", "RegExp.prototype",
+ "Script", "Script.prototype",
+ "Continuation", "Continuation.prototype",
+ };
+ for (int i=0; i < names.length; i++) {
+ addExcludedName(names[i]);
+ }
+
+ String[] optionalNames = {
+ "XML", "XML.prototype",
+ "XMLList", "XMLList.prototype",
+ };
+ for (int i=0; i < optionalNames.length; i++) {
+ addOptionalExcludedName(optionalNames[i]);
+ }
+ }
+
+ static Object lookupQualifiedName(Scriptable scope,
+ String qualifiedName)
+ {
+ StringTokenizer st = new StringTokenizer(qualifiedName, ".");
+ Object result = scope;
+ while (st.hasMoreTokens()) {
+ String s = st.nextToken();
+ result = ScriptableObject.getProperty((Scriptable)result, s);
+ if (result == null || !(result instanceof Scriptable))
+ break;
+ }
+ return result;
+ }
+
+ static class PendingLookup implements Serializable
+ {
+ static final long serialVersionUID = -2692990309789917727L;
+
+ PendingLookup(String name) { this.name = name; }
+
+ String getName() { return name; }
+
+ private String name;
+ }
+
+ protected Object replaceObject(Object obj) throws IOException
+ {
+ String name = (String) table.get(obj);
+ if (name == null)
+ return obj;
+ return new PendingLookup(name);
+ }
+
+ private Scriptable scope;
+ private Hashtable table;
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java
new file mode 100644
index 0000000..da57ddf
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLLib.java
@@ -0,0 +1,132 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml;
+
+import org.mozilla.javascript.*;
+
+public abstract class XMLLib
+{
+ private static final Object XML_LIB_KEY = new Object();
+
+ /**
+ An object which specifies an XMLLib implementation to be used at runtime.
+
+ This interface should be considered experimental. It may be better
+ (and certainly more flexible) to write an interface that returns an
+ XMLLib object rather than a class name, for example. But that would
+ cause many more ripple effects in the code, all the way back to
+ {@link ScriptRuntime}.
+ */
+ public static abstract class Factory {
+ public static Factory create(final String className) {
+ return new Factory() {
+ public String getImplementationClassName() {
+ return className;
+ }
+ };
+ }
+
+ public abstract String getImplementationClassName();
+ }
+
+ public static XMLLib extractFromScopeOrNull(Scriptable scope)
+ {
+ ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope);
+ if (so == null) {
+ // If library is not yet initialized, return null
+ return null;
+ }
+
+ // Ensure lazily initialization of real XML library instance
+ // which is done on first access to XML property
+ ScriptableObject.getProperty(so, "XML");
+
+ return (XMLLib)so.getAssociatedValue(XML_LIB_KEY);
+ }
+
+ public static XMLLib extractFromScope(Scriptable scope)
+ {
+ XMLLib lib = extractFromScopeOrNull(scope);
+ if (lib != null) {
+ return lib;
+ }
+ String msg = ScriptRuntime.getMessage0("msg.XML.not.available");
+ throw Context.reportRuntimeError(msg);
+ }
+
+ protected final XMLLib bindToScope(Scriptable scope)
+ {
+ ScriptableObject so = ScriptRuntime.getLibraryScopeOrNull(scope);
+ if (so == null) {
+ // standard library should be initialized at this point
+ throw new IllegalStateException();
+ }
+ return (XMLLib)so.associateValue(XML_LIB_KEY, this);
+ }
+
+ public abstract boolean isXMLName(Context cx, Object name);
+
+ public abstract Ref nameRef(Context cx, Object name,
+ Scriptable scope, int memberTypeFlags);
+
+ public abstract Ref nameRef(Context cx, Object namespace, Object name,
+ Scriptable scope, int memberTypeFlags);
+
+ /**
+ * Escapes the reserved characters in a value of an attribute.
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public abstract String escapeAttributeValue(Object value);
+
+ /**
+ * Escapes the reserved characters in a value of a text node.
+ *
+ * @param value Unescaped text
+ * @return The escaped text
+ */
+ public abstract String escapeTextValue(Object value);
+
+
+ /**
+ * Construct namespace for default xml statement.
+ */
+ public abstract Object toDefaultXmlNamespace(Context cx, Object uriValue);
+}
diff --git a/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java
new file mode 100644
index 0000000..5033564
--- /dev/null
+++ b/infrastructure/rhino1_7R1/src/org/mozilla/javascript/xml/XMLObject.java
@@ -0,0 +1,128 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xml;
+
+import org.mozilla.javascript.*;
+
+/**
+ * This Interface describes what all XML objects (XML, XMLList) should have in common.
+ *
+ */
+public abstract class XMLObject extends IdScriptableObject
+{
+ public XMLObject()
+ {
+ }
+
+ public XMLObject(Scriptable scope, Scriptable prototype)
+ {
+ super(scope, prototype);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Has]].
+ */
+ public abstract boolean ecmaHas(Context cx, Object id);
+
+ /**
+ * Implementation of ECMAScript [[Get]].
+ */
+ public abstract Object ecmaGet(Context cx, Object id);
+
+ /**
+ * Implementation of ECMAScript [[Put]].
+ */
+ public abstract void ecmaPut(Context cx, Object id, Object value);
+
+ /**
+ * Implementation of ECMAScript [[Delete]].
+ */
+ public abstract boolean ecmaDelete(Context cx, Object id);
+
+ /**
+ * Return an additional object to look for methods that runtime should
+ * consider during method search. Return null if no such object available.
+ */
+ public abstract Scriptable getExtraMethodSource(Context cx);
+
+ /**
+ * Generic reference to implement x.@y, x..y etc.
+ */
+ public abstract Ref memberRef(Context cx, Object elem,
+ int memberTypeFlags);
+
+ /**
+ * Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
+ */
+ public abstract Ref memberRef(Context cx, Object namespace, Object elem,
+ int memberTypeFlags);
+
+ /**
+ * Wrap this object into NativeWith to implement the with statement.
+ */
+ public abstract NativeWith enterWith(Scriptable scope);
+
+ /**
+ * Wrap this object into NativeWith to implement the .() query.
+ */
+ public abstract NativeWith enterDotQuery(Scriptable scope);
+
+ /**
+ * Custom <tt>+</tt> operator.
+ * Should return {@link Scriptable#NOT_FOUND} if this object does not have
+ * custom addition operator for the given value,
+ * or the result of the addition operation.
+ * <p>
+ * The default implementation returns {@link Scriptable#NOT_FOUND}
+ * to indicate no custom addition operation.
+ *
+ * @param cx the Context object associated with the current thread.
+ * @param thisIsLeft if true, the object should calculate this + value
+ * if false, the object should calculate value + this.
+ * @param value the second argument for addition operation.
+ */
+ public Object addValues(Context cx, boolean thisIsLeft, Object value)
+ {
+ return Scriptable.NOT_FOUND;
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/base.skip b/infrastructure/rhino1_7R1/testsrc/base.skip
new file mode 100644
index 0000000..35d6c54
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/base.skip
@@ -0,0 +1,685 @@
+# Rhino base skip list: these are tests that are always skipped for Rhino
+
+# These tests are skipped by Rhino either because a bug with a regression
+# test has yet to be fixed, or because the test is not applicable to Rhino.
+#
+
+# timer resolution test
+js1_5/extensions/regress-363258.js
+
+# Needs investigation
+js1_7/regress/regress-406477.js
+e4x/extensions/regress-410192.js
+
+# should be investigated: OutOfMemoryError
+js1_5/Regress/regress-330352.js
+
+# test consumes much memory, will get OutOfMemoryError depending on JVM
+# settings
+js1_5/extensions/regress-367501-04.js
+
+# stress test that can potentially time out
+js1_5/Regress/regress-404755.js
+
+# should be investigated: semicolon insertion
+ecma_3/LexicalConventions/7.9.1.js
+ecma_3/extensions/7.9.1.js
+
+# tests that do not work on non-English locales or for timezones outside the US
+ecma_3/Date/15.9.5.5.js
+js1_5/Regress/regress-58116.js
+
+# Fails on Macs?
+lc2/JavaToJS/char-002.js
+
+# Stress test; Reports of StackOverflowError (Mac only?)
+js1_5/Regress/regress-98901.js
+
+# performance regression test
+js1_5/Array/regress-99120-01.js
+js1_5/extensions/regress-371636.js
+
+# large concatenation of strings
+js1_5/Function/regress-338121-01.js
+js1_5/Function/regress-338121-02.js
+js1_5/Function/regress-338121-03.js
+
+# needs investigation: Date corner case
+ecma_3/Date/15.9.5.5-02.js
+
+# Infinite recursion
+e4x/Regress/regress-394941.js
+
+# GC tests
+js1_5/GC
+
+# bad test: random string generated will be too long about 1% of the time
+lc3/JavaArray/ToArray-001.js
+
+# would imply we would always need an activation for every non-leaf func
+js1_5/Regress/regress-383682.js
+
+# test depends on E4X, but test framework calls version(150)
+js1_5/Regress/regress-309242.js
+
+# performance test: Global vars should not be more than 2.5 times slower than local
+js1_5/Regress/regress-169559.js
+
+# infinite recursion
+js1_5/Regress/regress-234389.js
+
+# object watch not implemented
+js1_5/Regress/regress-240577.js
+js1_5/Function/regress-364023.js
+js1_5/Object/regress-362872-01.js
+js1_5/Object/regress-362872-02.js
+js1_5/Regress/regress-385393-06.js
+js1_5/extensions/regress-385393-09.js
+js1_7/GC/regress-381374.js
+
+# toLocaleFormat not implemented
+js1_5/extensions/toLocaleFormat-01.js
+js1_5/extensions/toLocaleFormat-02.js
+
+# source too complex
+js1_5/Expressions/regress-394673.js
+
+# import, export not implemented
+js1_5/Regress/regress-249211.js
+js1_7/lexical/regress-346642-03.js
+
+# concatentated string too large
+js1_5/Regress/regress-280769-1.js
+
+# stack overflow
+js1_5/Regress/regress-280769-2.js
+
+# performance tests
+js1_5/Regress/regress-313967-01.js
+js1_5/Regress/regress-313967-02.js
+js1_5/Array/regress-99120-02.js
+
+# concatentated string too large
+js1_5/Regress/regress-347306-01.js
+
+# import, export not implemented
+js1_5/decompilation/regress-349484.js
+
+# concatenated string too large
+js1_5/String/regress-157334-01.js
+js1_5/String/regress-56940-01.js
+js1_5/String/regress-56940-02.js
+
+# runs out of heap
+js1_5/Regress/regress-271716-n.js
+js1_5/Regress/regress-303213.js
+js1_5/Regress/regress-312588.js
+js1_5/Array/regress-157652.js
+js1_5/Regress/regress-330352.js
+
+# Tests that create very large strings by concatentation
+js1_5/extensions/regress-336409-1.js
+js1_5/extensions/regress-336409-2.js
+js1_5/extensions/regress-336410-1.js
+js1_5/extensions/regress-336410-2.js
+e4x/XML/regress-324422-1.js
+js1_5/Function/regress-338001.js
+js1_5/Regress/regress-159334.js
+js1_5/Regress/regress-191633.js
+js1_5/Regress/regress-280769-3.js
+js1_5/Regress/regress-280769-4.js
+js1_5/String/regress-314890.js
+js1_5/String/regress-322772.js
+js1_5/extensions/regress-363988.js
+
+# bug 152646 Will not fix this in Rhino; too much of a corner case
+js1_5/Regress/regress-152646.js
+
+#Verify error for bad branch
+js1_5/Regress/regress-96526-001.js
+js1_5/Regress/regress-96526-002.js
+js1_5/Regress/regress-96526-003.js
+
+# JSObject not used for Rhino LiveConnect
+lc3/ConvertJSObject
+lc3/Exceptions/throw_js_types.js
+lc3/JavaClass/ToJSObject-001.js
+lc3/JSObject/ToJSObject-001.js
+
+#Rhino implements Date.toLocaleTimeString() differently than SpiderMonkey
+ecma_3/Date/15.9.5.7.js
+
+#Rhino - as permitted by ECMA - does not allow indirect calls to eval
+js1_4/Eval/eval-001.js
+js1_4/Eval/eval-002.js
+js1_4/Eval/eval-003.js
+js1_5/Regress/regress-68498-003.js
+
+#Rhino compiled mode is limited by Java classfile size limitations
+#js1_5/Regress/regress-80981.js
+#js1_5/Regress/regress-90445.js
+#js1_5/Regress/regress-111557.js
+
+#Rhino relies on JVM to throw StackOverflow exception and does not
+#detect too deep recursion explicitly.
+js1_5/extensions/regress-192465.js
+js1_5/extensions/regress-226507.js
+js1_5/Regress/regress-89443.js
+
+# Skip these two; see http://bugzilla.mozilla.org/show_bug.cgi?id=81086, large
+# switch statement
+#ecma_3/Statements/regress-74474-002.js
+#ecma_3/Statements/regress-74474-003.js
+#Compiled mode cannot catch infinite recursion errors
+js1_5/Regress/regress-96128-n.js
+js1_5/Exceptions/regress-121658.js
+
+# This test uses the (non-ECMA) 'it' object of SpiderMonkey
+js1_2/version120/regress-99663.js
+
+# This test uses the gc() function of SpiderMonkey
+ecma_3/Function/regress-104584.js
+
+#This test uses the Error.stack property of SpiderMonkey (non-ECMA)
+js1_5/Exceptions/errstack-001.js
+
+#This test uses the clone() function in SpiderMonkey's js.c file
+#js1_5/Regress/regress-127557.js # apparently works, which doesn't make sense
+
+#These tests break with new Unicode in JDK 1.4
+ecma/String/15.5.4.11-2.js
+ecma/String/15.5.4.11-5.js
+ecma/String/15.5.4.12-1.js
+ecma/String/15.5.4.12-4.js
+ecma/String/15.5.4.12-5.js
+
+# Rhino doesn't implement the (non-ECMA) f.caller property
+js1_5/Function/regress-222029-001.js
+js1_5/Function/regress-222029-002.js
+
+# WONTFIX bug 119719
+js1_5/Regress/regress-119719.js
+
+# Bug Number 240317 relaxed errors for reserved identifiers but Rhino did not
+js1_5/Regress/regress-240317.js
+
+# Spidermonkey now defaults lineNumber and fileName
+# to the location and file where the exception occured.
+# exclude new test which assumes the defaults are
+# set according to Spidermonkey.
+js1_5/extensions/regress-50447-1.js
+
+# Invalid bug
+e4x/Regress/regress-278112.js
+
+# Invalid test? Cannot convert NaN to java.lang.Long
+lc3/template.js
+
+# Depends on generators being closed due to a call to gc(). Java finalizers
+# are not run immediately in a call to gc(), but instead usuallly are run
+# later on a different thread.
+js1_7/geniter/regress-347739.js
+js1_7/geniter/regress-349012-01.js
+js1_7/geniter/regress-349331.js
+
+# function named "yield"
+js1_7/lexical/regress-351515.js
+
+# unimplemented "options" shell function
+js1_7/block/regress-347559.js
+js1_5/Regress/regress-383674.js
+
+# decompilation
+js1_7/block/regress-344601.js
+js1_7/block/regress-351794.js
+js1_5/Regress/regress-10278.js
+
+# bad test: will fail if time of day increments a second between calls to Date()
+ecma/Date/15.9.2.1.js
+ecma/Date/15.9.2.2-2.js
+
+# JS 1.7 not yet implemented
+js1_7/decompilation
+# "y" flag for regexps
+js1_7/regexp/yflag.js
+# yield and xml-filtering predicate
+js1_7/geniter/regress-352605.js
+# js1_7 needs investigation
+js1_7/extensions/basic-for-each.js
+js1_7/extensions/regress-346642-06.js
+js1_7/extensions/regress-351102-03.js
+js1_7/extensions/regress-351102-04.js
+js1_7/extensions/regress-351102-05.js
+js1_7/extensions/regress-351102-07.js
+js1_7/extensions/regress-353214-01.js
+js1_7/extensions/regress-353214-02.js
+js1_7/extensions/regress-353249.js
+js1_7/extensions/regress-353454.js
+js1_7/extensions/regress-354945-02.js
+js1_7/extensions/regress-355145.js
+js1_7/extensions/regress-367629.js
+js1_7/extensions/regress-368213.js
+js1_7/extensions/regress-368224.js
+js1_7/extensions/regress-379482.js
+js1_7/extensions/regress-379566.js
+js1_7/extensions/regress-381301.js
+js1_7/extensions/regress-381303.js
+js1_7/iterable/regress-340526-02.js
+js1_7/regress/regress-350387.js
+js1_7/regress/regress-351503-01.js
+js1_7/regress/regress-351503-02.js
+js1_7/regress/regress-352870-01.js
+js1_7/regress/regress-352870-02.js
+js1_7/regress/regress-363040-01.js
+js1_7/regress/regress-363040-02.js
+js1_7/regress/regress-375695.js
+js1_7/regress/regress-379483.js
+
+# JS 1.8 not yet implemented
+js1_8
+
+# nondeterministic
+js1_5/Regress/regress-211590.js
+
+# long-running tests
+ecma/Date/15.9.5.10-2.js
+ecma/Date/15.9.5.11-2.js
+ecma/Date/15.9.5.12-2.js
+ecma/Date/15.9.5.8.js
+js1_5/Regress/regress-366122.js
+
+# "options" built-in function
+ecma_2/Exceptions/lexical-011.js
+ecma_2/Exceptions/lexical-014.js
+ecma_2/Exceptions/lexical-016.js
+ecma_2/Exceptions/lexical-021.js
+ecma_2/LexicalConventions/keywords-001.js
+js1_6/Regress/regress-378492.js
+js1_5/Regress/regress-115436.js
+js1_5/Regress/regress-214761.js
+js1_5/Regress/regress-253150.js
+js1_5/Regress/regress-306633.js
+js1_7/iterable/regress-355075-01.js
+js1_7/iterable/regress-355075-02.js
+
+# Function "exec" must be called directly, and not by way of a function of
+# another name.
+js1_5/extensions/regress-367119-01.js
+js1_5/extensions/regress-367119-02.js
+
+# Obsolete JS 1.2 behavior
+js1_2/operator/equality.js
+js1_3/regress/function-001-n.js
+js1_3/Script/function-001-n.js
+js1_2/function/function-001-n.js
+ecma_2/Exceptions/function-001.js
+
+# likely bugs. need investigation
+js1_6/Array/regress-386030.js
+ecma_3/Array/regress-387501.js
+js1_7/lexical/regress-336376-01.js
+
+# minor decompilation incompatibility
+js1_5/extensions/regress-384680.js
+
+# uninvestigated failures. May be some bugs in here.
+e4x/Regress/regress-373082.js
+e4x/XML/regress-376773.js
+e4x/decompilation/regress-352013.js
+e4x/decompilation/regress-352789.js
+e4x/extensions/regress-374163.js
+js1_5/Regress/regress-346237.js
+js1_5/decompilation/regress-351219.js
+js1_5/decompilation/regress-352453.js
+js1_5/decompilation/regress-353146.js
+js1_5/decompilation/regress-375882.js
+js1_5/extensions/regress-330569.js
+js1_5/extensions/regress-351448.js
+js1_5/extensions/regress-355736.js
+js1_5/extensions/regress-374589.js
+e4x/Expressions/11.1.4-01.js
+e4x/Expressions/11.1.4-02.js
+e4x/Expressions/11.1.4-03.js
+e4x/Expressions/11.1.4-04.js
+e4x/Expressions/11.1.4-08.js
+e4x/Expressions/11.1.4.js
+e4x/Expressions/11.6.1.js
+e4x/GC/regress-280844-1.js
+e4x/GC/regress-280844-1.js
+e4x/GC/regress-280844-2.js
+e4x/GC/regress-280844-2.js
+e4x/GC/regress-313952-02.js
+e4x/GC/regress-324278.js
+e4x/GC/regress-324278.js
+e4x/GC/regress-339785.js
+e4x/GC/regress-357063-01.js
+e4x/GC/regress-357063-02.js
+e4x/Global/13.1.2.1.js
+e4x/Regress/regress-257679.js
+e4x/Regress/regress-278112.js
+e4x/Regress/regress-308111.js
+e4x/Regress/regress-308111.js
+e4x/Regress/regress-309897.js
+e4x/Regress/regress-309897.js
+e4x/Regress/regress-311580.js
+e4x/Regress/regress-319872.js
+e4x/Regress/regress-319872.js
+e4x/Regress/regress-321547.js
+e4x/Regress/regress-322499.js
+e4x/Regress/regress-323338-1.js
+e4x/Regress/regress-323338-2.js
+e4x/Regress/regress-327564.js
+e4x/Regress/regress-329257.js
+e4x/Regress/regress-331558.js
+e4x/Regress/regress-344455.js
+e4x/Regress/regress-347155.js
+e4x/Regress/regress-347155.js
+e4x/decompilation/regress-350226.js
+e4x/Regress/regress-350238.js
+e4x/decompilation/regress-350531.js
+e4x/Regress/regress-350629.js
+e4x/decompilation/regress-351706.js
+e4x/decompilation/regress-351988.js
+e4x/Regress/regress-352097.js
+e4x/Regress/regress-352223.js
+e4x/decompilation/regress-352649.js
+e4x/Regress/regress-354998.js
+e4x/Regress/regress-355478.js
+e4x/Regress/regress-356238-02.js
+e4x/Regress/regress-356238-03.js
+e4x/Regress/regress-361451.js
+e4x/Regress/regress-364017.js
+e4x/Regress/regress-369740.js
+e4x/Regress/regress-370016.js
+e4x/Regress/regress-370048-01.js
+e4x/Regress/regress-370048-02.js
+e4x/Regress/regress-370372.js
+e4x/Regress/regress-371369.js
+e4x/Regress/regress-372563.js
+e4x/TypeConversion/10.2.1.js
+e4x/TypeConversion/10.5.1.js
+e4x/TypeConversion/10.5.js
+e4x/TypeConversion/10.6.1.js
+e4x/TypeConversion/10.6.js
+e4x/TypeConversion/regress-302097.js
+e4x/Types/9.1.1.10.js
+e4x/Types/9.1.1.11.js
+e4x/Types/9.1.1.12.js
+e4x/Types/9.1.1.13.js
+e4x/Types/9.1.1.4.js
+e4x/Types/9.1.1.5.js
+e4x/Types/9.1.1.7.js
+e4x/Types/9.1.1.8.js
+e4x/Types/9.1.1.9.js
+e4x/Types/9.2.1.10.js
+e4x/Types/9.2.1.3.js
+e4x/Types/9.2.1.4.js
+e4x/Types/9.2.1.5.js
+e4x/Types/9.2.1.6.js
+e4x/Types/9.2.1.7.js
+e4x/Types/9.2.1.9.js
+e4x/XML/13.4.3.js
+e4x/XML/13.4.4.1.js
+e4x/XML/13.4.4.10.js
+e4x/XML/13.4.4.17.js
+e4x/XML/13.4.4.26.js
+e4x/XML/13.4.4.28.js
+e4x/XML/13.4.4.3-01.js
+e4x/XML/13.4.4.3-02.js
+e4x/XML/regress-324422-2.js
+e4x/XMLList/regress-373072.js
+e4x/decompilation/decompile-xml-escapes.js
+e4x/extensions/regress-312196.js
+e4x/extensions/regress-313080.js
+e4x/extensions/regress-337226.js
+e4x/extensions/regress-352846-01.js
+e4x/extensions/regress-352846-02.js
+e4x/extensions/regress-352846-03.js
+e4x/extensions/regress-353165.js
+ecma/Array/15.4.3.1-2.js
+ecma/Array/15.4.5.1-1.js
+ecma/Boolean/15.6.3.1-1.js
+ecma/FunctionObjects/15.3.3.1-2.js
+ecma/Number/15.7.3.1-3.js
+ecma/ObjectObjects/15.2.3.1-1.js
+ecma/Statements/12.6.3-11.js
+ecma/Statements/12.6.3-2.js
+ecma/String/15.5.3.1-1.js
+ecma/String/15.5.4.11-2.js
+ecma/String/15.5.4.11-5.js
+ecma/String/15.5.4.12-1.js
+ecma/String/15.5.4.12-4.js
+ecma/String/15.5.4.12-5.js
+ecma_2/RegExp/exec-001.js
+ecma_2/RegExp/regexp-enumerate-001.js
+ecma_2/String/replace-001.js
+ecma_2/instanceof/instanceof-003.js
+ecma_3/Array/regress-322135-02.js
+ecma_3/Array/regress-322135-03.js
+ecma_3/Array/regress-322135-04.js
+ecma_3/Date/15.9.3.2-1.js
+ecma_3/Exceptions/15.11.7.6-001.js
+ecma_3/Object/8.6.1-01.js
+ecma_3/RegExp/regress-188206.js
+ecma_3/RegExp/regress-289669.js
+ecma_3/RegExp/regress-307456.js
+ecma_3/RegExp/regress-309840.js
+ecma_3/RegExp/regress-311414.js
+ecma_3/RegExp/regress-330684.js
+ecma_3/RegExp/regress-334158.js
+ecma_3/RegExp/regress-367888.js
+ecma_3/Statements/regress-121744.js
+ecma_3/String/15.5.4.14.js
+ecma_3/String/regress-304376.js
+ecma_3/extensions/regress-274152.js
+js1_1/regress/function-001.js
+js1_2/function/Function_object.js
+js1_2/function/regexparg-1.js
+js1_2/function/tostring-1.js
+js1_2/function/tostring-2.js
+js1_2/version120/regress-99663.js
+js1_4/Eval/eval-001.js
+js1_4/Eval/eval-002.js
+js1_4/Eval/eval-003.js
+js1_5/Array/regress-313153.js
+js1_5/Array/regress-330812.js
+js1_5/Array/regress-345961.js
+js1_5/Array/regress-350256-03.js
+js1_5/Array/regress-364104.js
+js1_5/Date/regress-301738-02.js
+js1_5/Date/regress-309925-02.js
+js1_5/Date/regress-346363.js
+js1_5/Date/toLocaleFormat.js
+js1_5/Exceptions/errstack-001.js
+js1_5/Exceptions/regress-121658.js
+js1_5/Exceptions/regress-315147.js
+js1_5/Exceptions/regress-332472.js
+js1_5/Exceptions/regress-333728.js
+js1_5/Exceptions/regress-342359.js
+js1_5/Exceptions/regress-350650-n.js
+js1_5/decompilation/regress-346902.js
+js1_5/decompilation/regress-346904.js
+js1_5/Expressions/regress-96526-delelem.js
+js1_5/Function/regress-222029-001.js
+js1_5/Function/regress-222029-002.js
+js1_5/Function/regress-344120.js
+js1_5/GC/regress-203278-2.js
+js1_5/GC/regress-278725.js
+js1_5/GC/regress-316885-01.js
+js1_5/GC/regress-324278.js
+js1_5/GC/regress-346794.js
+js1_5/GC/regress-348532.js
+js1_5/GetSet/getset-002.js
+js1_5/GetSet/regress-353264.js
+js1_5/LexicalConventions/regress-343675.js
+js1_5/Object/regress-308806-01.js
+js1_5/Regress/regress-103602.js
+js1_5/Regress/regress-106244.js
+js1_5/Regress/regress-119719.js
+js1_5/Regress/regress-139316.js
+js1_5/Regress/regress-173067.js
+js1_5/Regress/regress-203278-1.js
+js1_5/Regress/regress-213482.js
+js1_5/Regress/regress-247179.js
+js1_5/Regress/regress-248444.js
+js1_5/Regress/regress-252892.js
+js1_5/Regress/regress-261886.js
+js1_5/Regress/regress-261887.js
+js1_5/Regress/regress-274035.js
+js1_5/Regress/regress-280769-5.js
+js1_5/Regress/regress-280769.js
+js1_5/Regress/regress-281606.js
+js1_5/Regress/regress-290575.js
+js1_5/Regress/regress-294302.js
+js1_5/Regress/regress-315974.js
+js1_5/Regress/regress-317533.js
+js1_5/Regress/regress-319391.js
+js1_5/Regress/regress-320119.js
+js1_5/Regress/regress-321971.js
+js1_5/Regress/regress-323314-1.js
+js1_5/Regress/regress-325925.js
+js1_5/Regress/regress-328664.js
+js1_5/Regress/regress-329530.js
+js1_5/Regress/regress-334807-02.js
+js1_5/Regress/regress-334807-04.js
+js1_5/Regress/regress-336100.js
+js1_5/decompilation/regress-346892.js
+js1_5/decompilation/regress-346915.js
+js1_5/decompilation/regress-349491.js
+js1_5/decompilation/regress-349596.js
+js1_5/Regress/regress-349648.js
+js1_5/decompilation/regress-349650.js
+js1_5/decompilation/regress-350242.js
+js1_5/decompilation/regress-350263.js
+js1_5/Regress/regress-350268.js
+js1_5/decompilation/regress-350271.js
+js1_5/decompilation/regress-350666.js
+js1_5/Regress/regress-350692.js
+js1_5/decompilation/regress-351104.js
+js1_5/decompilation/regress-351597.js
+js1_5/decompilation/regress-351693.js
+js1_5/decompilation/regress-351793.js
+js1_5/Regress/regress-352009.js
+js1_5/decompilation/regress-352013.js
+js1_5/Regress/regress-352197.js
+js1_5/decompilation/regress-352202.js
+js1_5/decompilation/regress-352375.js
+js1_5/decompilation/regress-352649.js
+js1_5/decompilation/regress-353000.js
+js1_5/Regress/regress-354924.js
+js1_5/Regress/regress-355341.js
+js1_5/Regress/regress-355344.js
+js1_5/Regress/regress-355556.js
+js1_5/decompilation/regress-355992.js
+js1_5/Regress/regress-356693.js
+js1_5/Regress/regress-360969-05.js
+js1_5/Regress/regress-360969-06.js
+js1_5/Regress/regress-361467.js
+js1_5/Regress/regress-3649-n.js
+js1_5/Regress/regress-372364.js
+js1_5/Regress/regress-68498-003.js
+js1_5/Regress/regress-96526-002.js
+js1_5/extensions/getset-001.js
+js1_5/extensions/getset-003.js
+js1_5/extensions/regress-164697.js
+js1_5/extensions/regress-192465.js
+js1_5/extensions/regress-245148.js
+js1_5/extensions/regress-254375.js
+js1_5/extensions/regress-303277.js
+js1_5/extensions/regress-306738.js
+js1_5/extensions/regress-313630.js
+js1_5/extensions/regress-333541.js
+js1_5/extensions/regress-335700.js
+js1_5/extensions/regress-338804-02.js
+js1_5/extensions/regress-342960.js
+js1_5/extensions/regress-345967.js
+js1_5/extensions/regress-346494.js
+js1_5/extensions/regress-347306-02.js
+js1_5/extensions/regress-348986.js
+js1_5/extensions/regress-349616.js
+js1_5/extensions/regress-350531.js
+js1_5/extensions/regress-352060.js
+js1_5/extensions/regress-352094.js
+js1_5/extensions/regress-352372.js
+js1_5/extensions/regress-352455.js
+js1_5/extensions/regress-353214.js
+js1_5/extensions/regress-354541-02.js
+js1_5/extensions/regress-354541-04.js
+js1_5/extensions/regress-355339.js
+js1_5/extensions/regress-355497.js
+js1_5/extensions/regress-355820.js
+js1_5/extensions/regress-356085.js
+js1_5/extensions/regress-361346.js
+js1_5/extensions/regress-361360.js
+js1_5/extensions/regress-361552.js
+js1_5/extensions/regress-361558.js
+js1_5/extensions/regress-361571.js
+js1_5/extensions/regress-361964.js
+js1_5/extensions/regress-365869.js
+js1_5/extensions/regress-367923.js
+js1_5/extensions/regress-368859.js
+js1_5/extensions/regress-50447-1.js
+js1_6/Array/regress-290592.js
+js1_6/Array/regress-310425-01.js
+js1_6/Array/regress-320887.js
+js1_6/Regress/regress-350417.js
+js1_6/decompilation/regress-352084.js
+js1_6/decompilation/regress-352613-01.js
+js1_6/decompilation/regress-352613-02.js
+js1_6/Regress/regress-355002.js
+js1_6/Regress/regress-372565.js
+js1_6/String/regress-306591.js
+js1_6/extensions/regress-312385-01.js
+js1_6/extensions/regress-352392.js
+lc2/Arrays/array-008-n.js
+js1_5/Regress/regress-240317.js
+js1_5/Regress/regress-252892.js
+e4x/Expressions/regress-366123.js
+e4x/decompilation/regress-352459.js
+ecma/Date/15.9.5.31-1.js
+ecma/Date/15.9.5.35-1.js
+ecma_3/RegExp/regress-375642.js
+js1_5/Regress/regress-306727.js
+js1_5/Regress/regress-308566.js
+js1_5/Regress/regress-312260.js
+js1_5/Regress/regress-322430.js
+js1_5/decompilation/regress-356083.js
+js1_5/decompilation/regress-356248.js
+js1_5/extensions/regress-361856.js
+js1_5/extensions/regress-365527.js
+js1_5/extensions/regress-376052.js
+js1_6/Regress/regress-353078.js
+ecma_3/RegExp/regress-375715-01-n.js
+js1_5/extensions/regress-380581.js
+js1_5/extensions/regress-381205.js
+js1_5/extensions/regress-381211.js
+e4x/Regress/regress-383255.js
+ecma_3/RegExp/regress-375711.js
+ecma_3/RegExp/regress-375715-04.js
+js1_5/Regress/regress-367561-03.js
+js1_5/extensions/regress-367630.js
+js1_5/extensions/regress-375801.js
+js1_5/extensions/regress-380831.js
+js1_5/extensions/regress-382509.js
+js1_5/extensions/regress-383965.js
+js1_6/Regress/regress-382509.js
+js1_5/Function/regress-364023.js
+e4x/Regress/regress-380833.js
+js1_5/extensions/regress-358594-01.js
+js1_5/extensions/regress-358594-02.js
+js1_5/extensions/regress-358594-03.js
+js1_5/extensions/regress-358594-04.js
+js1_5/extensions/regress-358594-05.js
+js1_5/extensions/regress-358594-06.js
+js1_7/extensions/regress-380933.js
+ecma_3/extensions/regress-368516.js
+js1_5/extensions/regress-351463-01.js
+js1_5/extensions/regress-355655.js
+js1_7/block/regress-352422.js
+js1_7/block/regress-352786.js
+js1_7/block/regress-352907.js
+js1_7/block/regress-376410.js
+js1_7/block/regress-411279.js
+ecma_3/Number/15.7.4.2-01.js
+ecma_3/Number/15.7.4.3-01.js
+ecma_3/Number/15.7.4.7-2.js
diff --git a/infrastructure/rhino1_7R1/testsrc/build.xml b/infrastructure/rhino1_7R1/testsrc/build.xml
new file mode 100644
index 0000000..bc05516
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/build.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="testsrc" basedir="..">
+ <!--
+ Location of mozilla/js/tests directory
+ -->
+ <property name="test.library.dir" location="../tests" />
+
+ <!--
+ Destination to which testing classes should be built
+ -->
+ <property name="test.classes" value="${build.dir}/test/classes" />
+
+ <!--
+ Output directory for HTML files generated by jsdriver
+ -->
+ <property name="test.output" value="${build.dir}/test/output" />
+
+ <!--
+ Timeout in milliseconds for tests
+ -->
+ <property name="test.timeout" value="60000" />
+
+ <!--
+ Maximum heap size for VM executing test cases.
+ -->
+ <property name="test.vm.mx" value="256m" />
+
+ <target name="junit-compile">
+ <mkdir dir="${test.classes}" />
+ <get src="http://mirrors.ibiblio.org/pub/mirrors/maven2/junit/junit/3.8.2/junit-3.8.2.jar" dest="lib/junit.jar" usetimestamp="true"/>
+ <javac
+ srcdir="testsrc"
+ destdir="${test.classes}" debug="true"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ <classpath>
+ <pathelement path="lib/junit.jar" />
+ <pathelement path="${classes}" />
+ <pathelement path="${test-classes}" />
+ </classpath>
+ <include name="org/mozilla/javascript/drivers/StandardTests.java" />
+ </javac>
+ <antcall target="copy-files" />
+ </target>
+
+ <target name="compile">
+ <mkdir dir="${test.classes}" />
+ <javac
+ srcdir="testsrc"
+ destdir="${test.classes}" debug="true"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ <classpath>
+ <pathelement path="${classes}" />
+ </classpath>
+ <sourcepath path="testsrc" />
+ <include name="org/mozilla/javascript/drivers/JsDriver.java" />
+ </javac>
+ <antcall target="copy-files" />
+ </target>
+
+ <target name="copy-files">
+ <copy todir="${test.classes}">
+ <fileset dir="testsrc">
+ <exclude name="**/*.java build.xml"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="clean">
+ <delete dir="${test.classes}" />
+ </target>
+
+ <target name="coverage-instrument">
+ <get src="http://mirrors.ibiblio.org/pub/mirrors/maven2/emma/emma/2.0.5312/emma-2.0.5312.jar" dest="lib/emma.jar" usetimestamp="true"/>
+ <get src="http://mirrors.ibiblio.org/pub/mirrors/maven2/emma/emma_ant/2.0.5312/emma_ant-2.0.5312.jar" dest="lib/emma_ant.jar" usetimestamp="true"/>
+ <property name="coverage.dir" location="${build.dir}/coverage"/>
+ <property name="coverage.classes.dir" location="${build.dir}/coverage/classes"/>
+ <mkdir dir="${coverage.classes.dir}"/>
+ <path id="emma.lib">
+ <pathelement location="lib/emma.jar" />
+ <pathelement location="lib/emma_ant.jar" />
+ </path>
+ <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
+ <property name="coverage.instrumentationfile" location="${coverage.dir}/instrumentation"/>
+ <emma enabled="true">
+ <instr
+ instrpath="${classes}" outdir="${coverage.classes.dir}"
+ outfile="${coverage.instrumentationfile}" mode="copy"/>
+ </emma>
+ <copy todir="${coverage.classes.dir}">
+ <fileset dir="src" excludes="**/*.java"/>
+ </copy>
+ <copy todir="${coverage.classes.dir}">
+ <fileset dir="${classes}"/>
+ </copy>
+ <property name="coverage.outfile" location="${coverage.dir}/coverage"/>
+ </target>
+
+ <target name="junit" depends="junit-compile,coverage-instrument">
+ <junit printsummary="on" fork="true" forkmode="once" maxmemory="${test.vm.mx}" showoutput="true">
+ <sysproperty key="java.awt.headless" value="true" />
+ <sysproperty key="mozilla.js.tests" value="${test.library.dir}" />
+ <sysproperty key="mozilla.js.tests.timeout" value="${test.timeout}" />
+ <sysproperty key="emma.coverage.out.file" value="${coverage.outfile}"/>
+ <classpath>
+ <pathelement location="${xbean.jar}"/>
+ <pathelement location="${jsr173.jar}"/>
+ <pathelement path="${coverage.classes.dir}" />
+ <pathelement path="${classes}" />
+ <pathelement path="${test.classes}" />
+ <pathelement path="lib/emma.jar"/>
+ <pathelement path="lib/junit.jar" />
+ </classpath>
+ <batchtest todir="build/test">
+ <fileset dir="${test.classes}" includes="**/*Tests.class"/>
+ </batchtest>
+ <formatter type="plain" usefile="false" />
+ <formatter type="xml"/>
+ </junit>
+ <mkdir dir="build/test/report"/>
+ <junitreport todir="build/test/report">
+ <fileset dir="build/test" includes="*.xml"/>
+ <report todir="build/test/report"/>
+ </junitreport>
+ </target>
+
+ <target name="junit-coveragereport" depends="junit">
+ <property name="coverage.report.dir" location="${build.dir}/coverage/report"/>
+ <mkdir dir="${coverage.report.dir}"/>
+ <delete dir="${coverage.report.dir}"/>
+ <mkdir dir="${coverage.report.dir}"/>
+ <emma enabled="true">
+ <report>
+ <fileset dir="${basedir}">
+ <include name="build/coverage/instrumentation"/>
+ <include name="build/coverage/coverage"/>
+ </fileset>
+ <sourcepath>
+ <dirset dir="${basedir}">
+ <include name="src"/>
+ </dirset>
+ </sourcepath>
+ <html outfile="${coverage.report.dir}/index.html"/>
+ </report>
+ </emma>
+ </target>
+
+ <target name="jsdriver" depends="compile">
+ <tstamp>
+ <format property="test.timestamp" pattern="yyyy.MM.dd.HH.mm.ss" />
+ </tstamp>
+ <mkdir dir="${test.output}" />
+ <java
+ fork="true"
+ classname="org.mozilla.javascript.drivers.JsDriver"
+ maxmemory="${test.vm.mx}"
+ >
+ <classpath>
+ <pathelement location="${xbean.jar}"/>
+ <pathelement location="${jsr173.jar}"/>
+ <pathelement path="${classes}" />
+ <pathelement path="${test.classes}" />
+ </classpath>
+ <arg value="-p" />
+ <arg file="${test.library.dir}" />
+ <arg value="-f" />
+ <arg value="${test.output}/rhino-test-results.${test.timestamp}.html" />
+ <arg value="--timeout" />
+ <arg value="${test.timeout}" />
+ </java>
+ </target>
+
+ <target name="copy-source">
+ <mkdir dir="${dist.dir}/testsrc"/>
+ <copy todir="${dist.dir}/testsrc">
+ <fileset dir="testsrc"
+ includes="**/*.java,**/*.properties,**/*.xml,**/*.html,**/*.skip" />
+ </copy>
+ </target>
+</project>
diff --git a/infrastructure/rhino1_7R1/testsrc/opt1.skip b/infrastructure/rhino1_7R1/testsrc/opt1.skip
new file mode 100644
index 0000000..7006882
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/opt1.skip
@@ -0,0 +1,26 @@
+# Rhino skip list: opt1.skip. Tests to be run at -opt 1
+# These tests are skipped by Rhino either because a bug with a regression
+# test has yet to be fixed, or because the test is not applicable to Rhino.
+
+# program too large/complex
+ecma_3/Statements/regress-302439.js
+ecma_3/Statements/regress-324650.js
+ecma_3/Statements/regress-74474-002.js
+ecma_3/Statements/regress-74474-003.js
+js1_5/Regress/regress-244470.js
+js1_5/Regress/regress-308085.js
+js1_5/Regress/regress-80981.js
+js1_5/Regress/regress-89443.js
+js1_5/extensions/regress-226507.js
+
+# program too large/complex; could have better error message
+js1_5/Regress/regress-111557.js
+js1_5/Regress/regress-155081-2.js
+js1_5/Regress/regress-155081.js
+js1_5/extensions/regress-311161.js
+
+# Missing line number information on error
+js1_5/Regress/regress-167328.js
+js1_5/extensions/regress-50447.js
+js1_5/Exceptions/regress-257751.js
+
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/JsDriver.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/JsDriver.java
new file mode 100644
index 0000000..8bae79f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/JsDriver.java
@@ -0,0 +1,838 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Java port of jsDriver.pl.
+ *
+ * The Initial Developer of the Original Code is
+ * David P. Caldwell.
+ * Portions created by David P. Caldwell are Copyright (C)
+ * 2007 David P. Caldwell. All Rights Reserved.
+ *
+ *
+ * Contributor(s):
+ * David P. Caldwell <inonit@inonit.com>
+ * Norris Boyd <norrisboyd@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.drivers;
+
+import java.io.*;
+import java.util.*;
+
+import org.w3c.dom.*;
+
+import org.mozilla.javascript.tools.shell.*;
+
+/**
+ * @version $Id: JsDriver.java,v 1.5 2007/10/11 19:44:10 szegedia%freemail.hu Exp $
+ */
+public class JsDriver {
+ private JsDriver() {
+ }
+
+ private static String join(String[] list) {
+ String rv = "";
+ for (int i=0; i<list.length; i++) {
+ rv += list[i];
+ if (i+1 != list.length) {
+ rv += ",";
+ }
+ }
+ return rv;
+ }
+
+ private static class Tests {
+ private File testDirectory;
+ private String[] list;
+ private String[] skip;
+
+ Tests(File testDirectory, String[] list, String[] skip) {
+ this.testDirectory = testDirectory;
+ this.list = getTestList(list);
+ this.skip = getTestList(skip);
+ }
+
+ private String[] getTestList(String[] tests) {
+ ArrayList list = new ArrayList();
+ for (int i=0; i < tests.length; i++) {
+ if (tests[i].startsWith("@"))
+ addTestsFromFile(tests[i].substring(1), list);
+ else
+ list.add(tests[i]);
+ }
+ return (String[])list.toArray(new String[0]);
+ }
+
+ private void addTestsFromFile(String filename, ArrayList list) {
+ try {
+ Properties props = new Properties();
+ props.load(new FileInputStream(new File(filename)));
+ list.addAll(props.keySet());
+ } catch (IOException e) {
+ throw new RuntimeException("Could not read file '" + filename + "'", e);
+ }
+ }
+
+ private boolean matches(String[] patterns, String path) {
+ for (int i=0; i<patterns.length; i++) {
+ if (path.startsWith(patterns[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean matches(String path) {
+ if (list.length == 0) return true;
+ return matches(list, path);
+ }
+
+ private boolean excluded(String path) {
+ if (skip.length == 0) return false;
+ return matches(skip, path);
+ }
+
+ private void addFiles(List rv, String prefix, File directory) {
+ File[] files = directory.listFiles();
+ if (files == null) throw new RuntimeException("files null for " + directory);
+ for (int i=0; i<files.length; i++) {
+ String path = prefix + files[i].getName();
+ if (ShellTest.DIRECTORY_FILTER.accept(files[i])) {
+ addFiles(rv, path + "/", files[i]);
+ } else {
+ boolean isTopLevel = prefix.length() == 0;
+ if (ShellTest.TEST_FILTER.accept(files[i]) && matches(path) && !excluded(path) && !isTopLevel) {
+ rv.add(new Script(path, files[i]));
+ }
+ }
+ }
+ }
+
+ static class Script {
+ private String path;
+ private File file;
+
+ Script(String path, File file) {
+ this.path = path;
+ this.file = file;
+ }
+
+ String getPath() {
+ return path;
+ }
+
+ File getFile() {
+ return file;
+ }
+ }
+
+ Script[] getFiles() {
+ ArrayList rv = new ArrayList();
+ addFiles(rv, "", testDirectory);
+ return (Script[])rv.toArray(new Script[0]);
+ }
+ }
+
+ private static class ConsoleStatus extends ShellTest.Status {
+ private File jsFile;
+
+ private Arguments.Console console;
+ private boolean trace;
+
+ private boolean failed;
+
+ ConsoleStatus(Arguments.Console console, boolean trace) {
+ this.console = console;
+ this.trace = trace;
+ }
+
+ void running(File jsFile) {
+ try {
+ console.println("Running: " + jsFile.getCanonicalPath());
+ this.jsFile = jsFile;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ void failed(String s) {
+ console.println("Failed: " + jsFile + ": " + s);
+ failed = true;
+ }
+
+ void threw(Throwable t) {
+ console.println("Failed: " + jsFile + " with exception.");
+ console.println(ShellTest.getStackTrace(t));
+ failed = true;
+ }
+
+ void timedOut() {
+ console.println("Failed: " + jsFile + ": timed out.");
+ failed = true;
+ }
+
+ void exitCodesWere(int expected, int actual) {
+ if (expected != actual) {
+ console.println("Failed: " + jsFile + " expected " + expected + " actual " + actual);
+ failed = true;
+ }
+ }
+
+ void outputWas(String s) {
+ if (!failed) {
+ console.println("Passed: " + jsFile);
+ if (trace) {
+ console.println(s);
+ }
+ }
+ }
+ }
+
+ // returns true if node was found, false otherwise
+ private static boolean setContent(Element node, String id, String content) {
+ if (node.getAttribute("id").equals(id)) {
+ node.setTextContent(node.getTextContent() + "\n" + content);
+ return true;
+ } else {
+ NodeList children = node.getChildNodes();
+ for (int i=0; i<children.getLength(); i++) {
+ if (children.item(i) instanceof Element) {
+ Element e = (Element)children.item(i);
+ boolean rv = setContent( e, id, content );
+ if (rv) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private static Element getElementById(Element node, String id) {
+ if (node.getAttribute("id").equals(id)) {
+ return node;
+ } else {
+ NodeList children = node.getChildNodes();
+ for (int i=0; i<children.getLength(); i++) {
+ if (children.item(i) instanceof Element) {
+ Element rv = getElementById( (Element)children.item(i), id );
+ if (rv != null) {
+ return rv;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String newlineLineEndings(String s) {
+ StringBuffer rv = new StringBuffer();
+ for (int i=0; i<s.length(); i++) {
+ if (s.charAt(i) == '\r') {
+ if (i+1<s.length() && s.charAt(i+1) == '\n') {
+ // just skip \r
+ } else {
+ // Macintosh, substitute \n
+ rv.append('\n');
+ }
+ } else {
+ rv.append(s.charAt(i));
+ }
+ }
+ return rv.toString();
+ }
+
+ private static class HtmlStatus extends ShellTest.Status {
+ private String testPath;
+ private String bugUrl;
+ private String lxrUrl;
+ private Document html;
+ private Element failureHtml;
+ private boolean failed;
+
+ private String output;
+
+ HtmlStatus(String lxrUrl, String bugUrl, String testPath, Document html, Element failureHtml) {
+ this.testPath = testPath;
+ this.bugUrl = bugUrl;
+ this.lxrUrl = lxrUrl;
+ this.html = html;
+ this.failureHtml = failureHtml;
+ }
+
+ void running(File file) {
+ }
+
+ void failed(String s) {
+ failed = true;
+ setContent(failureHtml, "failureDetails.reason", "Failure reason: \n" + s);
+ }
+
+ void exitCodesWere(int expected, int actual) {
+ if (expected != actual) {
+ failed = true;
+ setContent(failureHtml, "failureDetails.reason", "expected exit code " + expected + " but got " + actual);
+ }
+ }
+
+ void threw(Throwable e) {
+ failed = true;
+ setContent(failureHtml, "failureDetails.reason", "Threw Java exception:\n" + newlineLineEndings(ShellTest.getStackTrace(e)));
+ }
+
+ void timedOut() {
+ failed = true;
+ setContent(failureHtml, "failureDetails.reason", "Timed out.");
+ }
+
+ void outputWas(String s) {
+ this.output = s;
+ }
+
+ private String getLinesStartingWith(String prefix) {
+ BufferedReader r = new BufferedReader(new StringReader(output));
+ String line = null;
+ String rv = "";
+ try {
+ while( (line = r.readLine()) != null ) {
+ if (line.startsWith(prefix)) {
+ if (rv.length() > 0) {
+ rv += "\n";
+ }
+ rv += line;
+ }
+ }
+ return rv;
+ } catch (IOException e) {
+ throw new RuntimeException("Can't happen.");
+ }
+ }
+
+ boolean failed() {
+ return failed;
+ }
+
+ void finish() {
+ if (failed) {
+ getElementById(failureHtml, "failureDetails.status").setTextContent(getLinesStartingWith("STATUS:"));
+
+ String bn = getLinesStartingWith("BUGNUMBER:");
+ Element bnlink = getElementById(failureHtml, "failureDetails.bug.href");
+ if (bn.length() > 0) {
+ String number = bn.substring("BUGNUMBER: ".length());
+ if (!number.equals("none")) {
+ bnlink.setAttribute("href", bugUrl + number);
+ getElementById(bnlink, "failureDetails.bug.number").setTextContent(number);
+ } else {
+ bnlink.getParentNode().removeChild(bnlink);
+ }
+ } else {
+ bnlink.getParentNode().removeChild(bnlink);
+ }
+
+ getElementById(failureHtml, "failureDetails.lxr").setAttribute("href", lxrUrl + testPath);
+ getElementById(failureHtml, "failureDetails.lxr.text").setTextContent(testPath);
+
+ getElementById(html.getDocumentElement(), "retestList.text").setTextContent(
+ getElementById(html.getDocumentElement(), "retestList.text").getTextContent()
+ + testPath
+ + "\n"
+ );
+
+ getElementById(html.getDocumentElement(), "failureDetails").appendChild(failureHtml);
+ }
+ }
+ }
+
+ private static class XmlStatus extends ShellTest.Status {
+ private Element target;
+ private Date start;
+
+ XmlStatus(String path, Element root) {
+ this.target = root.getOwnerDocument().createElement("test");
+ this.target.setAttribute("path", path);
+ root.appendChild(target);
+ }
+
+ void running(File file) {
+ this.start = new Date();
+ }
+
+ private Element createElement(Element parent, String name) {
+ Element rv = parent.getOwnerDocument().createElement(name);
+ parent.appendChild(rv);
+ return rv;
+ }
+
+ private void finish() {
+ Date end = new Date();
+ long elapsed = end.getTime() - start.getTime();
+ this.target.setAttribute("elapsed", String.valueOf(elapsed));
+ }
+
+ private void setTextContent(Element e, String content) {
+ e.setTextContent( newlineLineEndings(content) );
+ }
+
+ void exitCodesWere(int expected, int actual) {
+ finish();
+ Element exit = createElement(target, "exit");
+ exit.setAttribute("expected", String.valueOf(expected));
+ exit.setAttribute("actual", String.valueOf(actual));
+ }
+
+ void timedOut() {
+ finish();
+ createElement(target, "timedOut");
+ }
+
+ void failed(String s) {
+ finish();
+ Element failed = createElement(target, "failed");
+ setTextContent(failed, s);
+ }
+
+ void outputWas(String message) {
+ finish();
+ Element output = createElement(target, "output");
+ setTextContent(output, message);
+ }
+
+ void threw(Throwable t) {
+ finish();
+ Element threw = createElement(target, "threw");
+ setTextContent(threw, ShellTest.getStackTrace(t));
+ }
+ }
+
+ private static class Results {
+ private ShellContextFactory factory;
+ private Arguments arguments;
+ private File output;
+ private boolean trace;
+
+ private Document html;
+ private Element failureHtml;
+
+ private Document xml;
+
+ private Date start;
+ private int tests;
+ private int failures;
+
+ Results(ShellContextFactory factory, Arguments arguments, boolean trace) {
+ this.factory = factory;
+ this.arguments = arguments;
+
+ File output = arguments.getOutputFile();
+ if (output == null) {
+ output = new File("rhino-test-results." + new java.text.SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date()) + ".html");
+ }
+ this.output = output;
+
+ this.trace = trace;
+ }
+
+ private Document parse(InputStream in) {
+ try {
+ javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ factory.setValidating(false);
+ javax.xml.parsers.DocumentBuilder dom = factory.newDocumentBuilder();
+ return dom.parse(in);
+ } catch (Throwable t) {
+ throw new RuntimeException("Parser failure", t);
+ }
+ }
+
+ private Document getTemplate() {
+ return parse(getClass().getResourceAsStream("results.html"));
+ }
+
+ private void write(Document template, boolean xml) {
+ try {
+ File output = this.output;
+ javax.xml.transform.TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance();
+ javax.xml.transform.Transformer xform = factory.newTransformer();
+ if (xml) {
+ xform.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml");
+ xform.setOutputProperty(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
+ output = new File(output.getCanonicalPath() + ".xml");
+ }
+ xform.transform(
+ new javax.xml.transform.dom.DOMSource(template),
+ new javax.xml.transform.stream.StreamResult( new FileOutputStream(output) )
+ );
+ } catch (IOException e) {
+ arguments.getConsole().println("Could not write results file to " + output + ": ");
+ e.printStackTrace(System.err);
+ } catch (javax.xml.transform.TransformerConfigurationException e) {
+ throw new RuntimeException("Parser failure", e);
+ } catch (javax.xml.transform.TransformerException e) {
+ throw new RuntimeException("Parser failure", e);
+ }
+ }
+
+ void start() {
+ this.html = getTemplate();
+ this.failureHtml = getElementById(html.getDocumentElement(), "failureDetails.prototype");
+ if (this.failureHtml == null) {
+ try {
+ javax.xml.transform.TransformerFactory.newInstance().newTransformer().transform(
+ new javax.xml.transform.dom.DOMSource(html),
+ new javax.xml.transform.stream.StreamResult(System.err)
+ );
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ throw new RuntimeException("No");
+ }
+ this.failureHtml.getParentNode().removeChild(this.failureHtml);
+
+ try {
+ this.xml = javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .getDOMImplementation().createDocument(null, "results", null)
+ ;
+ xml.getDocumentElement().setAttribute("timestamp", String.valueOf(new Date().getTime()));
+ xml.getDocumentElement().setAttribute("optimization", String.valueOf(arguments.getOptimizationLevel()));
+ xml.getDocumentElement().setAttribute("strict", String.valueOf(arguments.isStrict()));
+ xml.getDocumentElement().setAttribute("timeout", String.valueOf(arguments.getTimeout()));
+ } catch (javax.xml.parsers.ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+
+ this.start = new Date();
+ }
+
+ void run(Tests.Script script, ShellTest.Parameters parameters) {
+ String path = script.getPath();
+ File test = script.getFile();
+ ConsoleStatus cStatus = new ConsoleStatus(arguments.getConsole(), trace);
+ HtmlStatus hStatus = new HtmlStatus(arguments.getLxrUrl(), arguments.getBugUrl(), path, html, (Element)failureHtml.cloneNode(true));
+ XmlStatus xStatus = new XmlStatus(path, this.xml.getDocumentElement());
+ ShellTest.Status status = ShellTest.Status.compose(new ShellTest.Status[] { cStatus, hStatus, xStatus });
+ try {
+ ShellTest.run(factory, test, parameters, status);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ tests++;
+ if (hStatus.failed()) {
+ failures++;
+ }
+ hStatus.finish();
+ }
+
+ private void set(Document document, String id, String value) {
+ getElementById(document.getDocumentElement(), id).setTextContent(value);
+ }
+
+ void finish() {
+ Date end = new Date();
+ long elapsedMs = end.getTime() - start.getTime();
+ set(html, "results.testlist", join(arguments.getTestList()));
+ set(html, "results.skiplist", join(arguments.getSkipList()));
+ String pct = new java.text.DecimalFormat("##0.00").format( (double)failures / (double)tests * 100.0 );
+ set(html, "results.results", "Tests attempted: " + tests + " Failures: " + failures + " (" + pct + "%)");
+ set(html, "results.platform", "java.home=" + System.getProperty("java.home")
+ + "\n" + "java.version=" + System.getProperty("java.version")
+ + "\n" + "os.name=" + System.getProperty("os.name")
+ );
+ set(html, "results.classpath", System.getProperty("java.class.path").replace(File.pathSeparatorChar, ' '));
+ int elapsedSeconds = (int)(elapsedMs / 1000);
+ int elapsedMinutes = elapsedSeconds / 60;
+ elapsedSeconds = elapsedSeconds % 60;
+ String elapsed = "" + elapsedMinutes + " minutes, " + elapsedSeconds + " seconds";
+ set(html, "results.elapsed", elapsed);
+ set(html, "results.time", new java.text.SimpleDateFormat("MMMM d yyyy h:mm:ss aa").format(new java.util.Date()));
+ write(html, false);
+ write(xml, true);
+ }
+ }
+
+ private static class ShellTestParameters extends ShellTest.Parameters {
+ private int timeout;
+
+ ShellTestParameters(int timeout) {
+ this.timeout = timeout;
+ }
+
+ int getTimeoutMilliseconds() {
+ return timeout;
+ }
+ }
+
+ void run(Arguments arguments) throws Throwable {
+ if (arguments.help()) {
+ System.out.println("See mozilla/js/tests/README-jsDriver.html; note that some options are not supported.");
+ System.out.println("Consult the Java source code at testsrc/org/mozilla/javascript/JsDriver.java for details.");
+ System.exit(0);
+ }
+
+ ShellContextFactory factory = new ShellContextFactory();
+ factory.setOptimizationLevel(arguments.getOptimizationLevel());
+ factory.setStrictMode(arguments.isStrict());
+
+ File path = arguments.getTestsPath();
+ if (path == null) {
+ path = new File("../tests");
+ }
+ if (!path.exists()) {
+ throw new RuntimeException("JavaScript tests not found at " + path.getCanonicalPath());
+ }
+ Tests tests = new Tests(path, arguments.getTestList(), arguments.getSkipList());
+ Tests.Script[] all = tests.getFiles();
+ arguments.getConsole().println("Running " + all.length + " tests.");
+
+ Results results = new Results(factory, arguments, arguments.trace());
+
+ results.start();
+ for (int i=0; i<all.length; i++) {
+ results.run(all[i], new ShellTestParameters(arguments.getTimeout()));
+ }
+ results.finish();
+ }
+
+ public static void main(Arguments arguments) throws Throwable {
+ JsDriver driver = new JsDriver();
+ driver.run(arguments);
+ }
+
+ private static class Arguments {
+ private ArrayList options = new ArrayList();
+
+ private Option bugUrl = new Option("b", "bugurl", false, false, "http://bugzilla.mozilla.org/show_bug.cgi?id=");
+ private Option optimizationLevel = new Option("o", "optimization", false, false, "-1");
+ private Option strict = new Option(null, "strict", false, true, null);
+ private Option outputFile = new Option("f", "file", false, false, null);
+ private Option help = new Option("h", "help", false, true, null);
+ private Option logFailuresToConsole = new Option("k", "confail", false, true, null);
+ private Option testList = new Option("l", "list", true, false, null);
+ private Option skipList = new Option("L", "neglist", true, false, null);
+ private Option testsPath = new Option("p", "testpath", false, false, null);
+ private Option trace = new Option("t", "trace", false, true, null);
+ private Option lxrUrl = new Option("u", "lxrurl", false, false, "http://lxr.mozilla.org/mozilla/source/js/tests/");
+ private Option timeout = new Option(null, "timeout", false, false, "60000");
+
+ public static class Console {
+ public void print(String message) {
+ System.out.print(message);
+ }
+ public void println(String message) {
+ System.out.println(message);
+ }
+ }
+ private Console console = new Console();
+
+ private class Option {
+ private String letterOption;
+ private String wordOption;
+ private boolean array;
+ private boolean flag;
+ private boolean ignored;
+
+ private ArrayList values = new ArrayList();
+
+ // array: can this option have multiple values?
+ // flag: is this option a simple true/false switch?
+ Option(String letterOption, String wordOption, boolean array, boolean flag, String unspecified) {
+ this.letterOption = letterOption;
+ this.wordOption = wordOption;
+ this.flag = flag;
+ this.array = array;
+ if (!flag && !array) {
+ this.values.add(unspecified);
+ }
+ options.add(this);
+ }
+
+ Option ignored() {
+ this.ignored = true;
+ return this;
+ }
+
+ int getInt() {
+ return Integer.parseInt( getValue() );
+ }
+
+ String getValue() {
+ return (String)values.get(0);
+ }
+
+ boolean getSwitch() {
+ return values.size() > 0;
+ }
+
+ File getFile() {
+ if (getValue() == null) return null;
+ return new File(getValue());
+ }
+
+ String[] getValues() {
+ return (String[])values.toArray(new String[0]);
+ }
+
+ void process(List arguments) {
+ String option = (String)arguments.get(0);
+ String dashLetter = (letterOption == null) ? (String)null : "-" + letterOption;
+ if (option.equals(dashLetter) || option.equals("--" + wordOption)) {
+ arguments.remove(0);
+ if (flag) {
+ values.add(0, (String)null );
+ } else if (array) {
+ while( arguments.size() > 0 && !( (String)arguments.get(0) ).startsWith("-") ) {
+ values.add(arguments.remove(0));
+ }
+ } else {
+ values.set(0, arguments.remove(0));
+ }
+ if (ignored) {
+ System.err.println("WARNING: " + option + " is ignored in the Java version of the test driver.");
+ }
+ }
+ }
+ }
+
+ // -b URL, --bugurl=URL
+ public String getBugUrl() {
+ return bugUrl.getValue();
+ }
+
+ // -c PATH, --classpath=PATH
+ // Does not apply; we will use the VM's classpath
+
+ // -e TYPE ..., --engine=TYPE ...
+ // Does not apply; was used to select between SpiderMonkey and Rhino
+
+ // Not in jsDriver.pl
+ public int getOptimizationLevel() {
+ return optimizationLevel.getInt();
+ }
+
+ // --strict
+ public boolean isStrict() {
+ return strict.getSwitch();
+ }
+
+ // -f FILE, --file=FILE
+ public File getOutputFile() {
+ return outputFile.getFile();
+ }
+
+ // -h, --help
+ public boolean help() {
+ return help.getSwitch();
+ }
+
+ // -j PATH, --javapath=PATH
+ // Does not apply; we will use this JVM
+
+ // -k, --confail
+ // TODO Currently this is ignored; not clear precisely what it means (perhaps we should not be logging ordinary
+ // pass/fail to the console currently?)
+ public boolean logFailuresToConsole() {
+ return logFailuresToConsole.getSwitch();
+ }
+
+ // -l FILE,... or --list=FILE,...
+ public String[] getTestList() {
+ return testList.getValues();
+ }
+
+ // -L FILE,... or --neglist=FILE,...
+ public String[] getSkipList() {
+ return skipList.getValues();
+ }
+
+ // -p PATH, --testpath=PATH
+ public File getTestsPath() {
+ return testsPath.getFile();
+ }
+
+ // -s PATH, --shellpath=PATH
+ // Does not apply; we will use the Rhino shell with any classes given on the classpath
+
+ // -t, --trace
+ public boolean trace() {
+ return trace.getSwitch();
+ }
+
+ // -u URL, --lxrurl=URL
+ public String getLxrUrl() {
+ return lxrUrl.getValue();
+ }
+
+ //
+ // New arguments
+ //
+
+ // --timeout
+ // Milliseconds to wait for each test
+ public int getTimeout() {
+ return timeout.getInt();
+ }
+
+ public Console getConsole() {
+ return console;
+ }
+
+ void process(List arguments) {
+ while(arguments.size() > 0) {
+ String option = (String)arguments.get(0);
+ if (option.startsWith("--")) {
+ // preprocess --name=value options into --name value
+ if (option.indexOf("=") != -1) {
+ arguments.set(0, option.substring(option.indexOf("=")));
+ arguments.add(1, option.substring(option.indexOf("=") + 1));
+ }
+ } else if (option.startsWith("-")) {
+ // could be multiple single-letter options, e.g. -kht, so preprocess them into -k -h -t
+ if (option.length() > 2) {
+ for (int i=2; i<option.length(); i++) {
+ arguments.add(1, "-" + option.substring(i,i+1));
+ }
+ arguments.set(0, option.substring(0,2));
+ }
+ }
+ int lengthBefore = arguments.size();
+ for (int i=0; i<options.size(); i++) {
+ if (arguments.size() > 0) {
+ ((Option)options.get(i)).process(arguments);
+ }
+ }
+
+ if (arguments.size() == lengthBefore) {
+ System.err.println("WARNING: ignoring unrecognized option " + arguments.remove(0));
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ ArrayList arguments = new ArrayList();
+ arguments.addAll(Arrays.asList(args));
+ Arguments clArguments = new Arguments();
+ clArguments.process(arguments);
+ main(clArguments);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java
new file mode 100644
index 0000000..9acf64e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java
@@ -0,0 +1,346 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Java port of jsDriver.pl.
+ *
+ * The Initial Developer of the Original Code is
+ * David P. Caldwell.
+ * Portions created by David P. Caldwell are Copyright (C)
+ * 2007 David P. Caldwell. All Rights Reserved.
+ *
+ *
+ * Contributor(s):
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.drivers;
+
+import org.mozilla.javascript.*;
+import java.io.*;
+import java.util.*;
+
+import org.mozilla.javascript.tools.shell.*;
+
+/**
+ * @version $Id: ShellTest.java,v 1.5 2007/10/11 19:44:10 szegedia%freemail.hu Exp $
+ */
+class ShellTest {
+ static final FileFilter DIRECTORY_FILTER = new FileFilter() {
+ public boolean accept(File pathname)
+ {
+ return pathname.isDirectory() && !pathname.getName().equals("CVS");
+ }
+ };
+
+ static final FileFilter TEST_FILTER = new FileFilter() {
+ public boolean accept(File pathname)
+ {
+ return pathname.getName().endsWith(".js") && !pathname.getName().equals("shell.js") && !pathname.getName().equals("browser.js") && !pathname.getName().equals("template.js");
+ }
+ };
+
+ static String getStackTrace(Throwable t) {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ t.printStackTrace(new PrintStream(bytes));
+ return new String(bytes.toByteArray());
+ }
+
+ private static void runFileIfExists(Context cx, Scriptable global, File f)
+ {
+ if(f.isFile())
+ {
+ Main.processFile(cx, global, f.getPath());
+ }
+ }
+
+ private static class TestState
+ {
+ boolean finished;
+ ErrorReporterWrapper errors;
+ int exitCode = 0;
+ }
+
+ static abstract class Status {
+ private boolean negative;
+
+ final void setNegative() {
+ this.negative = true;
+ }
+
+ final boolean isNegative() {
+ return this.negative;
+ }
+
+ final void hadErrors(JsError[] errors) {
+ if (!negative && errors.length > 0) {
+ failed("JavaScript errors:\n" + JsError.toString(errors));
+ } else if (negative && errors.length == 0) {
+ failed("Should have produced runtime error.");
+ }
+ }
+
+ abstract void running(File jsFile);
+
+ abstract void failed(String s);
+ abstract void threw(Throwable t);
+ abstract void timedOut();
+ abstract void exitCodesWere(int expected, int actual);
+ abstract void outputWas(String s);
+
+ static Status compose(final Status[] array) {
+ return new Status() {
+ void running(File file) {
+ for (int i=0; i<array.length; i++) {
+ array[i].running(file);
+ }
+ }
+ void threw(Throwable t) {
+ for (int i=0; i<array.length; i++) {
+ array[i].threw(t);
+ }
+ }
+ void failed(String s) {
+ for (int i=0; i<array.length; i++) {
+ array[i].failed(s);
+ }
+ }
+ void exitCodesWere(int expected, int actual) {
+ for (int i=0; i<array.length; i++) {
+ array[i].exitCodesWere(expected, actual);
+ }
+ }
+ void outputWas(String s) {
+ for (int i=0; i<array.length; i++) {
+ array[i].outputWas(s);
+ }
+ }
+ void timedOut() {
+ for (int i=0; i<array.length; i++) {
+ array[i].timedOut();
+ }
+ }
+ };
+ }
+
+ static class JsError {
+ static String toString(JsError[] e) {
+ String rv = "";
+ for (int i=0; i<e.length; i++) {
+ rv += e[i].toString();
+ if (i+1 != e.length) {
+ rv += "\n";
+ }
+ }
+ return rv;
+ }
+
+ private String message;
+ private String sourceName;
+ private int line;
+ private String lineSource;
+ private int lineOffset;
+
+ JsError(String message, String sourceName, int line, String lineSource, int lineOffset) {
+ this.message = message;
+ this.sourceName = sourceName;
+ this.line = line;
+ this.lineSource = lineSource;
+ this.lineOffset = lineOffset;
+ }
+
+ public String toString() {
+ String locationLine = sourceName + ":" + line + ": " + message;
+ String sourceLine = this.lineSource;
+ String errCaret = null;
+ if (lineSource != null) {
+ errCaret = "";
+ for (int i=0; i<lineSource.length(); i++) {
+ char c = lineSource.charAt(i);
+ if (i < lineOffset-1) {
+ if (c == '\t') {
+ errCaret += "\t";
+ } else {
+ errCaret += " ";
+ }
+ } else if (i == lineOffset-1) {
+ errCaret += "^";
+ }
+ }
+ }
+ String rv = locationLine;
+ if (sourceLine != null) {
+ rv += "\n" + sourceLine;
+ }
+ if (errCaret != null) {
+ rv += "\n" + errCaret;
+ }
+ return rv;
+ }
+
+ String getMessage() {
+ return message;
+ }
+
+ String getSourceName() {
+ return sourceName;
+ }
+
+ int getLine() {
+ return line;
+ }
+
+ String getLineSource() {
+ return lineSource;
+ }
+
+ int getLineOffset() {
+ return lineOffset;
+ }
+ }
+ }
+
+ private static class ErrorReporterWrapper implements ErrorReporter {
+ private ErrorReporter original;
+ private ArrayList errors = new ArrayList();
+
+ ErrorReporterWrapper(ErrorReporter original) {
+ this.original = original;
+ }
+
+ private void addError(String string, String string0, int i, String string1, int i0) {
+ errors.add( new Status.JsError(string, string0, i, string1, i0) );
+ }
+
+ public void warning(String string, String string0, int i, String string1, int i0) {
+ original.warning(string, string0, i, string1, i0);
+ }
+
+ public EvaluatorException runtimeError(String string, String string0, int i, String string1, int i0) {
+ return original.runtimeError(string, string0, i, string1, i0);
+ }
+
+ public void error(String string, String string0, int i, String string1, int i0) {
+ addError(string, string0, i, string1, i0);
+ }
+ }
+
+ static abstract class Parameters {
+ abstract int getTimeoutMilliseconds();
+ }
+
+ static void run(final ShellContextFactory shellContextFactory, final File jsFile, final Parameters parameters, final Status status) throws Exception {
+ final Global global = new Global();
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintStream p = new PrintStream(out);
+ global.setOut(p);
+ global.setErr(p);
+ final TestState testState = new TestState();
+ if (jsFile.getName().endsWith("-n.js")) {
+ status.setNegative();
+ }
+ Thread t = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ shellContextFactory.call(new ContextAction()
+ {
+ public Object run(Context cx)
+ {
+ System.out.println("Running " + jsFile);
+ status.running(jsFile);
+ testState.errors = new ErrorReporterWrapper(cx.getErrorReporter());
+ cx.setErrorReporter( testState.errors );
+ global.init(cx);
+ try {
+ runFileIfExists(cx, global, new File(jsFile.getParentFile().getParentFile().getParentFile(), "shell.js"));
+ runFileIfExists(cx, global, new File(jsFile.getParentFile().getParentFile(), "shell.js"));
+ runFileIfExists(cx, global, new File(jsFile.getParentFile(), "shell.js"));
+ runFileIfExists(cx, global, jsFile);
+ // Emulate SpiderMonkey enum value from mozilla/js/src/js.c
+ for (int i=0; i<testState.errors.errors.size(); i++) {
+ Status.JsError thisOne = (Status.JsError)testState.errors.errors.get(i);
+ if (thisOne.getMessage().indexOf("java.lang.OutOfMemoryError") != -1) {
+ testState.exitCode = 5;
+ testState.errors.errors.remove(thisOne);
+ }
+ }
+ status.hadErrors( (Status.JsError[])testState.errors.errors.toArray(new Status.JsError[0]) );
+ } catch (ThreadDeath e) {
+ } catch (Throwable t) {
+ status.threw(t);
+ }
+ return null;
+ }
+ });
+ } finally {
+ synchronized(testState)
+ {
+ testState.finished = true;
+ }
+ }
+ }
+ }, jsFile.getPath());
+ t.setDaemon(true);
+ t.start();
+ t.join(parameters.getTimeoutMilliseconds());
+ synchronized(testState)
+ {
+ if(!testState.finished)
+ {
+ t.stop();
+ status.timedOut();
+ }
+ }
+ int expectedExitCode = 0;
+ p.flush();
+ status.outputWas(new String(out.toByteArray()));
+ BufferedReader r = new BufferedReader(new InputStreamReader(
+ new ByteArrayInputStream(out.toByteArray())));
+ String failures = "";
+ for(;;)
+ {
+ String s = r.readLine();
+ if(s == null)
+ {
+ break;
+ }
+ if(s.indexOf("FAILED!") != -1)
+ {
+ failures += s + '\n';
+ }
+ int expex = s.indexOf("EXPECT EXIT CODE ");
+ if(expex != -1)
+ {
+ expectedExitCode = s.charAt(expex + "EXPECT EXIT CODE ".length()) - '0';
+ }
+ }
+ status.exitCodesWere(expectedExitCode, testState.exitCode);
+ if(failures != "")
+ {
+ status.failed(failures);
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/StandardTests.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/StandardTests.java
new file mode 100644
index 0000000..9c05df6
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/StandardTests.java
@@ -0,0 +1,212 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Attila Szegedi
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.drivers;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Properties;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.mozilla.javascript.tools.shell.ShellContextFactory;
+
+/**
+ * Executes the tests in the js/tests directory, much like jsDriver.pl does.
+ * Excludes tests found in the js/tests/rhino-n.tests file.
+ * @author Attila Szegedi
+ * @version $Id: StandardTests.java,v 1.6.2.2 2008/02/11 16:57:16 nboyd%atg.com Exp $
+ */
+public class StandardTests extends TestSuite
+{
+ public static TestSuite suite() throws Exception
+ {
+ TestSuite suite = new TestSuite("Standard JavaScript tests");
+
+ File testDir = null;
+ if (System.getProperty("mozilla.js.tests") != null) {
+ testDir = new File(System.getProperty("mozilla.js.tests"));
+ } else {
+ URL url = StandardTests.class.getResource(".");
+ String path = url.getFile();
+ int jsIndex = path.lastIndexOf("/js");
+ if(jsIndex == -1)
+ {
+ throw new IllegalStateException("You aren't running the tests from within the standard mozilla/js directory structure");
+ }
+ path = path.substring(0, jsIndex + 3).replace('/', File.separatorChar);
+ testDir = new File(path, "tests");
+ }
+ if(!testDir.isDirectory())
+ {
+ throw new FileNotFoundException(testDir + " is not a directory");
+ }
+ Properties excludes = new Properties();
+ loadExcludes(excludes, "/base.skip");
+ Properties opt1Excludes = new Properties();
+ loadExcludes(opt1Excludes, "/opt1.skip");
+ opt1Excludes.putAll(excludes);
+ for(int i = -1; i < 2; ++i)
+ {
+ TestSuite optimizationLevelSuite = new TestSuite("Optimization level " + i);
+ addSuites(optimizationLevelSuite, testDir, i == -1 ? excludes : opt1Excludes, i);
+ suite.addTest(optimizationLevelSuite);
+ }
+ return suite;
+ }
+
+ private static void loadExcludes(Properties excludes, String excludeFileName) throws IOException
+ {
+ InputStream in = StandardTests.class.getResourceAsStream(excludeFileName);
+ try
+ {
+ excludes.load(in);
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+
+ private static void addSuites(TestSuite topLevel, File testDir, Properties excludes, int optimizationLevel)
+ {
+ File[] subdirs = testDir.listFiles(ShellTest.DIRECTORY_FILTER);
+ Arrays.sort(subdirs);
+ for (int i = 0; i < subdirs.length; i++)
+ {
+ File subdir = subdirs[i];
+ String name = subdir.getName();
+ TestSuite testSuite = new TestSuite(name);
+ addCategories(testSuite, subdir, name + "/", excludes, optimizationLevel);
+ topLevel.addTest(testSuite);
+ }
+ }
+
+ private static void addCategories(TestSuite suite, File suiteDir, String prefix, Properties excludes, int optimizationLevel)
+ {
+ File[] subdirs = suiteDir.listFiles(ShellTest.DIRECTORY_FILTER);
+ Arrays.sort(subdirs);
+ for (int i = 0; i < subdirs.length; i++)
+ {
+ File subdir = subdirs[i];
+ String name = subdir.getName();
+ TestSuite testCategory = new TestSuite(name);
+ addTests(testCategory, subdir, prefix + name + "/", excludes, optimizationLevel);
+ suite.addTest(testCategory);
+ }
+ }
+
+ private static void addTests(TestSuite suite, File suiteDir, String prefix, Properties excludes, int optimizationLevel)
+ {
+ File[] jsFiles = suiteDir.listFiles(ShellTest.TEST_FILTER);
+ Arrays.sort(jsFiles);
+ for (int i = 0; i < jsFiles.length; i++)
+ {
+ File jsFile = jsFiles[i];
+ String name = jsFile.getName();
+ if(!excludes.containsKey(prefix + name))
+ {
+ suite.addTest(new JsTestCase(jsFile, optimizationLevel));
+ }
+ }
+ }
+
+ private static class JunitStatus extends ShellTest.Status {
+ final void running(File jsFile) {
+ // do nothing
+ }
+
+ final void failed(String s) {
+ Assert.fail(s);
+ }
+
+ final void exitCodesWere(int expected, int actual) {
+ Assert.assertEquals("Unexpected exit code", expected, actual);
+ }
+
+ final void outputWas(String s) {
+ System.out.print(s);
+ }
+
+ final void threw(Throwable t) {
+ Assert.fail(ShellTest.getStackTrace(t));
+ }
+
+ final void timedOut() {
+ failed("Timed out.");
+ }
+ }
+
+ private static final class JsTestCase extends TestCase
+ {
+ private final File jsFile;
+ private final int optimizationLevel;
+
+ JsTestCase(File jsFile, int optimizationLevel)
+ {
+ super(jsFile.getName() + (optimizationLevel == 1 ? "-compiled" : "-interpreted"));
+ this.jsFile = jsFile;
+ this.optimizationLevel = optimizationLevel;
+ }
+
+ public int countTestCases()
+ {
+ return 1;
+ }
+
+ private static class ShellTestParameters extends ShellTest.Parameters {
+ int getTimeoutMilliseconds() {
+ if (System.getProperty("mozilla.js.tests.timeout") != null) {
+ return Integer.parseInt(System.getProperty("mozilla.js.tests.timeout"));
+ }
+ return 60000;
+ }
+ }
+
+ public void runBare() throws Exception
+ {
+ final ShellContextFactory shellContextFactory = new ShellContextFactory();
+ shellContextFactory.setOptimizationLevel(optimizationLevel);
+ ShellTest.run(shellContextFactory, jsFile, new ShellTestParameters(), new JunitStatus());
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/results.html b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/results.html
new file mode 100644
index 0000000..36bd729
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/results.html
@@ -0,0 +1,105 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Rhino: Test Results</title>
+</head>
+<body>
+ <a name="top"><span /></a>
+ <h1>Results of JavaScript Test Library for Rhino</h1>
+ <div id="summary">
+ <h2>Summary</h2>
+ <p>
+ <table>
+ <tr>
+ <td>
+ Test List
+ </td>
+ <td>
+ <span id="results.testlist">
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Skip List
+ </td>
+ <td>
+ <span id="results.skiplist">
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Results
+ </td>
+ <td>
+ <span id="results.results">
+ </span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Platform, JRE
+ </td>
+ <td>
+ <!--
+ Should include os.name, java.home, java.version, java.class.path
+ -->
+ <span id="results.platform"></span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Classpath
+ </td>
+ <td>
+ <span id="results.classpath"></span>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Time
+ </td>
+ <td>
+ Execution took <span id="results.elapsed"></span>, ending at <span id="results.time"></span>
+ </td>
+ </tr>
+ </table>
+ </p>
+ <p>
+ <a href="#failureDetails">Failure Details</a>
+ <a href="#retestList">Retest List</a>
+ </p>
+ </div>
+ <div id="failureDetails">
+ <a name="failureDetails"><span /></a>
+ <h2>Failure Details</h2>
+ <div id="failureDetails.prototype">
+ <h3>
+ Testcase <a id="failureDetails.lxr" href=""><span id="failureDetails.lxr.text">path</span></a> failed
+ <a id="failureDetails.bug.href" href="">Bug Number <span id="failureDetails.bug.number">XXX</span></a>
+ </h3>
+ <div>
+ <pre id="failureDetails.status">
+ </pre>
+ <pre id="failureDetails.reason">
+ </pre>
+ <pre id="failureDetails.output">
+ </pre>
+ </div>
+ <div>
+ <a href="#top">Top of Page</a>
+ </div>
+ </div>
+ </div>
+ <div>
+ <a href="#failureDetails">Top of Failures</a>
+ </div>
+ <div>
+ <a name="retestList"><span /></a>
+ <h2>Retest List</h2>
+ <pre id="retestList.text"></pre>
+ <a href="#top">Top of Page</a>
+ <a href="#retestList">Top of Retest List</a>
+ </div>
+</body>
+</html>
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/Bug409702Test.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/Bug409702Test.java
new file mode 100644
index 0000000..e9793cb
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/Bug409702Test.java
@@ -0,0 +1,49 @@
+/**
+ *
+ */
+package org.mozilla.javascript.tests;
+
+import junit.framework.TestCase;
+
+import org.mozilla.javascript.*;
+
+/**
+ * See https://bugzilla.mozilla.org/show_bug.cgi?id=409702
+ * @author Norris Boyd
+ */
+public class Bug409702Test extends TestCase {
+
+ public static abstract class Test {
+ public Test() {
+ }
+
+ public abstract void a();
+
+ public abstract int b();
+
+ public static abstract class Subclass extends Test {
+
+ @Override
+ public final void a() {
+ }
+ }
+ }
+
+ public void testAdapter() {
+ final int value = 12;
+ String source =
+ "var instance = " +
+ " new JavaAdapter(" + getClass().getName() + ".Test.Subclass," +
+ "{ b: function () { return " + value + "; } });" +
+ "instance.b();";
+
+ Context cx = ContextFactory.getGlobal().enterContext();
+ try {
+ Scriptable scope = cx.initStandardObjects();
+ Object result = cx.evaluateString(scope, source, "source", 1, null);
+ assertEquals(new Integer(value), result);
+ } finally {
+ Context.exit();
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/JavaAcessibilityTest.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/JavaAcessibilityTest.java
new file mode 100644
index 0000000..b6cf3ca
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/JavaAcessibilityTest.java
@@ -0,0 +1,99 @@
+/**
+ *
+ */
+package org.mozilla.javascript.tests;
+
+import junit.framework.TestCase;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ContextAction;
+import org.mozilla.javascript.ContextFactory;
+import org.mozilla.javascript.NativeJavaObject;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.tools.shell.Global;
+import org.mozilla.javascript.tools.shell.ShellContextFactory;
+
+/**
+ * @author donnamalayeri
+ */
+public class JavaAcessibilityTest extends TestCase {
+
+ protected final Global global = new Global();
+ String importClass = "importClass(Packages.org.mozilla.javascript.tests.PrivateAccessClass)\n";
+
+ public JavaAcessibilityTest() {
+ global.init(contextFactory);
+ }
+
+ private ContextFactory contextFactory = new ShellContextFactory() {
+ protected boolean hasFeature(Context cx, int featureIndex) {
+ if (featureIndex == Context.FEATURE_ENHANCED_JAVA_ACCESS)
+ return true;
+ return super.hasFeature(cx, featureIndex);
+ }
+ };
+
+ public void testAccessingFields() {
+ Object result = runScript(importClass + "PrivateAccessClass.staticPackagePrivateInt");
+ assertEquals(new Integer(0), result);
+
+ result = runScript(importClass + "PrivateAccessClass.staticPrivateInt");
+ assertEquals(new Integer(1), result);
+
+ result = runScript(importClass + "PrivateAccessClass.staticProtectedInt");
+ assertEquals(new Integer(2), result);
+
+ result = runScript(importClass + "new PrivateAccessClass().packagePrivateString");
+ assertEquals("package private", ((NativeJavaObject) result).unwrap());
+
+ result = runScript(importClass + "new PrivateAccessClass().privateString");
+ assertEquals("private", ((NativeJavaObject) result).unwrap());
+
+ result = runScript(importClass + "new PrivateAccessClass().protectedString");
+ assertEquals("protected", ((NativeJavaObject) result).unwrap());
+
+ result = runScript(importClass + "new PrivateAccessClass.PrivateNestedClass().packagePrivateInt");
+ assertEquals(new Integer(0), result);
+
+ result = runScript(importClass + "new PrivateAccessClass.PrivateNestedClass().privateInt");
+ assertEquals(new Integer(1), result);
+
+ result = runScript(importClass + "new PrivateAccessClass.PrivateNestedClass().protectedInt");
+ assertEquals(new Integer(2), result);
+ }
+
+ public void testAccessingMethods() {
+ Object result = runScript(importClass + "PrivateAccessClass.staticPackagePrivateMethod()");
+ assertEquals(new Integer(0), result);
+
+ result = runScript(importClass + "PrivateAccessClass.staticPrivateMethod()");
+ assertEquals(new Integer(1), result);
+
+ result = runScript(importClass + "PrivateAccessClass.staticProtectedMethod()");
+ assertEquals(new Integer(2), result);
+
+ result = runScript(importClass + "new PrivateAccessClass().packagePrivateMethod()");
+ assertEquals(new Integer(3), result);
+
+ result = runScript(importClass + "new PrivateAccessClass().privateMethod()");
+ assertEquals(new Integer(4), result);
+
+ result = runScript(importClass + "new PrivateAccessClass().protectedMethod()");
+ assertEquals(new Integer(5), result);
+ }
+
+ public void testAccessingConstructors() {
+ runScript(importClass + "new PrivateAccessClass(\"foo\")");
+ runScript(importClass + "new PrivateAccessClass(5)");
+ runScript(importClass + "new PrivateAccessClass(5, \"foo\")");
+ }
+
+ private Object runScript(final String scriptSourceText) {
+ return this.contextFactory.call(new ContextAction() {
+ public Object run(Context context) {
+ Script script = context.compileString(scriptSourceText, "", 1, null);
+ return script.exec(context, global);
+ }
+ });
+ }
+}
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/PrivateAccessClass.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/PrivateAccessClass.java
new file mode 100644
index 0000000..08f95a3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/tests/PrivateAccessClass.java
@@ -0,0 +1,89 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Attila Szegedi
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tests;
+
+/**
+ * A class with private/protected/package private members, to test the Rhino
+ * feature Context.FEATURE_ENHANCED_JAVA_ACCESS, that allows bypassing Java
+ * member access restrictions.
+ * @author Donna Malayeri
+ */
+
+public class PrivateAccessClass
+{
+ private PrivateAccessClass() { }
+ PrivateAccessClass(String s) { }
+ private PrivateAccessClass(int x) { }
+ protected PrivateAccessClass(int x, String s) { }
+
+ private static class PrivateNestedClass
+ {
+ private PrivateNestedClass() { }
+
+ int packagePrivateInt = 0;
+ private int privateInt = 1;
+ protected int protectedInt = 2;
+ }
+
+ static int staticPackagePrivateInt = 0;
+ private static int staticPrivateInt = 1;
+ protected static int staticProtectedInt = 2;
+
+ String packagePrivateString = "package private";
+ private String privateString = "private";
+ protected String protectedString = "protected";
+
+ static int staticPackagePrivateMethod() { return 0; }
+ static private int staticPrivateMethod() { return 1; }
+ static protected int staticProtectedMethod() { return 2; }
+
+ int packagePrivateMethod() { return 3; }
+ private int privateMethod() { return 4; }
+ protected int protectedMethod() { return 5; }
+
+ /*
+ * Suppress warnings about unused private members.
+ */
+ public int referenceToPrivateMembers() {
+ PrivateAccessClass pac = new PrivateAccessClass();
+ PrivateAccessClass pac2 = new PrivateAccessClass(2);
+ PrivateNestedClass pnc = new PrivateNestedClass();
+ System.out.println(privateString);
+ return pnc.privateInt + staticPrivateInt + staticPrivateMethod() +
+ pac.privateMethod();
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/build.xml b/infrastructure/rhino1_7R1/toolsrc/build.xml
new file mode 100644
index 0000000..be9a9b7
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/build.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<!--
+Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
+Requires Ant version 1.2
+-->
+<project name="toolsrc" default="compile" basedir="..">
+
+ <target name="properties">
+ <property file="build.properties"/>
+ <property name="debugger"
+ value="org/mozilla/javascript/tools/debugger"/>
+ </target>
+
+ <target name="compile" depends="properties">
+ <javac srcdir="toolsrc"
+ destdir="${classes}"
+ includes="org/**/*.java"
+ excludes="org/**/debugger/*.java"
+ deprecation="on"
+ debug="${debug}"
+ target="${target-jvm}"
+ source="${source-level}"
+ >
+ </javac>
+ <copy todir="${classes}">
+ <fileset dir="toolsrc" includes="org/**/*.properties" />
+ </copy>
+ </target>
+
+ <target name="copy-source" depends="properties">
+ <mkdir dir="${dist.dir}/toolsrc"/>
+ <copy todir="${dist.dir}/toolsrc">
+ <fileset dir="toolsrc"
+ includes="**/*.java,**/*.properties,**/*.xml"
+ excludes="${debugger}/downloaded/**" />
+ </copy>
+ </target>
+
+ <target name="download-debugger" depends="properties">
+ <ant dir="toolsrc/${debugger}" target="download"/>
+ </target>
+
+ <target name="compile-debugger" depends="download-debugger">
+ <mkdir dir="classes"/>
+ <javac srcdir="toolsrc"
+ destdir="classes"
+ includes="org/**/debugger/*.java,org/**/debugger/downloaded/*.java"
+ classpath="js.jar"
+ deprecation="on"
+ target="${target-jvm}"
+ source="${source-level}"/>
+ <copy todir="classes">
+ <fileset dir="toolsrc" includes="org/**/*.properties" />
+ </copy>
+ <jar jarfile="js.jar"
+ basedir="classes"
+ update="yes"
+ />
+ </target>
+
+ <target name="clean" depends="properties">
+ <delete includeEmptyDirs="true">
+ <fileset dir="${classes}"
+ includes="org/mozilla/javascript/tools/**"/>
+ </delete>
+ </target>
+
+</project>
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/ToolErrorReporter.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/ToolErrorReporter.java
new file mode 100644
index 0000000..938f5f2
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/ToolErrorReporter.java
@@ -0,0 +1,225 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Kurt Westerfeld
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools;
+
+import org.mozilla.javascript.*;
+
+import java.text.MessageFormat;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Error reporter for tools.
+ *
+ * Currently used by both the shell and the compiler.
+ */
+public class ToolErrorReporter implements ErrorReporter {
+
+ public ToolErrorReporter(boolean reportWarnings) {
+ this(reportWarnings, System.err);
+ }
+
+ public ToolErrorReporter(boolean reportWarnings, PrintStream err) {
+ this.reportWarnings = reportWarnings;
+ this.err = err;
+ }
+
+ /**
+ * Look up the message corresponding to messageId in the
+ * org.mozilla.javascript.tools.shell.resources.Messages property file.
+ * For internationalization support.
+ */
+ public static String getMessage(String messageId) {
+ return getMessage(messageId, (Object []) null);
+ }
+
+ public static String getMessage(String messageId, String argument) {
+ Object[] args = { argument };
+ return getMessage(messageId, args);
+ }
+
+ public static String getMessage(String messageId, Object arg1, Object arg2)
+ {
+ Object[] args = { arg1, arg2 };
+ return getMessage(messageId, args);
+ }
+
+ public static String getMessage(String messageId, Object[] args) {
+ Context cx = Context.getCurrentContext();
+ Locale locale = cx == null ? Locale.getDefault() : cx.getLocale();
+
+ // ResourceBundle does cacheing.
+ ResourceBundle rb = ResourceBundle.getBundle
+ ("org.mozilla.javascript.tools.resources.Messages", locale);
+
+ String formatString;
+ try {
+ formatString = rb.getString(messageId);
+ } catch (java.util.MissingResourceException mre) {
+ throw new RuntimeException("no message resource found for message property "
+ + messageId);
+ }
+
+ if (args == null) {
+ return formatString;
+ } else {
+ MessageFormat formatter = new MessageFormat(formatString);
+ return formatter.format(args);
+ }
+ }
+
+ private static String getExceptionMessage(RhinoException ex)
+ {
+ String msg;
+ if (ex instanceof JavaScriptException) {
+ msg = getMessage("msg.uncaughtJSException", ex.details());
+ } else if (ex instanceof EcmaError) {
+ msg = getMessage("msg.uncaughtEcmaError", ex.details());
+ } else if (ex instanceof EvaluatorException) {
+ msg = ex.details();
+ } else {
+ msg = ex.toString();
+ }
+ return msg;
+ }
+
+ public void warning(String message, String sourceName, int line,
+ String lineSource, int lineOffset)
+ {
+ if (!reportWarnings)
+ return;
+ reportErrorMessage(message, sourceName, line, lineSource, lineOffset,
+ true);
+ }
+
+ public void error(String message, String sourceName, int line,
+ String lineSource, int lineOffset)
+ {
+ hasReportedErrorFlag = true;
+ reportErrorMessage(message, sourceName, line, lineSource, lineOffset,
+ false);
+ }
+
+ public EvaluatorException runtimeError(String message, String sourceName,
+ int line, String lineSource,
+ int lineOffset)
+ {
+ return new EvaluatorException(message, sourceName, line,
+ lineSource, lineOffset);
+ }
+
+ public boolean hasReportedError() {
+ return hasReportedErrorFlag;
+ }
+
+ public boolean isReportingWarnings() {
+ return this.reportWarnings;
+ }
+
+ public void setIsReportingWarnings(boolean reportWarnings) {
+ this.reportWarnings = reportWarnings;
+ }
+
+ public static void reportException(ErrorReporter er, RhinoException ex)
+ {
+ if (er instanceof ToolErrorReporter) {
+ ((ToolErrorReporter)er).reportException(ex);
+ } else {
+ String msg = getExceptionMessage(ex);
+ er.error(msg, ex.sourceName(), ex.lineNumber(),
+ ex.lineSource(), ex.columnNumber());
+ }
+ }
+
+ public void reportException(RhinoException ex)
+ {
+ if (ex instanceof WrappedException) {
+ WrappedException we = (WrappedException)ex;
+ we.printStackTrace(err);
+ } else {
+ String lineSeparator =
+ SecurityUtilities.getSystemProperty("line.separator");
+ String msg = getExceptionMessage(ex) + lineSeparator +
+ ex.getScriptStackTrace();
+ reportErrorMessage(msg, ex.sourceName(), ex.lineNumber(),
+ ex.lineSource(), ex.columnNumber(), false);
+ }
+ }
+
+ private void reportErrorMessage(String message, String sourceName, int line,
+ String lineSource, int lineOffset,
+ boolean justWarning)
+ {
+ if (line > 0) {
+ String lineStr = String.valueOf(line);
+ if (sourceName != null) {
+ Object[] args = { sourceName, lineStr, message };
+ message = getMessage("msg.format3", args);
+ } else {
+ Object[] args = { lineStr, message };
+ message = getMessage("msg.format2", args);
+ }
+ } else {
+ Object[] args = { message };
+ message = getMessage("msg.format1", args);
+ }
+ if (justWarning) {
+ message = getMessage("msg.warning", message);
+ }
+ err.println(messagePrefix + message);
+ if (null != lineSource) {
+ err.println(messagePrefix + lineSource);
+ err.println(messagePrefix + buildIndicator(lineOffset));
+ }
+ }
+
+ private String buildIndicator(int offset){
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < offset-1; i++)
+ sb.append(".");
+ sb.append("^");
+ return sb.toString();
+ }
+
+ private final String messagePrefix = "js: ";
+ private boolean hasReportedErrorFlag;
+ private boolean reportWarnings;
+ private PrintStream err;
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java
new file mode 100644
index 0000000..de8fcde
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java
@@ -0,0 +1,1560 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * SeeBeyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Matt Gould
+ * Christopher Oliver
+ * Cameron McCormack
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.debugger;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.debug.*;
+import java.util.*;
+import java.io.*;
+import java.net.URL;
+
+/**
+ * Dim or Debugger Implementation for Rhino.
+ */
+public class Dim {
+
+ // Constants for instructing the debugger what action to perform
+ // to end interruption. Used by 'returnValue'.
+ public static final int STEP_OVER = 0;
+ public static final int STEP_INTO = 1;
+ public static final int STEP_OUT = 2;
+ public static final int GO = 3;
+ public static final int BREAK = 4;
+ public static final int EXIT = 5;
+
+ // Constants for the DimIProxy interface implementation class.
+ private static final int IPROXY_DEBUG = 0;
+ private static final int IPROXY_LISTEN = 1;
+ private static final int IPROXY_COMPILE_SCRIPT = 2;
+ private static final int IPROXY_EVAL_SCRIPT = 3;
+ private static final int IPROXY_STRING_IS_COMPILABLE = 4;
+ private static final int IPROXY_OBJECT_TO_STRING = 5;
+ private static final int IPROXY_OBJECT_PROPERTY = 6;
+ private static final int IPROXY_OBJECT_IDS = 7;
+
+ /**
+ * Interface to the debugger GUI.
+ */
+ private GuiCallback callback;
+
+ /**
+ * Whether the debugger should break.
+ */
+ private boolean breakFlag;
+
+ /**
+ * The ScopeProvider object that provides the scope in which to
+ * evaluate script.
+ */
+ private ScopeProvider scopeProvider;
+
+ /**
+ * The index of the current stack frame.
+ */
+ private int frameIndex = -1;
+
+ /**
+ * Information about the current stack at the point of interruption.
+ */
+ private volatile ContextData interruptedContextData;
+
+ /**
+ * The ContextFactory to listen to for debugging information.
+ */
+ private ContextFactory contextFactory;
+
+ /**
+ * Synchronization object used to allow script evaluations to
+ * happen when a thread is resumed.
+ */
+ private Object monitor = new Object();
+
+ /**
+ * Synchronization object used to wait for valid
+ * {@link #interruptedContextData}.
+ */
+ private Object eventThreadMonitor = new Object();
+
+ /**
+ * The action to perform to end the interruption loop.
+ */
+ private volatile int returnValue = -1;
+
+ /**
+ * Whether the debugger is inside the interruption loop.
+ */
+ private boolean insideInterruptLoop;
+
+ /**
+ * The requested script string to be evaluated when the thread
+ * has been resumed.
+ */
+ private String evalRequest;
+
+ /**
+ * The stack frame in which to evaluate {@link #evalRequest}.
+ */
+ private StackFrame evalFrame;
+
+ /**
+ * The result of evaluating {@link #evalRequest}.
+ */
+ private String evalResult;
+
+ /**
+ * Whether the debugger should break when a script exception is thrown.
+ */
+ private boolean breakOnExceptions;
+
+ /**
+ * Whether the debugger should break when a script function is entered.
+ */
+ private boolean breakOnEnter;
+
+ /**
+ * Whether the debugger should break when a script function is returned
+ * from.
+ */
+ private boolean breakOnReturn;
+
+ /**
+ * Table mapping URLs to information about the script source.
+ */
+ private final Hashtable urlToSourceInfo = new Hashtable();
+
+ /**
+ * Table mapping function names to information about the function.
+ */
+ private final Hashtable functionNames = new Hashtable();
+
+ /**
+ * Table mapping functions to information about the function.
+ */
+ private final Hashtable functionToSource = new Hashtable();
+
+ /**
+ * ContextFactory.Listener instance attached to {@link #contextFactory}.
+ */
+ private DimIProxy listener;
+
+ /**
+ * Sets the GuiCallback object to use.
+ */
+ public void setGuiCallback(GuiCallback callback) {
+ this.callback = callback;
+ }
+
+ /**
+ * Tells the debugger to break at the next opportunity.
+ */
+ public void setBreak() {
+ this.breakFlag = true;
+ }
+
+ /**
+ * Sets the ScopeProvider to be used.
+ */
+ public void setScopeProvider(ScopeProvider scopeProvider) {
+ this.scopeProvider = scopeProvider;
+ }
+
+ /**
+ * Switches context to the stack frame with the given index.
+ */
+ public void contextSwitch(int frameIndex) {
+ this.frameIndex = frameIndex;
+ }
+
+ /**
+ * Sets whether the debugger should break on exceptions.
+ */
+ public void setBreakOnExceptions(boolean breakOnExceptions) {
+ this.breakOnExceptions = breakOnExceptions;
+ }
+
+ /**
+ * Sets whether the debugger should break on function entering.
+ */
+ public void setBreakOnEnter(boolean breakOnEnter) {
+ this.breakOnEnter = breakOnEnter;
+ }
+
+ /**
+ * Sets whether the debugger should break on function return.
+ */
+ public void setBreakOnReturn(boolean breakOnReturn) {
+ this.breakOnReturn = breakOnReturn;
+ }
+
+ /**
+ * Attaches the debugger to the given ContextFactory.
+ */
+ public void attachTo(ContextFactory factory) {
+ detach();
+ this.contextFactory = factory;
+ this.listener = new DimIProxy(this, IPROXY_LISTEN);
+ factory.addListener(this.listener);
+ }
+
+ /**
+ * Detaches the debugger from the current ContextFactory.
+ */
+ public void detach() {
+ if (listener != null) {
+ contextFactory.removeListener(listener);
+ contextFactory = null;
+ listener = null;
+ }
+ }
+
+ /**
+ * Releases resources associated with this debugger.
+ */
+ public void dispose() {
+ detach();
+ }
+
+ /**
+ * Returns the FunctionSource object for the given script or function.
+ */
+ private FunctionSource getFunctionSource(DebuggableScript fnOrScript) {
+ FunctionSource fsource = functionSource(fnOrScript);
+ if (fsource == null) {
+ String url = getNormalizedUrl(fnOrScript);
+ SourceInfo si = sourceInfo(url);
+ if (si == null) {
+ if (!fnOrScript.isGeneratedScript()) {
+ // Not eval or Function, try to load it from URL
+ String source = loadSource(url);
+ if (source != null) {
+ DebuggableScript top = fnOrScript;
+ for (;;) {
+ DebuggableScript parent = top.getParent();
+ if (parent == null) {
+ break;
+ }
+ top = parent;
+ }
+ registerTopScript(top, source);
+ fsource = functionSource(fnOrScript);
+ }
+ }
+ }
+ }
+ return fsource;
+ }
+
+ /**
+ * Loads the script at the given URL.
+ */
+ private String loadSource(String sourceUrl) {
+ String source = null;
+ int hash = sourceUrl.indexOf('#');
+ if (hash >= 0) {
+ sourceUrl = sourceUrl.substring(0, hash);
+ }
+ try {
+ InputStream is;
+ openStream:
+ {
+ if (sourceUrl.indexOf(':') < 0) {
+ // Can be a file name
+ try {
+ if (sourceUrl.startsWith("~/")) {
+ String home = SecurityUtilities.getSystemProperty("user.home");
+ if (home != null) {
+ String pathFromHome = sourceUrl.substring(2);
+ File f = new File(new File(home), pathFromHome);
+ if (f.exists()) {
+ is = new FileInputStream(f);
+ break openStream;
+ }
+ }
+ }
+ File f = new File(sourceUrl);
+ if (f.exists()) {
+ is = new FileInputStream(f);
+ break openStream;
+ }
+ } catch (SecurityException ex) { }
+ // No existing file, assume missed http://
+ if (sourceUrl.startsWith("//")) {
+ sourceUrl = "http:" + sourceUrl;
+ } else if (sourceUrl.startsWith("/")) {
+ sourceUrl = "http://127.0.0.1" + sourceUrl;
+ } else {
+ sourceUrl = "http://" + sourceUrl;
+ }
+ }
+
+ is = (new URL(sourceUrl)).openStream();
+ }
+
+ try {
+ source = Kit.readReader(new InputStreamReader(is));
+ } finally {
+ is.close();
+ }
+ } catch (IOException ex) {
+ System.err.println
+ ("Failed to load source from "+sourceUrl+": "+ ex);
+ }
+ return source;
+ }
+
+ /**
+ * Registers the given script as a top-level script in the debugger.
+ */
+ private void registerTopScript(DebuggableScript topScript, String source) {
+ if (!topScript.isTopLevel()) {
+ throw new IllegalArgumentException();
+ }
+ String url = getNormalizedUrl(topScript);
+ DebuggableScript[] functions = getAllFunctions(topScript);
+ final SourceInfo sourceInfo = new SourceInfo(source, functions, url);
+
+ synchronized (urlToSourceInfo) {
+ SourceInfo old = (SourceInfo)urlToSourceInfo.get(url);
+ if (old != null) {
+ sourceInfo.copyBreakpointsFrom(old);
+ }
+ urlToSourceInfo.put(url, sourceInfo);
+ for (int i = 0; i != sourceInfo.functionSourcesTop(); ++i) {
+ FunctionSource fsource = sourceInfo.functionSource(i);
+ String name = fsource.name();
+ if (name.length() != 0) {
+ functionNames.put(name, fsource);
+ }
+ }
+ }
+
+ synchronized (functionToSource) {
+ for (int i = 0; i != functions.length; ++i) {
+ FunctionSource fsource = sourceInfo.functionSource(i);
+ functionToSource.put(functions[i], fsource);
+ }
+ }
+
+ callback.updateSourceText(sourceInfo);
+ }
+
+ /**
+ * Returns the FunctionSource object for the given function or script.
+ */
+ private FunctionSource functionSource(DebuggableScript fnOrScript) {
+ return (FunctionSource)functionToSource.get(fnOrScript);
+ }
+
+ /**
+ * Returns an array of all function names.
+ */
+ public String[] functionNames() {
+ String[] a;
+ synchronized (urlToSourceInfo) {
+ Enumeration e = functionNames.keys();
+ a = new String[functionNames.size()];
+ int i = 0;
+ while (e.hasMoreElements()) {
+ a[i++] = (String)e.nextElement();
+ }
+ }
+ return a;
+ }
+
+ /**
+ * Returns the FunctionSource object for the function with the given name.
+ */
+ public FunctionSource functionSourceByName(String functionName) {
+ return (FunctionSource)functionNames.get(functionName);
+ }
+
+ /**
+ * Returns the SourceInfo object for the given URL.
+ */
+ public SourceInfo sourceInfo(String url) {
+ return (SourceInfo)urlToSourceInfo.get(url);
+ }
+
+ /**
+ * Returns the source URL for the given script or function.
+ */
+ private String getNormalizedUrl(DebuggableScript fnOrScript) {
+ String url = fnOrScript.getSourceName();
+ if (url == null) { url = "<stdin>"; }
+ else {
+ // Not to produce window for eval from different lines,
+ // strip line numbers, i.e. replace all #[0-9]+\(eval\) by
+ // (eval)
+ // Option: similar teatment for Function?
+ char evalSeparator = '#';
+ StringBuffer sb = null;
+ int urlLength = url.length();
+ int cursor = 0;
+ for (;;) {
+ int searchStart = url.indexOf(evalSeparator, cursor);
+ if (searchStart < 0) {
+ break;
+ }
+ String replace = null;
+ int i = searchStart + 1;
+ while (i != urlLength) {
+ int c = url.charAt(i);
+ if (!('0' <= c && c <= '9')) {
+ break;
+ }
+ ++i;
+ }
+ if (i != searchStart + 1) {
+ // i points after #[0-9]+
+ if ("(eval)".regionMatches(0, url, i, 6)) {
+ cursor = i + 6;
+ replace = "(eval)";
+ }
+ }
+ if (replace == null) {
+ break;
+ }
+ if (sb == null) {
+ sb = new StringBuffer();
+ sb.append(url.substring(0, searchStart));
+ }
+ sb.append(replace);
+ }
+ if (sb != null) {
+ if (cursor != urlLength) {
+ sb.append(url.substring(cursor));
+ }
+ url = sb.toString();
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Returns an array of all functions in the given script.
+ */
+ private static DebuggableScript[] getAllFunctions
+ (DebuggableScript function) {
+ ObjArray functions = new ObjArray();
+ collectFunctions_r(function, functions);
+ DebuggableScript[] result = new DebuggableScript[functions.size()];
+ functions.toArray(result);
+ return result;
+ }
+
+ /**
+ * Helper function for {@link #getAllFunctions(DebuggableScript)}.
+ */
+ private static void collectFunctions_r(DebuggableScript function,
+ ObjArray array) {
+ array.add(function);
+ for (int i = 0; i != function.getFunctionCount(); ++i) {
+ collectFunctions_r(function.getFunction(i), array);
+ }
+ }
+
+ /**
+ * Clears all breakpoints.
+ */
+ public void clearAllBreakpoints() {
+ Enumeration e = urlToSourceInfo.elements();
+ while (e.hasMoreElements()) {
+ SourceInfo si = (SourceInfo)e.nextElement();
+ si.removeAllBreakpoints();
+ }
+ }
+
+ /**
+ * Called when a breakpoint has been hit.
+ */
+ private void handleBreakpointHit(StackFrame frame, Context cx) {
+ breakFlag = false;
+ interrupted(cx, frame, null);
+ }
+
+ /**
+ * Called when a script exception has been thrown.
+ */
+ private void handleExceptionThrown(Context cx, Throwable ex,
+ StackFrame frame) {
+ if (breakOnExceptions) {
+ ContextData cd = frame.contextData();
+ if (cd.lastProcessedException != ex) {
+ interrupted(cx, frame, ex);
+ cd.lastProcessedException = ex;
+ }
+ }
+ }
+
+ /**
+ * Returns the current ContextData object.
+ */
+ public ContextData currentContextData() {
+ return interruptedContextData;
+ }
+
+ /**
+ * Sets the action to perform to end interruption.
+ */
+ public void setReturnValue(int returnValue) {
+ synchronized (monitor) {
+ this.returnValue = returnValue;
+ monitor.notify();
+ }
+ }
+
+ /**
+ * Resumes execution of script.
+ */
+ public void go() {
+ synchronized (monitor) {
+ this.returnValue = GO;
+ monitor.notifyAll();
+ }
+ }
+
+ /**
+ * Evaluates the given script.
+ */
+ public String eval(String expr) {
+ String result = "undefined";
+ if (expr == null) {
+ return result;
+ }
+ ContextData contextData = currentContextData();
+ if (contextData == null || frameIndex >= contextData.frameCount()) {
+ return result;
+ }
+ StackFrame frame = contextData.getFrame(frameIndex);
+ if (contextData.eventThreadFlag) {
+ Context cx = Context.getCurrentContext();
+ result = do_eval(cx, frame, expr);
+ } else {
+ synchronized (monitor) {
+ if (insideInterruptLoop) {
+ evalRequest = expr;
+ evalFrame = frame;
+ monitor.notify();
+ do {
+ try {
+ monitor.wait();
+ } catch (InterruptedException exc) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ } while (evalRequest != null);
+ result = evalResult;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Compiles the given script.
+ */
+ public void compileScript(String url, String text) {
+ DimIProxy action = new DimIProxy(this, IPROXY_COMPILE_SCRIPT);
+ action.url = url;
+ action.text = text;
+ action.withContext();
+ }
+
+ /**
+ * Evaluates the given script.
+ */
+ public void evalScript(final String url, final String text) {
+ DimIProxy action = new DimIProxy(this, IPROXY_EVAL_SCRIPT);
+ action.url = url;
+ action.text = text;
+ action.withContext();
+ }
+
+ /**
+ * Converts the given script object to a string.
+ */
+ public String objectToString(Object object) {
+ DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_TO_STRING);
+ action.object = object;
+ action.withContext();
+ return action.stringResult;
+ }
+
+ /**
+ * Returns whether the given string is syntactically valid script.
+ */
+ public boolean stringIsCompilableUnit(String str) {
+ DimIProxy action = new DimIProxy(this, IPROXY_STRING_IS_COMPILABLE);
+ action.text = str;
+ action.withContext();
+ return action.booleanResult;
+ }
+
+ /**
+ * Returns the value of a property on the given script object.
+ */
+ public Object getObjectProperty(Object object, Object id) {
+ DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_PROPERTY);
+ action.object = object;
+ action.id = id;
+ action.withContext();
+ return action.objectResult;
+ }
+
+ /**
+ * Returns an array of the property names on the given script object.
+ */
+ public Object[] getObjectIds(Object object) {
+ DimIProxy action = new DimIProxy(this, IPROXY_OBJECT_IDS);
+ action.object = object;
+ action.withContext();
+ return action.objectArrayResult;
+ }
+
+ /**
+ * Returns the value of a property on the given script object.
+ */
+ private Object getObjectPropertyImpl(Context cx, Object object,
+ Object id) {
+ Scriptable scriptable = (Scriptable)object;
+ Object result;
+ if (id instanceof String) {
+ String name = (String)id;
+ if (name.equals("this")) {
+ result = scriptable;
+ } else if (name.equals("__proto__")) {
+ result = scriptable.getPrototype();
+ } else if (name.equals("__parent__")) {
+ result = scriptable.getParentScope();
+ } else {
+ result = ScriptableObject.getProperty(scriptable, name);
+ if (result == ScriptableObject.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+ }
+ } else {
+ int index = ((Integer)id).intValue();
+ result = ScriptableObject.getProperty(scriptable, index);
+ if (result == ScriptableObject.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns an array of the property names on the given script object.
+ */
+ private Object[] getObjectIdsImpl(Context cx, Object object) {
+ if (!(object instanceof Scriptable) || object == Undefined.instance) {
+ return Context.emptyArgs;
+ }
+
+ Object[] ids;
+ Scriptable scriptable = (Scriptable)object;
+ if (scriptable instanceof DebuggableObject) {
+ ids = ((DebuggableObject)scriptable).getAllIds();
+ } else {
+ ids = scriptable.getIds();
+ }
+
+ Scriptable proto = scriptable.getPrototype();
+ Scriptable parent = scriptable.getParentScope();
+ int extra = 0;
+ if (proto != null) {
+ ++extra;
+ }
+ if (parent != null) {
+ ++extra;
+ }
+ if (extra != 0) {
+ Object[] tmp = new Object[extra + ids.length];
+ System.arraycopy(ids, 0, tmp, extra, ids.length);
+ ids = tmp;
+ extra = 0;
+ if (proto != null) {
+ ids[extra++] = "__proto__";
+ }
+ if (parent != null) {
+ ids[extra++] = "__parent__";
+ }
+ }
+
+ return ids;
+ }
+
+ /**
+ * Interrupts script execution.
+ */
+ private void interrupted(Context cx, final StackFrame frame,
+ Throwable scriptException) {
+ ContextData contextData = frame.contextData();
+ boolean eventThreadFlag = callback.isGuiEventThread();
+ contextData.eventThreadFlag = eventThreadFlag;
+
+ boolean recursiveEventThreadCall = false;
+
+interruptedCheck:
+ synchronized (eventThreadMonitor) {
+ if (eventThreadFlag) {
+ if (interruptedContextData != null) {
+ recursiveEventThreadCall = true;
+ break interruptedCheck;
+ }
+ } else {
+ while (interruptedContextData != null) {
+ try {
+ eventThreadMonitor.wait();
+ } catch (InterruptedException exc) {
+ return;
+ }
+ }
+ }
+ interruptedContextData = contextData;
+ }
+
+ if (recursiveEventThreadCall) {
+ // XXX: For now the following is commented out as on Linux
+ // too deep recursion of dispatchNextGuiEvent causes GUI lockout.
+ // Note: it can make GUI unresponsive if long-running script
+ // will be called on GUI thread while processing another interrupt
+ if (false) {
+ // Run event dispatch until gui sets a flag to exit the initial
+ // call to interrupted.
+ while (this.returnValue == -1) {
+ try {
+ callback.dispatchNextGuiEvent();
+ } catch (InterruptedException exc) {
+ }
+ }
+ }
+ return;
+ }
+
+ if (interruptedContextData == null) Kit.codeBug();
+
+ try {
+ do {
+ int frameCount = contextData.frameCount();
+ this.frameIndex = frameCount -1;
+
+ final String threadTitle = Thread.currentThread().toString();
+ final String alertMessage;
+ if (scriptException == null) {
+ alertMessage = null;
+ } else {
+ alertMessage = scriptException.toString();
+ }
+
+ int returnValue = -1;
+ if (!eventThreadFlag) {
+ synchronized (monitor) {
+ if (insideInterruptLoop) Kit.codeBug();
+ this.insideInterruptLoop = true;
+ this.evalRequest = null;
+ this.returnValue = -1;
+ callback.enterInterrupt(frame, threadTitle,
+ alertMessage);
+ try {
+ for (;;) {
+ try {
+ monitor.wait();
+ } catch (InterruptedException exc) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ if (evalRequest != null) {
+ this.evalResult = null;
+ try {
+ evalResult = do_eval(cx, evalFrame,
+ evalRequest);
+ } finally {
+ evalRequest = null;
+ evalFrame = null;
+ monitor.notify();
+ }
+ continue;
+ }
+ if (this.returnValue != -1) {
+ returnValue = this.returnValue;
+ break;
+ }
+ }
+ } finally {
+ insideInterruptLoop = false;
+ }
+ }
+ } else {
+ this.returnValue = -1;
+ callback.enterInterrupt(frame, threadTitle, alertMessage);
+ while (this.returnValue == -1) {
+ try {
+ callback.dispatchNextGuiEvent();
+ } catch (InterruptedException exc) {
+ }
+ }
+ returnValue = this.returnValue;
+ }
+ switch (returnValue) {
+ case STEP_OVER:
+ contextData.breakNextLine = true;
+ contextData.stopAtFrameDepth = contextData.frameCount();
+ break;
+ case STEP_INTO:
+ contextData.breakNextLine = true;
+ contextData.stopAtFrameDepth = -1;
+ break;
+ case STEP_OUT:
+ if (contextData.frameCount() > 1) {
+ contextData.breakNextLine = true;
+ contextData.stopAtFrameDepth
+ = contextData.frameCount() -1;
+ }
+ break;
+ }
+ } while (false);
+ } finally {
+ synchronized (eventThreadMonitor) {
+ interruptedContextData = null;
+ eventThreadMonitor.notifyAll();
+ }
+ }
+
+ }
+
+ /**
+ * Evaluates script in the given stack frame.
+ */
+ private static String do_eval(Context cx, StackFrame frame, String expr) {
+ String resultString;
+ Debugger saved_debugger = cx.getDebugger();
+ Object saved_data = cx.getDebuggerContextData();
+ int saved_level = cx.getOptimizationLevel();
+
+ cx.setDebugger(null, null);
+ cx.setOptimizationLevel(-1);
+ cx.setGeneratingDebug(false);
+ try {
+ Callable script = (Callable)cx.compileString(expr, "", 0, null);
+ Object result = script.call(cx, frame.scope, frame.thisObj,
+ ScriptRuntime.emptyArgs);
+ if (result == Undefined.instance) {
+ resultString = "";
+ } else {
+ resultString = ScriptRuntime.toString(result);
+ }
+ } catch (Exception exc) {
+ resultString = exc.getMessage();
+ } finally {
+ cx.setGeneratingDebug(true);
+ cx.setOptimizationLevel(saved_level);
+ cx.setDebugger(saved_debugger, saved_data);
+ }
+ if (resultString == null) {
+ resultString = "null";
+ }
+ return resultString;
+ }
+
+ /**
+ * Proxy class to implement debug interfaces without bloat of class
+ * files.
+ */
+ private static class DimIProxy
+ implements ContextAction, ContextFactory.Listener, Debugger {
+
+ /**
+ * The debugger.
+ */
+ private Dim dim;
+
+ /**
+ * The interface implementation type. One of the IPROXY_* constants
+ * defined in {@link Dim}.
+ */
+ private int type;
+
+ /**
+ * The URL origin of the script to compile or evaluate.
+ */
+ private String url;
+
+ /**
+ * The text of the script to compile, evaluate or test for compilation.
+ */
+ private String text;
+
+ /**
+ * The object to convert, get a property from or enumerate.
+ */
+ private Object object;
+
+ /**
+ * The property to look up in {@link #object}.
+ */
+ private Object id;
+
+ /**
+ * The boolean result of the action.
+ */
+ private boolean booleanResult;
+
+ /**
+ * The String result of the action.
+ */
+ private String stringResult;
+
+ /**
+ * The Object result of the action.
+ */
+ private Object objectResult;
+
+ /**
+ * The Object[] result of the action.
+ */
+ private Object[] objectArrayResult;
+
+ /**
+ * Creates a new DimIProxy.
+ */
+ private DimIProxy(Dim dim, int type) {
+ this.dim = dim;
+ this.type = type;
+ }
+
+ // ContextAction
+
+ /**
+ * Performs the action given by {@link #type}.
+ */
+ public Object run(Context cx) {
+ switch (type) {
+ case IPROXY_COMPILE_SCRIPT:
+ cx.compileString(text, url, 1, null);
+ break;
+
+ case IPROXY_EVAL_SCRIPT:
+ {
+ Scriptable scope = null;
+ if (dim.scopeProvider != null) {
+ scope = dim.scopeProvider.getScope();
+ }
+ if (scope == null) {
+ scope = new ImporterTopLevel(cx);
+ }
+ cx.evaluateString(scope, text, url, 1, null);
+ }
+ break;
+
+ case IPROXY_STRING_IS_COMPILABLE:
+ booleanResult = cx.stringIsCompilableUnit(text);
+ break;
+
+ case IPROXY_OBJECT_TO_STRING:
+ if (object == Undefined.instance) {
+ stringResult = "undefined";
+ } else if (object == null) {
+ stringResult = "null";
+ } else if (object instanceof NativeCall) {
+ stringResult = "[object Call]";
+ } else {
+ stringResult = Context.toString(object);
+ }
+ break;
+
+ case IPROXY_OBJECT_PROPERTY:
+ objectResult = dim.getObjectPropertyImpl(cx, object, id);
+ break;
+
+ case IPROXY_OBJECT_IDS:
+ objectArrayResult = dim.getObjectIdsImpl(cx, object);
+ break;
+
+ default:
+ throw Kit.codeBug();
+ }
+ return null;
+ }
+
+ /**
+ * Performs the action given by {@link #type} with the attached
+ * {@link ContextFactory}.
+ */
+ private void withContext() {
+ dim.contextFactory.call(this);
+ }
+
+ // ContextFactory.Listener
+
+ /**
+ * Called when a Context is created.
+ */
+ public void contextCreated(Context cx) {
+ if (type != IPROXY_LISTEN) Kit.codeBug();
+ ContextData contextData = new ContextData();
+ Debugger debugger = new DimIProxy(dim, IPROXY_DEBUG);
+ cx.setDebugger(debugger, contextData);
+ cx.setGeneratingDebug(true);
+ cx.setOptimizationLevel(-1);
+ }
+
+ /**
+ * Called when a Context is destroyed.
+ */
+ public void contextReleased(Context cx) {
+ if (type != IPROXY_LISTEN) Kit.codeBug();
+ }
+
+ // Debugger
+
+ /**
+ * Returns a StackFrame for the given function or script.
+ */
+ public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
+ if (type != IPROXY_DEBUG) Kit.codeBug();
+
+ FunctionSource item = dim.getFunctionSource(fnOrScript);
+ if (item == null) {
+ // Can not debug if source is not available
+ return null;
+ }
+ return new StackFrame(cx, dim, item);
+ }
+
+ /**
+ * Called when compilation is finished.
+ */
+ public void handleCompilationDone(Context cx,
+ DebuggableScript fnOrScript,
+ String source) {
+ if (type != IPROXY_DEBUG) Kit.codeBug();
+
+ if (!fnOrScript.isTopLevel()) {
+ return;
+ }
+ dim.registerTopScript(fnOrScript, source);
+ }
+ }
+
+ /**
+ * Class to store information about a stack.
+ */
+ public static class ContextData {
+
+ /**
+ * The stack frames.
+ */
+ private ObjArray frameStack = new ObjArray();
+
+ /**
+ * Whether the debugger should break at the next line in this context.
+ */
+ private boolean breakNextLine;
+
+ /**
+ * The frame depth the debugger should stop at. Used to implement
+ * "step over" and "step out".
+ */
+ private int stopAtFrameDepth = -1;
+
+ /**
+ * Whether this context is in the event thread.
+ */
+ private boolean eventThreadFlag;
+
+ /**
+ * The last exception that was processed.
+ */
+ private Throwable lastProcessedException;
+
+ /**
+ * Returns the ContextData for the given Context.
+ */
+ public static ContextData get(Context cx) {
+ return (ContextData) cx.getDebuggerContextData();
+ }
+
+ /**
+ * Returns the number of stack frames.
+ */
+ public int frameCount() {
+ return frameStack.size();
+ }
+
+ /**
+ * Returns the stack frame with the given index.
+ */
+ public StackFrame getFrame(int frameNumber) {
+ int num = frameStack.size() - frameNumber - 1;
+ return (StackFrame) frameStack.get(num);
+ }
+
+ /**
+ * Pushes a stack frame on to the stack.
+ */
+ private void pushFrame(StackFrame frame) {
+ frameStack.push(frame);
+ }
+
+ /**
+ * Pops a stack frame from the stack.
+ */
+ private void popFrame() {
+ frameStack.pop();
+ }
+ }
+
+ /**
+ * Object to represent one stack frame.
+ */
+ public static class StackFrame implements DebugFrame {
+
+ /**
+ * The debugger.
+ */
+ private Dim dim;
+
+ /**
+ * The ContextData for the Context being debugged.
+ */
+ private ContextData contextData;
+
+ /**
+ * The scope.
+ */
+ private Scriptable scope;
+
+ /**
+ * The 'this' object.
+ */
+ private Scriptable thisObj;
+
+ /**
+ * Information about the function.
+ */
+ private FunctionSource fsource;
+
+ /**
+ * Array of breakpoint state for each source line.
+ */
+ private boolean[] breakpoints;
+
+ /**
+ * Current line number.
+ */
+ private int lineNumber;
+
+ /**
+ * Creates a new StackFrame.
+ */
+ private StackFrame(Context cx, Dim dim, FunctionSource fsource) {
+ this.dim = dim;
+ this.contextData = ContextData.get(cx);
+ this.fsource = fsource;
+ this.breakpoints = fsource.sourceInfo().breakpoints;
+ this.lineNumber = fsource.firstLine();
+ }
+
+ /**
+ * Called when the stack frame is entered.
+ */
+ public void onEnter(Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args) {
+ contextData.pushFrame(this);
+ this.scope = scope;
+ this.thisObj = thisObj;
+ if (dim.breakOnEnter) {
+ dim.handleBreakpointHit(this, cx);
+ }
+ }
+
+ /**
+ * Called when the current position has changed.
+ */
+ public void onLineChange(Context cx, int lineno) {
+ this.lineNumber = lineno;
+
+ if (!breakpoints[lineno] && !dim.breakFlag) {
+ boolean lineBreak = contextData.breakNextLine;
+ if (lineBreak && contextData.stopAtFrameDepth >= 0) {
+ lineBreak = (contextData.frameCount()
+ <= contextData.stopAtFrameDepth);
+ }
+ if (!lineBreak) {
+ return;
+ }
+ contextData.stopAtFrameDepth = -1;
+ contextData.breakNextLine = false;
+ }
+
+ dim.handleBreakpointHit(this, cx);
+ }
+
+ /**
+ * Called when an exception has been thrown.
+ */
+ public void onExceptionThrown(Context cx, Throwable exception) {
+ dim.handleExceptionThrown(cx, exception, this);
+ }
+
+ /**
+ * Called when the stack frame has been left.
+ */
+ public void onExit(Context cx, boolean byThrow,
+ Object resultOrException) {
+ if (dim.breakOnReturn && !byThrow) {
+ dim.handleBreakpointHit(this, cx);
+ }
+ contextData.popFrame();
+ }
+
+ /**
+ * Called when a 'debugger' statement is executed.
+ */
+ public void onDebuggerStatement(Context cx) {
+ dim.handleBreakpointHit(this, cx);
+ }
+
+ /**
+ * Returns the SourceInfo object for the function.
+ */
+ public SourceInfo sourceInfo() {
+ return fsource.sourceInfo();
+ }
+
+ /**
+ * Returns the ContextData object for the Context.
+ */
+ public ContextData contextData() {
+ return contextData;
+ }
+
+ /**
+ * Returns the scope object for this frame.
+ */
+ public Object scope() {
+ return scope;
+ }
+
+ /**
+ * Returns the 'this' object for this frame.
+ */
+ public Object thisObj() {
+ return thisObj;
+ }
+
+ /**
+ * Returns the source URL.
+ */
+ public String getUrl() {
+ return fsource.sourceInfo().url();
+ }
+
+ /**
+ * Returns the current line number.
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+ }
+
+ /**
+ * Class to store information about a function.
+ */
+ public static class FunctionSource {
+
+ /**
+ * Information about the source of the function.
+ */
+ private SourceInfo sourceInfo;
+
+ /**
+ * Line number of the first line of the function.
+ */
+ private int firstLine;
+
+ /**
+ * The function name.
+ */
+ private String name;
+
+ /**
+ * Creates a new FunctionSource.
+ */
+ private FunctionSource(SourceInfo sourceInfo, int firstLine,
+ String name) {
+ if (name == null) throw new IllegalArgumentException();
+ this.sourceInfo = sourceInfo;
+ this.firstLine = firstLine;
+ this.name = name;
+ }
+
+ /**
+ * Returns the SourceInfo object that describes the source of the
+ * function.
+ */
+ public SourceInfo sourceInfo() {
+ return sourceInfo;
+ }
+
+ /**
+ * Returns the line number of the first line of the function.
+ */
+ public int firstLine() {
+ return firstLine;
+ }
+
+ /**
+ * Returns the name of the function.
+ */
+ public String name() {
+ return name;
+ }
+ }
+
+ /**
+ * Class to store information about a script source.
+ */
+ public static class SourceInfo {
+
+ /**
+ * An empty array of booleans.
+ */
+ private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
+
+ /**
+ * The script.
+ */
+ private String source;
+
+ /**
+ * The URL of the script.
+ */
+ private String url;
+
+ /**
+ * Array indicating which lines can have breakpoints set.
+ */
+ private boolean[] breakableLines;
+
+ /**
+ * Array indicating whether a breakpoint is set on the line.
+ */
+ private boolean[] breakpoints;
+
+ /**
+ * Array of FunctionSource objects for the functions in the script.
+ */
+ private FunctionSource[] functionSources;
+
+ /**
+ * Creates a new SourceInfo object.
+ */
+ private SourceInfo(String source, DebuggableScript[] functions,
+ String normilizedUrl) {
+ this.source = source;
+ this.url = normilizedUrl;
+
+ int N = functions.length;
+ int[][] lineArrays = new int[N][];
+ for (int i = 0; i != N; ++i) {
+ lineArrays[i] = functions[i].getLineNumbers();
+ }
+
+ int minAll = 0, maxAll = -1;
+ int[] firstLines = new int[N];
+ for (int i = 0; i != N; ++i) {
+ int[] lines = lineArrays[i];
+ if (lines == null || lines.length == 0) {
+ firstLines[i] = -1;
+ } else {
+ int min, max;
+ min = max = lines[0];
+ for (int j = 1; j != lines.length; ++j) {
+ int line = lines[j];
+ if (line < min) {
+ min = line;
+ } else if (line > max) {
+ max = line;
+ }
+ }
+ firstLines[i] = min;
+ if (minAll > maxAll) {
+ minAll = min;
+ maxAll = max;
+ } else {
+ if (min < minAll) {
+ minAll = min;
+ }
+ if (max > maxAll) {
+ maxAll = max;
+ }
+ }
+ }
+ }
+
+ if (minAll > maxAll) {
+ // No line information
+ this.breakableLines = EMPTY_BOOLEAN_ARRAY;
+ this.breakpoints = EMPTY_BOOLEAN_ARRAY;
+ } else {
+ if (minAll < 0) {
+ // Line numbers can not be negative
+ throw new IllegalStateException(String.valueOf(minAll));
+ }
+ int linesTop = maxAll + 1;
+ this.breakableLines = new boolean[linesTop];
+ this.breakpoints = new boolean[linesTop];
+ for (int i = 0; i != N; ++i) {
+ int[] lines = lineArrays[i];
+ if (lines != null && lines.length != 0) {
+ for (int j = 0; j != lines.length; ++j) {
+ int line = lines[j];
+ this.breakableLines[line] = true;
+ }
+ }
+ }
+ }
+ this.functionSources = new FunctionSource[N];
+ for (int i = 0; i != N; ++i) {
+ String name = functions[i].getFunctionName();
+ if (name == null) {
+ name = "";
+ }
+ this.functionSources[i]
+ = new FunctionSource(this, firstLines[i], name);
+ }
+ }
+
+ /**
+ * Returns the source text.
+ */
+ public String source() {
+ return this.source;
+ }
+
+ /**
+ * Returns the script's origin URL.
+ */
+ public String url() {
+ return this.url;
+ }
+
+ /**
+ * Returns the number of FunctionSource objects stored in this object.
+ */
+ public int functionSourcesTop() {
+ return functionSources.length;
+ }
+
+ /**
+ * Returns the FunctionSource object with the given index.
+ */
+ public FunctionSource functionSource(int i) {
+ return functionSources[i];
+ }
+
+ /**
+ * Copies the breakpoints from the given SourceInfo object into this
+ * one.
+ */
+ private void copyBreakpointsFrom(SourceInfo old) {
+ int end = old.breakpoints.length;
+ if (end > this.breakpoints.length) {
+ end = this.breakpoints.length;
+ }
+ for (int line = 0; line != end; ++line) {
+ if (old.breakpoints[line]) {
+ this.breakpoints[line] = true;
+ }
+ }
+ }
+
+ /**
+ * Returns whether the given line number can have a breakpoint set on
+ * it.
+ */
+ public boolean breakableLine(int line) {
+ return (line < this.breakableLines.length)
+ && this.breakableLines[line];
+ }
+
+ /**
+ * Returns whether there is a breakpoint set on the given line.
+ */
+ public boolean breakpoint(int line) {
+ if (!breakableLine(line)) {
+ throw new IllegalArgumentException(String.valueOf(line));
+ }
+ return line < this.breakpoints.length && this.breakpoints[line];
+ }
+
+ /**
+ * Sets or clears the breakpoint flag for the given line.
+ */
+ public boolean breakpoint(int line, boolean value) {
+ if (!breakableLine(line)) {
+ throw new IllegalArgumentException(String.valueOf(line));
+ }
+ boolean changed;
+ synchronized (breakpoints) {
+ if (breakpoints[line] != value) {
+ breakpoints[line] = value;
+ changed = true;
+ } else {
+ changed = false;
+ }
+ }
+ return changed;
+ }
+
+ /**
+ * Removes all breakpoints from the script.
+ */
+ public void removeAllBreakpoints() {
+ synchronized (breakpoints) {
+ for (int line = 0; line != breakpoints.length; ++line) {
+ breakpoints[line] = false;
+ }
+ }
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java
new file mode 100644
index 0000000..f9762ec
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java
@@ -0,0 +1,71 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov, igor@fastmail.fm
+ * Cameron McCormack
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.debugger;
+
+/**
+ * Interface for communication between the debugger and its GUI. This
+ * should be implemented by the GUI.
+ */
+public interface GuiCallback {
+
+ /**
+ * Called when the source text of some script has been changed.
+ */
+ void updateSourceText(Dim.SourceInfo sourceInfo);
+
+ /**
+ * Called when the interrupt loop has been entered.
+ */
+ void enterInterrupt(Dim.StackFrame lastFrame,
+ String threadTitle,
+ String alertMessage);
+
+ /**
+ * Returns whether the current thread is the GUI's event thread.
+ * This information is required to avoid blocking the event thread
+ * from the debugger.
+ */
+ boolean isGuiEventThread();
+
+ /**
+ * Processes the next GUI event. This manual pumping of GUI events
+ * is necessary when the GUI event thread itself has been stopped.
+ */
+ void dispatchNextGuiEvent() throws InterruptedException;
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Main.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Main.java
new file mode 100644
index 0000000..3f90915
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/Main.java
@@ -0,0 +1,431 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * SeeBeyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Matt Gould
+ * Christopher Oliver
+ * Cameron McCormack
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.debugger;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import javax.swing.JFrame;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.tools.shell.Global;
+
+/**
+ * Rhino script debugger main class. This class links together a
+ * debugger object ({@link Dim}) and a debugger GUI object ({@link SwingGui}).
+ */
+public class Main {
+
+ /**
+ * The debugger.
+ */
+ private Dim dim;
+
+ /**
+ * The debugger frame.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * Creates a new Main.
+ */
+ public Main(String title) {
+ dim = new Dim();
+ debugGui = new SwingGui(dim, title);
+ }
+
+ /**
+ * Returns the debugger window {@link JFrame}.
+ */
+ public JFrame getDebugFrame() {
+ return debugGui;
+ }
+
+ /**
+ * Breaks execution of the script.
+ */
+ public void doBreak() {
+ dim.setBreak();
+ }
+
+ /**
+ * Sets whether execution should break when a script exception is thrown.
+ */
+ public void setBreakOnExceptions(boolean value) {
+ dim.setBreakOnExceptions(value);
+ debugGui.getMenubar().getBreakOnExceptions().setSelected(value);
+ }
+
+ /**
+ * Sets whether execution should break when a function is entered.
+ */
+ public void setBreakOnEnter(boolean value) {
+ dim.setBreakOnEnter(value);
+ debugGui.getMenubar().getBreakOnEnter().setSelected(value);
+ }
+
+ /**
+ * Sets whether execution should break when a function is left.
+ */
+ public void setBreakOnReturn(boolean value) {
+ dim.setBreakOnReturn(value);
+ debugGui.getMenubar().getBreakOnReturn().setSelected(value);
+ }
+
+ /**
+ * Removes all breakpoints.
+ */
+ public void clearAllBreakpoints() {
+ dim.clearAllBreakpoints();
+ }
+
+ /**
+ * Resumes execution of the script.
+ */
+ public void go() {
+ dim.go();
+ }
+
+ /**
+ * Sets the scope to be used for script evaluation.
+ */
+ public void setScope(Scriptable scope) {
+ setScopeProvider(IProxy.newScopeProvider(scope));
+ }
+
+ /**
+ * Sets the {@link ScopeProvider} that provides a scope to be used
+ * for script evaluation.
+ */
+ public void setScopeProvider(ScopeProvider p) {
+ dim.setScopeProvider(p);
+ }
+
+ /**
+ * Assign a Runnable object that will be invoked when the user
+ * selects "Exit..." or closes the Debugger main window.
+ */
+ public void setExitAction(Runnable r) {
+ debugGui.setExitAction(r);
+ }
+
+ /**
+ * Returns an {@link InputStream} for stdin from the debugger's internal
+ * Console window.
+ */
+ public InputStream getIn() {
+ return debugGui.getConsole().getIn();
+ }
+
+ /**
+ * Returns a {@link PrintStream} for stdout to the debugger's internal
+ * Console window.
+ */
+ public PrintStream getOut() {
+ return debugGui.getConsole().getOut();
+ }
+
+ /**
+ * Returns a {@link PrintStream} for stderr in the Debugger's internal
+ * Console window.
+ */
+ public PrintStream getErr() {
+ return debugGui.getConsole().getErr();
+ }
+
+ /**
+ * Packs the debugger GUI frame.
+ */
+ public void pack() {
+ debugGui.pack();
+ }
+
+ /**
+ * Sets the debugger GUI frame dimensions.
+ */
+ public void setSize(int w, int h) {
+ debugGui.setSize(w, h);
+ }
+
+ /**
+ * Sets the visibility of the debugger GUI frame.
+ */
+ public void setVisible(boolean flag) {
+ debugGui.setVisible(flag);
+ }
+
+ /**
+ * Returns whether the debugger GUI frame is visible.
+ */
+ public boolean isVisible() {
+ return debugGui.isVisible();
+ }
+
+ /**
+ * Frees any resources held by the debugger.
+ */
+ public void dispose() {
+ clearAllBreakpoints();
+ dim.go();
+ debugGui.dispose();
+ dim = null;
+ }
+
+ /**
+ * Attaches the debugger to the given {@link ContextFactory}.
+ */
+ public void attachTo(ContextFactory factory) {
+ dim.attachTo(factory);
+ }
+
+ /**
+ * Detaches from the current {@link ContextFactory}.
+ */
+ public void detach() {
+ dim.detach();
+ }
+
+ /**
+ * Main entry point. Creates a debugger attached to a Rhino
+ * {@link org.mozilla.javascript.tools.shell.Main} shell session.
+ */
+ public static void main(String[] args) {
+ Main main = new Main("Rhino JavaScript Debugger");
+ main.doBreak();
+ main.setExitAction(new IProxy(IProxy.EXIT_ACTION));
+
+ System.setIn(main.getIn());
+ System.setOut(main.getOut());
+ System.setErr(main.getErr());
+
+ Global global = org.mozilla.javascript.tools.shell.Main.getGlobal();
+ global.setIn(main.getIn());
+ global.setOut(main.getOut());
+ global.setErr(main.getErr());
+
+ main.attachTo(
+ org.mozilla.javascript.tools.shell.Main.shellContextFactory);
+
+ main.setScope(global);
+
+ main.pack();
+ main.setSize(600, 460);
+ main.setVisible(true);
+
+ org.mozilla.javascript.tools.shell.Main.exec(args);
+ }
+
+ /**
+ * Entry point for embedded applications. This method attaches
+ * to the global {@link ContextFactory} with a scope of a newly
+ * created {@link Global} object. No I/O redirection is performed
+ * as with {@link #main(String[])}.
+ */
+ public static void mainEmbedded(String title) {
+ ContextFactory factory = ContextFactory.getGlobal();
+ Global global = new Global();
+ global.init(factory);
+ mainEmbedded(factory, global, title);
+ }
+
+ /**
+ * Entry point for embedded applications. This method attaches
+ * to the given {@link ContextFactory} with the given scope. No
+ * I/O redirection is performed as with {@link #main(String[])}.
+ */
+ public static void mainEmbedded(ContextFactory factory,
+ Scriptable scope,
+ String title) {
+ mainEmbeddedImpl(factory, scope, title);
+ }
+
+ /**
+ * Entry point for embedded applications. This method attaches
+ * to the given {@link ContextFactory} with the given scope. No
+ * I/O redirection is performed as with {@link #main(String[])}.
+ */
+ public static void mainEmbedded(ContextFactory factory,
+ ScopeProvider scopeProvider,
+ String title) {
+ mainEmbeddedImpl(factory, scopeProvider, title);
+ }
+
+ /**
+ * Helper method for {@link #mainEmbedded(String)}, etc.
+ */
+ private static void mainEmbeddedImpl(ContextFactory factory,
+ Object scopeProvider,
+ String title) {
+ if (title == null) {
+ title = "Rhino JavaScript Debugger (embedded usage)";
+ }
+ Main main = new Main(title);
+ main.doBreak();
+ main.setExitAction(new IProxy(IProxy.EXIT_ACTION));
+
+ main.attachTo(factory);
+ if (scopeProvider instanceof ScopeProvider) {
+ main.setScopeProvider((ScopeProvider)scopeProvider);
+ } else {
+ Scriptable scope = (Scriptable)scopeProvider;
+ if (scope instanceof Global) {
+ Global global = (Global)scope;
+ global.setIn(main.getIn());
+ global.setOut(main.getOut());
+ global.setErr(main.getErr());
+ }
+ main.setScope(scope);
+ }
+
+ main.pack();
+ main.setSize(600, 460);
+ main.setVisible(true);
+ }
+
+ // Deprecated methods
+
+ /**
+ * @deprecated Use {@link #setSize(int, int)} instead.
+ */
+ public void setSize(java.awt.Dimension dimension) {
+ debugGui.setSize(dimension.width, dimension.height);
+ }
+
+ /**
+ * @deprecated
+ * The method does nothing and is only present for compatibility.
+ */
+ public void setOptimizationLevel(int level) {
+ }
+
+ /**
+ * @deprecated
+ * The method is only present for compatibility and should not be called.
+ */
+ public void contextEntered(Context cx) {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * @deprecated
+ * The method is only present for compatibility and should not be called.
+ */
+ public void contextExited(Context cx) {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * @deprecated
+ * The method is only present for compatibility and should not be called.
+ */
+ public void contextCreated(Context cx) {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * @deprecated
+ * The method is only present for compatibility and should not be called.
+ */
+ public void contextReleased(Context cx)
+ {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * Class to consolidate all internal implementations of interfaces
+ * to avoid class generation bloat.
+ */
+ private static class IProxy implements Runnable, ScopeProvider {
+
+ // Constants for 'type'.
+ public static final int EXIT_ACTION = 1;
+ public static final int SCOPE_PROVIDER = 2;
+
+ /**
+ * The type of interface.
+ */
+ private final int type;
+
+ /**
+ * The scope object to expose when {@link #type} =
+ * {@link #SCOPE_PROVIDER}.
+ */
+ private Scriptable scope;
+
+ /**
+ * Creates a new IProxy.
+ */
+ public IProxy(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Creates a new IProxy that acts as a {@link ScopeProvider}.
+ */
+ public static ScopeProvider newScopeProvider(Scriptable scope) {
+ IProxy scopeProvider = new IProxy(SCOPE_PROVIDER);
+ scopeProvider.scope = scope;
+ return scopeProvider;
+ }
+
+ // ContextAction
+
+ /**
+ * Exit action.
+ */
+ public void run() {
+ if (type != EXIT_ACTION) Kit.codeBug();
+ System.exit(0);
+ }
+
+ // ScopeProvider
+
+ /**
+ * Returns the scope for script evaluations.
+ */
+ public Scriptable getScope() {
+ if (type != SCOPE_PROVIDER) Kit.codeBug();
+ if (scope == null) Kit.codeBug();
+ return scope;
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/ScopeProvider.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/ScopeProvider.java
new file mode 100644
index 0000000..d8f65b9
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/ScopeProvider.java
@@ -0,0 +1,52 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * See Beyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christopher Oliver
+ * Cameron McCormack
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.debugger;
+
+import org.mozilla.javascript.Scriptable;
+
+/**
+ * Interface to provide a scope object for script evaluation to the debugger.
+ */
+public interface ScopeProvider {
+
+ /**
+ * Returns the scope object to be used for script evaluation.
+ */
+ Scriptable getScope();
+} \ No newline at end of file
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java
new file mode 100644
index 0000000..61dc065
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java
@@ -0,0 +1,3547 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * SeeBeyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Matt Gould
+ * Cameron McCormack
+ * Christopher Oliver
+ * Hannes Wallnoefer
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.debugger;
+
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.event.*;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.*;
+
+import java.util.*;
+import java.io.*;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreePath;
+import java.lang.reflect.Method;
+
+import org.mozilla.javascript.Kit;
+import org.mozilla.javascript.SecurityUtilities;
+
+import org.mozilla.javascript.tools.shell.ConsoleTextArea;
+
+import org.mozilla.javascript.tools.debugger.downloaded.JTreeTable;
+import org.mozilla.javascript.tools.debugger.downloaded.TreeTableModel;
+import org.mozilla.javascript.tools.debugger.downloaded.TreeTableModelAdapter;
+
+/**
+ * GUI for the Rhino debugger.
+ */
+public class SwingGui extends JFrame implements GuiCallback {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -8217029773456711621L;
+
+ /**
+ * The debugger.
+ */
+ Dim dim;
+
+ /**
+ * The action to run when the 'Exit' menu item is chosen or the
+ * frame is closed.
+ */
+ private Runnable exitAction;
+
+ /**
+ * The {@link JDesktopPane} that holds the script windows.
+ */
+ private JDesktopPane desk;
+
+ /**
+ * The {@link JPanel} that shows information about the context.
+ */
+ private ContextWindow context;
+
+ /**
+ * The menu bar.
+ */
+ private Menubar menubar;
+
+ /**
+ * The tool bar.
+ */
+ private JToolBar toolBar;
+
+ /**
+ * The console that displays I/O from the script.
+ */
+ private JSInternalConsole console;
+
+ /**
+ * The {@link JSplitPane} that separates {@link #desk} from
+ * {@link org.mozilla.javascript.Context}.
+ */
+ private JSplitPane split1;
+
+ /**
+ * The status bar.
+ */
+ private JLabel statusBar;
+
+ /**
+ * Hash table of internal frame names to the internal frames themselves.
+ */
+ private Hashtable toplevels = new Hashtable();
+
+ /**
+ * Hash table of script URLs to their internal frames.
+ */
+ private Hashtable fileWindows = new Hashtable();
+
+ /**
+ * The {@link FileWindow} that last had the focus.
+ */
+ private FileWindow currentWindow;
+
+ /**
+ * File choose dialog for loading a script.
+ */
+ JFileChooser dlg;
+
+ /**
+ * The AWT EventQueue. Used for manually pumping AWT events from
+ * {@link #dispatchNextGuiEvent()}.
+ */
+ private EventQueue awtEventQueue;
+
+ /**
+ * Creates a new SwingGui.
+ */
+ public SwingGui(Dim dim, String title) {
+ super(title);
+ this.dim = dim;
+ init();
+ dim.setGuiCallback(this);
+ }
+
+ /**
+ * Returns the Menubar of this debugger frame.
+ */
+ public Menubar getMenubar() {
+ return menubar;
+ }
+
+ /**
+ * Sets the {@link Runnable} that will be run when the "Exit" menu
+ * item is chosen.
+ */
+ public void setExitAction(Runnable r) {
+ exitAction = r;
+ }
+
+ /**
+ * Returns the debugger console component.
+ */
+ public JSInternalConsole getConsole() {
+ return console;
+ }
+
+ /**
+ * Sets the visibility of the debugger GUI.
+ */
+ public void setVisible(boolean b) {
+ super.setVisible(b);
+ if (b) {
+ // this needs to be done after the window is visible
+ console.consoleTextArea.requestFocus();
+ context.split.setDividerLocation(0.5);
+ try {
+ console.setMaximum(true);
+ console.setSelected(true);
+ console.show();
+ console.consoleTextArea.requestFocus();
+ } catch (Exception exc) {
+ }
+ }
+ }
+
+ /**
+ * Records a new internal frame.
+ */
+ void addTopLevel(String key, JFrame frame) {
+ if (frame != this) {
+ toplevels.put(key, frame);
+ }
+ }
+
+ /**
+ * Constructs the debugger GUI.
+ */
+ private void init() {
+ menubar = new Menubar(this);
+ setJMenuBar(menubar);
+ toolBar = new JToolBar();
+ JButton button;
+ JButton breakButton, goButton, stepIntoButton,
+ stepOverButton, stepOutButton;
+ String [] toolTips = {"Break (Pause)",
+ "Go (F5)",
+ "Step Into (F11)",
+ "Step Over (F7)",
+ "Step Out (F8)"};
+ int count = 0;
+ button = breakButton = new JButton("Break");
+ button.setToolTipText("Break");
+ button.setActionCommand("Break");
+ button.addActionListener(menubar);
+ button.setEnabled(true);
+ button.setToolTipText(toolTips[count++]);
+
+ button = goButton = new JButton("Go");
+ button.setToolTipText("Go");
+ button.setActionCommand("Go");
+ button.addActionListener(menubar);
+ button.setEnabled(false);
+ button.setToolTipText(toolTips[count++]);
+
+ button = stepIntoButton = new JButton("Step Into");
+ button.setToolTipText("Step Into");
+ button.setActionCommand("Step Into");
+ button.addActionListener(menubar);
+ button.setEnabled(false);
+ button.setToolTipText(toolTips[count++]);
+
+ button = stepOverButton = new JButton("Step Over");
+ button.setToolTipText("Step Over");
+ button.setActionCommand("Step Over");
+ button.setEnabled(false);
+ button.addActionListener(menubar);
+ button.setToolTipText(toolTips[count++]);
+
+ button = stepOutButton = new JButton("Step Out");
+ button.setToolTipText("Step Out");
+ button.setActionCommand("Step Out");
+ button.setEnabled(false);
+ button.addActionListener(menubar);
+ button.setToolTipText(toolTips[count++]);
+
+ Dimension dim = stepOverButton.getPreferredSize();
+ breakButton.setPreferredSize(dim);
+ breakButton.setMinimumSize(dim);
+ breakButton.setMaximumSize(dim);
+ breakButton.setSize(dim);
+ goButton.setPreferredSize(dim);
+ goButton.setMinimumSize(dim);
+ goButton.setMaximumSize(dim);
+ stepIntoButton.setPreferredSize(dim);
+ stepIntoButton.setMinimumSize(dim);
+ stepIntoButton.setMaximumSize(dim);
+ stepOverButton.setPreferredSize(dim);
+ stepOverButton.setMinimumSize(dim);
+ stepOverButton.setMaximumSize(dim);
+ stepOutButton.setPreferredSize(dim);
+ stepOutButton.setMinimumSize(dim);
+ stepOutButton.setMaximumSize(dim);
+ toolBar.add(breakButton);
+ toolBar.add(goButton);
+ toolBar.add(stepIntoButton);
+ toolBar.add(stepOverButton);
+ toolBar.add(stepOutButton);
+
+ JPanel contentPane = new JPanel();
+ contentPane.setLayout(new BorderLayout());
+ getContentPane().add(toolBar, BorderLayout.NORTH);
+ getContentPane().add(contentPane, BorderLayout.CENTER);
+ desk = new JDesktopPane();
+ desk.setPreferredSize(new Dimension(600, 300));
+ desk.setMinimumSize(new Dimension(150, 50));
+ desk.add(console = new JSInternalConsole("JavaScript Console"));
+ context = new ContextWindow(this);
+ context.setPreferredSize(new Dimension(600, 120));
+ context.setMinimumSize(new Dimension(50, 50));
+
+ split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, desk,
+ context);
+ split1.setOneTouchExpandable(true);
+ SwingGui.setResizeWeight(split1, 0.66);
+ contentPane.add(split1, BorderLayout.CENTER);
+ statusBar = new JLabel();
+ statusBar.setText("Thread: ");
+ contentPane.add(statusBar, BorderLayout.SOUTH);
+ dlg = new JFileChooser();
+
+ javax.swing.filechooser.FileFilter filter =
+ new javax.swing.filechooser.FileFilter() {
+ public boolean accept(File f) {
+ if (f.isDirectory()) {
+ return true;
+ }
+ String n = f.getName();
+ int i = n.lastIndexOf('.');
+ if (i > 0 && i < n.length() -1) {
+ String ext = n.substring(i + 1).toLowerCase();
+ if (ext.equals("js")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ return "JavaScript Files (*.js)";
+ }
+ };
+ dlg.addChoosableFileFilter(filter);
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ exit();
+ }
+ });
+ }
+
+ /**
+ * Runs the {@link #exitAction}.
+ */
+ private void exit() {
+ if (exitAction != null) {
+ SwingUtilities.invokeLater(exitAction);
+ }
+ dim.setReturnValue(Dim.EXIT);
+ }
+
+ /**
+ * Returns the {@link FileWindow} for the given URL.
+ */
+ FileWindow getFileWindow(String url) {
+ if (url == null || url.equals("<stdin>")) {
+ return null;
+ }
+ return (FileWindow)fileWindows.get(url);
+ }
+
+ /**
+ * Returns a short version of the given URL.
+ */
+ static String getShortName(String url) {
+ int lastSlash = url.lastIndexOf('/');
+ if (lastSlash < 0) {
+ lastSlash = url.lastIndexOf('\\');
+ }
+ String shortName = url;
+ if (lastSlash >= 0 && lastSlash + 1 < url.length()) {
+ shortName = url.substring(lastSlash + 1);
+ }
+ return shortName;
+ }
+
+ /**
+ * Closes the given {@link FileWindow}.
+ */
+ void removeWindow(FileWindow w) {
+ fileWindows.remove(w.getUrl());
+ JMenu windowMenu = getWindowMenu();
+ int count = windowMenu.getItemCount();
+ JMenuItem lastItem = windowMenu.getItem(count -1);
+ String name = getShortName(w.getUrl());
+ for (int i = 5; i < count; i++) {
+ JMenuItem item = windowMenu.getItem(i);
+ if (item == null) continue; // separator
+ String text = item.getText();
+ //1 D:\foo.js
+ //2 D:\bar.js
+ int pos = text.indexOf(' ');
+ if (text.substring(pos + 1).equals(name)) {
+ windowMenu.remove(item);
+ // Cascade [0]
+ // Tile [1]
+ // ------- [2]
+ // Console [3]
+ // ------- [4]
+ if (count == 6) {
+ // remove the final separator
+ windowMenu.remove(4);
+ } else {
+ int j = i - 4;
+ for (;i < count -1; i++) {
+ JMenuItem thisItem = windowMenu.getItem(i);
+ if (thisItem != null) {
+ //1 D:\foo.js
+ //2 D:\bar.js
+ text = thisItem.getText();
+ if (text.equals("More Windows...")) {
+ break;
+ } else {
+ pos = text.indexOf(' ');
+ thisItem.setText((char)('0' + j) + " " +
+ text.substring(pos + 1));
+ thisItem.setMnemonic('0' + j);
+ j++;
+ }
+ }
+ }
+ if (count - 6 == 0 && lastItem != item) {
+ if (lastItem.getText().equals("More Windows...")) {
+ windowMenu.remove(lastItem);
+ }
+ }
+ }
+ break;
+ }
+ }
+ windowMenu.revalidate();
+ }
+
+ /**
+ * Shows the line at which execution in the given stack frame just stopped.
+ */
+ void showStopLine(Dim.StackFrame frame) {
+ String sourceName = frame.getUrl();
+ if (sourceName == null || sourceName.equals("<stdin>")) {
+ if (console.isVisible()) {
+ console.show();
+ }
+ } else {
+ showFileWindow(sourceName, -1);
+ int lineNumber = frame.getLineNumber();
+ FileWindow w = getFileWindow(sourceName);
+ if (w != null) {
+ setFilePosition(w, lineNumber);
+ }
+ }
+ }
+
+ /**
+ * Shows a {@link FileWindow} for the given source, creating it
+ * if it doesn't exist yet. if <code>lineNumber</code> is greater
+ * than -1, it indicates the line number to select and display.
+ * @param sourceUrl the source URL
+ * @param lineNumber the line number to select, or -1
+ */
+ protected void showFileWindow(String sourceUrl, int lineNumber) {
+ FileWindow w = getFileWindow(sourceUrl);
+ if (w == null) {
+ Dim.SourceInfo si = dim.sourceInfo(sourceUrl);
+ createFileWindow(si, -1);
+ w = getFileWindow(sourceUrl);
+ }
+ if (lineNumber > -1) {
+ int start = w.getPosition(lineNumber-1);
+ int end = w.getPosition(lineNumber)-1;
+ w.textArea.select(start);
+ w.textArea.setCaretPosition(start);
+ w.textArea.moveCaretPosition(end);
+ }
+ try {
+ if (w.isIcon()) {
+ w.setIcon(false);
+ }
+ w.setVisible(true);
+ w.moveToFront();
+ w.setSelected(true);
+ requestFocus();
+ w.requestFocus();
+ w.textArea.requestFocus();
+ } catch (Exception exc) {
+ }
+ }
+
+ /**
+ * Creates and shows a new {@link FileWindow} for the given source.
+ */
+ protected void createFileWindow(Dim.SourceInfo sourceInfo, int line) {
+ boolean activate = true;
+
+ String url = sourceInfo.url();
+ FileWindow w = new FileWindow(this, sourceInfo);
+ fileWindows.put(url, w);
+ if (line != -1) {
+ if (currentWindow != null) {
+ currentWindow.setPosition(-1);
+ }
+ try {
+ w.setPosition(w.textArea.getLineStartOffset(line-1));
+ } catch (BadLocationException exc) {
+ try {
+ w.setPosition(w.textArea.getLineStartOffset(0));
+ } catch (BadLocationException ee) {
+ w.setPosition(-1);
+ }
+ }
+ }
+ desk.add(w);
+ if (line != -1) {
+ currentWindow = w;
+ }
+ menubar.addFile(url);
+ w.setVisible(true);
+
+ if (activate) {
+ try {
+ w.setMaximum(true);
+ w.setSelected(true);
+ w.moveToFront();
+ } catch (Exception exc) {
+ }
+ }
+ }
+
+ /**
+ * Update the source text for <code>sourceInfo</code>. This returns true
+ * if a {@link FileWindow} for the given source exists and could be updated.
+ * Otherwise, this does nothing and returns false.
+ * @param sourceInfo the source info
+ * @return true if a {@link FileWindow} for the given source exists
+ * and could be updated, false otherwise.
+ */
+ protected boolean updateFileWindow(Dim.SourceInfo sourceInfo) {
+ String fileName = sourceInfo.url();
+ FileWindow w = getFileWindow(fileName);
+ if (w != null) {
+ w.updateText(sourceInfo);
+ w.show();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Moves the current position in the given {@link FileWindow} to the
+ * given line.
+ */
+ private void setFilePosition(FileWindow w, int line) {
+ boolean activate = true;
+ JTextArea ta = w.textArea;
+ try {
+ if (line == -1) {
+ w.setPosition(-1);
+ if (currentWindow == w) {
+ currentWindow = null;
+ }
+ } else {
+ int loc = ta.getLineStartOffset(line-1);
+ if (currentWindow != null && currentWindow != w) {
+ currentWindow.setPosition(-1);
+ }
+ w.setPosition(loc);
+ currentWindow = w;
+ }
+ } catch (BadLocationException exc) {
+ // fix me
+ }
+ if (activate) {
+ if (w.isIcon()) {
+ desk.getDesktopManager().deiconifyFrame(w);
+ }
+ desk.getDesktopManager().activateFrame(w);
+ try {
+ w.show();
+ w.toFront(); // required for correct frame layering (JDK 1.4.1)
+ w.setSelected(true);
+ } catch (Exception exc) {
+ }
+ }
+ }
+
+ /**
+ * Handles script interruption.
+ */
+ void enterInterruptImpl(Dim.StackFrame lastFrame,
+ String threadTitle, String alertMessage) {
+ statusBar.setText("Thread: " + threadTitle);
+
+ showStopLine(lastFrame);
+
+ if (alertMessage != null) {
+ MessageDialogWrapper.showMessageDialog(this,
+ alertMessage,
+ "Exception in Script",
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+ updateEnabled(true);
+
+ Dim.ContextData contextData = lastFrame.contextData();
+
+ JComboBox ctx = context.context;
+ Vector toolTips = context.toolTips;
+ context.disableUpdate();
+ int frameCount = contextData.frameCount();
+ ctx.removeAllItems();
+ // workaround for JDK 1.4 bug that caches selected value even after
+ // removeAllItems() is called
+ ctx.setSelectedItem(null);
+ toolTips.removeAllElements();
+ for (int i = 0; i < frameCount; i++) {
+ Dim.StackFrame frame = contextData.getFrame(i);
+ String url = frame.getUrl();
+ int lineNumber = frame.getLineNumber();
+ String shortName = url;
+ if (url.length() > 20) {
+ shortName = "..." + url.substring(url.length() - 17);
+ }
+ String location = "\"" + shortName + "\", line " + lineNumber;
+ ctx.insertItemAt(location, i);
+ location = "\"" + url + "\", line " + lineNumber;
+ toolTips.addElement(location);
+ }
+ context.enableUpdate();
+ ctx.setSelectedIndex(0);
+ ctx.setMinimumSize(new Dimension(50, ctx.getMinimumSize().height));
+ }
+
+ /**
+ * Returns the 'Window' menu.
+ */
+ private JMenu getWindowMenu() {
+ return menubar.getMenu(3);
+ }
+
+ /**
+ * Displays a {@link JFileChooser} and returns the selected filename.
+ */
+ private String chooseFile(String title) {
+ dlg.setDialogTitle(title);
+ File CWD = null;
+ String dir = SecurityUtilities.getSystemProperty("user.dir");
+ if (dir != null) {
+ CWD = new File(dir);
+ }
+ if (CWD != null) {
+ dlg.setCurrentDirectory(CWD);
+ }
+ int returnVal = dlg.showOpenDialog(this);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ try {
+ String result = dlg.getSelectedFile().getCanonicalPath();
+ CWD = dlg.getSelectedFile().getParentFile();
+ Properties props = System.getProperties();
+ props.put("user.dir", CWD.getPath());
+ System.setProperties(props);
+ return result;
+ } catch (IOException ignored) {
+ } catch (SecurityException ignored) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the current selected internal frame.
+ */
+ private JInternalFrame getSelectedFrame() {
+ JInternalFrame[] frames = desk.getAllFrames();
+ for (int i = 0; i < frames.length; i++) {
+ if (frames[i].isShowing()) {
+ return frames[i];
+ }
+ }
+ return frames[frames.length - 1];
+ }
+
+ /**
+ * Enables or disables the menu and tool bars with respect to the
+ * state of script execution.
+ */
+ private void updateEnabled(boolean interrupted) {
+ ((Menubar)getJMenuBar()).updateEnabled(interrupted);
+ for (int ci = 0, cc = toolBar.getComponentCount(); ci < cc; ci++) {
+ boolean enableButton;
+ if (ci == 0) {
+ // Break
+ enableButton = !interrupted;
+ } else {
+ enableButton = interrupted;
+ }
+ toolBar.getComponent(ci).setEnabled(enableButton);
+ }
+ if (interrupted) {
+ toolBar.setEnabled(true);
+ // raise the debugger window
+ int state = getExtendedState();
+ if (state == Frame.ICONIFIED) {
+ setExtendedState(Frame.NORMAL);
+ }
+ toFront();
+ context.enable();
+ } else {
+ if (currentWindow != null) currentWindow.setPosition(-1);
+ context.disable();
+ }
+ }
+
+ /**
+ * Calls {@link JSplitPane#setResizeWeight} via reflection.
+ * For compatibility, since JDK &lt; 1.3 does not have this method.
+ */
+ static void setResizeWeight(JSplitPane pane, double weight) {
+ try {
+ Method m = JSplitPane.class.getMethod("setResizeWeight",
+ new Class[]{double.class});
+ m.invoke(pane, new Object[]{new Double(weight)});
+ } catch (NoSuchMethodException exc) {
+ } catch (IllegalAccessException exc) {
+ } catch (java.lang.reflect.InvocationTargetException exc) {
+ }
+ }
+
+ /**
+ * Reads the file with the given name and returns its contents as a String.
+ */
+ private String readFile(String fileName) {
+ String text;
+ try {
+ Reader r = new FileReader(fileName);
+ try {
+ text = Kit.readReader(r);
+ } finally {
+ r.close();
+ }
+ } catch (IOException ex) {
+ MessageDialogWrapper.showMessageDialog(this,
+ ex.getMessage(),
+ "Error reading "+fileName,
+ JOptionPane.ERROR_MESSAGE);
+ text = null;
+ }
+ return text;
+ }
+
+ // GuiCallback
+
+ /**
+ * Called when the source text for a script has been updated.
+ */
+ public void updateSourceText(Dim.SourceInfo sourceInfo) {
+ RunProxy proxy = new RunProxy(this, RunProxy.UPDATE_SOURCE_TEXT);
+ proxy.sourceInfo = sourceInfo;
+ SwingUtilities.invokeLater(proxy);
+ }
+
+ /**
+ * Called when the interrupt loop has been entered.
+ */
+ public void enterInterrupt(Dim.StackFrame lastFrame,
+ String threadTitle,
+ String alertMessage) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ enterInterruptImpl(lastFrame, threadTitle, alertMessage);
+ } else {
+ RunProxy proxy = new RunProxy(this, RunProxy.ENTER_INTERRUPT);
+ proxy.lastFrame = lastFrame;
+ proxy.threadTitle = threadTitle;
+ proxy.alertMessage = alertMessage;
+ SwingUtilities.invokeLater(proxy);
+ }
+ }
+
+ /**
+ * Returns whether the current thread is the GUI event thread.
+ */
+ public boolean isGuiEventThread() {
+ return SwingUtilities.isEventDispatchThread();
+ }
+
+ /**
+ * Processes the next GUI event.
+ */
+ public void dispatchNextGuiEvent() throws InterruptedException {
+ EventQueue queue = awtEventQueue;
+ if (queue == null) {
+ queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ awtEventQueue = queue;
+ }
+ AWTEvent event = queue.getNextEvent();
+ if (event instanceof ActiveEvent) {
+ ((ActiveEvent)event).dispatch();
+ } else {
+ Object source = event.getSource();
+ if (source instanceof Component) {
+ Component comp = (Component)source;
+ comp.dispatchEvent(event);
+ } else if (source instanceof MenuComponent) {
+ ((MenuComponent)source).dispatchEvent(event);
+ }
+ }
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action from the menu or toolbar.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ int returnValue = -1;
+ if (cmd.equals("Cut") || cmd.equals("Copy") || cmd.equals("Paste")) {
+ JInternalFrame f = getSelectedFrame();
+ if (f != null && f instanceof ActionListener) {
+ ((ActionListener)f).actionPerformed(e);
+ }
+ } else if (cmd.equals("Step Over")) {
+ returnValue = Dim.STEP_OVER;
+ } else if (cmd.equals("Step Into")) {
+ returnValue = Dim.STEP_INTO;
+ } else if (cmd.equals("Step Out")) {
+ returnValue = Dim.STEP_OUT;
+ } else if (cmd.equals("Go")) {
+ returnValue = Dim.GO;
+ } else if (cmd.equals("Break")) {
+ dim.setBreak();
+ } else if (cmd.equals("Exit")) {
+ exit();
+ } else if (cmd.equals("Open")) {
+ String fileName = chooseFile("Select a file to compile");
+ if (fileName != null) {
+ String text = readFile(fileName);
+ if (text != null) {
+ RunProxy proxy = new RunProxy(this, RunProxy.OPEN_FILE);
+ proxy.fileName = fileName;
+ proxy.text = text;
+ new Thread(proxy).start();
+ }
+ }
+ } else if (cmd.equals("Load")) {
+ String fileName = chooseFile("Select a file to execute");
+ if (fileName != null) {
+ String text = readFile(fileName);
+ if (text != null) {
+ RunProxy proxy = new RunProxy(this, RunProxy.LOAD_FILE);
+ proxy.fileName = fileName;
+ proxy.text = text;
+ new Thread(proxy).start();
+ }
+ }
+ } else if (cmd.equals("More Windows...")) {
+ MoreWindows dlg = new MoreWindows(this, fileWindows,
+ "Window", "Files");
+ dlg.showDialog(this);
+ } else if (cmd.equals("Console")) {
+ if (console.isIcon()) {
+ desk.getDesktopManager().deiconifyFrame(console);
+ }
+ console.show();
+ desk.getDesktopManager().activateFrame(console);
+ console.consoleTextArea.requestFocus();
+ } else if (cmd.equals("Cut")) {
+ } else if (cmd.equals("Copy")) {
+ } else if (cmd.equals("Paste")) {
+ } else if (cmd.equals("Go to function...")) {
+ FindFunction dlg = new FindFunction(this, "Go to function",
+ "Function");
+ dlg.showDialog(this);
+ } else if (cmd.equals("Tile")) {
+ JInternalFrame[] frames = desk.getAllFrames();
+ int count = frames.length;
+ int rows, cols;
+ rows = cols = (int)Math.sqrt(count);
+ if (rows*cols < count) {
+ cols++;
+ if (rows * cols < count) {
+ rows++;
+ }
+ }
+ Dimension size = desk.getSize();
+ int w = size.width/cols;
+ int h = size.height/rows;
+ int x = 0;
+ int y = 0;
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ int index = (i*cols) + j;
+ if (index >= frames.length) {
+ break;
+ }
+ JInternalFrame f = frames[index];
+ try {
+ f.setIcon(false);
+ f.setMaximum(false);
+ } catch (Exception exc) {
+ }
+ desk.getDesktopManager().setBoundsForFrame(f, x, y,
+ w, h);
+ x += w;
+ }
+ y += h;
+ x = 0;
+ }
+ } else if (cmd.equals("Cascade")) {
+ JInternalFrame[] frames = desk.getAllFrames();
+ int count = frames.length;
+ int x, y, w, h;
+ x = y = 0;
+ h = desk.getHeight();
+ int d = h / count;
+ if (d > 30) d = 30;
+ for (int i = count -1; i >= 0; i--, x += d, y += d) {
+ JInternalFrame f = frames[i];
+ try {
+ f.setIcon(false);
+ f.setMaximum(false);
+ } catch (Exception exc) {
+ }
+ Dimension dimen = f.getPreferredSize();
+ w = dimen.width;
+ h = dimen.height;
+ desk.getDesktopManager().setBoundsForFrame(f, x, y, w, h);
+ }
+ } else {
+ Object obj = getFileWindow(cmd);
+ if (obj != null) {
+ FileWindow w = (FileWindow)obj;
+ try {
+ if (w.isIcon()) {
+ w.setIcon(false);
+ }
+ w.setVisible(true);
+ w.moveToFront();
+ w.setSelected(true);
+ } catch (Exception exc) {
+ }
+ }
+ }
+ if (returnValue != -1) {
+ updateEnabled(false);
+ dim.setReturnValue(returnValue);
+ }
+ }
+}
+
+/**
+ * Helper class for showing a message dialog.
+ */
+class MessageDialogWrapper {
+
+ /**
+ * Shows a message dialog, wrapping the <code>msg</code> at 60
+ * columns.
+ */
+ public static void showMessageDialog(Component parent, String msg,
+ String title, int flags) {
+ if (msg.length() > 60) {
+ StringBuffer buf = new StringBuffer();
+ int len = msg.length();
+ int j = 0;
+ int i;
+ for (i = 0; i < len; i++, j++) {
+ char c = msg.charAt(i);
+ buf.append(c);
+ if (Character.isWhitespace(c)) {
+ int k;
+ for (k = i + 1; k < len; k++) {
+ if (Character.isWhitespace(msg.charAt(k))) {
+ break;
+ }
+ }
+ if (k < len) {
+ int nextWordLen = k - i;
+ if (j + nextWordLen > 60) {
+ buf.append('\n');
+ j = 0;
+ }
+ }
+ }
+ }
+ msg = buf.toString();
+ }
+ JOptionPane.showMessageDialog(parent, msg, title, flags);
+ }
+}
+
+/**
+ * Extension of JTextArea for script evaluation input.
+ */
+class EvalTextArea
+ extends JTextArea
+ implements KeyListener, DocumentListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -3918033649601064194L;
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * History of expressions that have been evaluated
+ */
+ private Vector history;
+
+ /**
+ * Index of the selected history item.
+ */
+ private int historyIndex = -1;
+
+ /**
+ * Position in the display where output should go.
+ */
+ private int outputMark;
+
+ /**
+ * Creates a new EvalTextArea.
+ */
+ public EvalTextArea(SwingGui debugGui) {
+ this.debugGui = debugGui;
+ history = new java.util.Vector();
+ Document doc = getDocument();
+ doc.addDocumentListener(this);
+ addKeyListener(this);
+ setLineWrap(true);
+ setFont(new Font("Monospaced", 0, 12));
+ append("% ");
+ outputMark = doc.getLength();
+ }
+
+ /**
+ * Selects a subrange of the text.
+ */
+ public void select(int start, int end) {
+ //requestFocus();
+ super.select(start, end);
+ }
+
+ /**
+ * Called when Enter is pressed.
+ */
+ private synchronized void returnPressed() {
+ Document doc = getDocument();
+ int len = doc.getLength();
+ Segment segment = new Segment();
+ try {
+ doc.getText(outputMark, len - outputMark, segment);
+ } catch (javax.swing.text.BadLocationException ignored) {
+ ignored.printStackTrace();
+ }
+ String text = segment.toString();
+ if (debugGui.dim.stringIsCompilableUnit(text)) {
+ if (text.trim().length() > 0) {
+ history.addElement(text);
+ historyIndex = history.size();
+ }
+ append("\n");
+ String result = debugGui.dim.eval(text);
+ if (result.length() > 0) {
+ append(result);
+ append("\n");
+ }
+ append("% ");
+ outputMark = doc.getLength();
+ } else {
+ append("\n");
+ }
+ }
+
+ /**
+ * Writes output into the text area.
+ */
+ public synchronized void write(String str) {
+ insert(str, outputMark);
+ int len = str.length();
+ outputMark += len;
+ select(outputMark, outputMark);
+ }
+
+ // KeyListener
+
+ /**
+ * Called when a key is pressed.
+ */
+ public void keyPressed(KeyEvent e) {
+ int code = e.getKeyCode();
+ if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
+ if (outputMark == getCaretPosition()) {
+ e.consume();
+ }
+ } else if (code == KeyEvent.VK_HOME) {
+ int caretPos = getCaretPosition();
+ if (caretPos == outputMark) {
+ e.consume();
+ } else if (caretPos > outputMark) {
+ if (!e.isControlDown()) {
+ if (e.isShiftDown()) {
+ moveCaretPosition(outputMark);
+ } else {
+ setCaretPosition(outputMark);
+ }
+ e.consume();
+ }
+ }
+ } else if (code == KeyEvent.VK_ENTER) {
+ returnPressed();
+ e.consume();
+ } else if (code == KeyEvent.VK_UP) {
+ historyIndex--;
+ if (historyIndex >= 0) {
+ if (historyIndex >= history.size()) {
+ historyIndex = history.size() -1;
+ }
+ if (historyIndex >= 0) {
+ String str = (String)history.elementAt(historyIndex);
+ int len = getDocument().getLength();
+ replaceRange(str, outputMark, len);
+ int caretPos = outputMark + str.length();
+ select(caretPos, caretPos);
+ } else {
+ historyIndex++;
+ }
+ } else {
+ historyIndex++;
+ }
+ e.consume();
+ } else if (code == KeyEvent.VK_DOWN) {
+ int caretPos = outputMark;
+ if (history.size() > 0) {
+ historyIndex++;
+ if (historyIndex < 0) {historyIndex = 0;}
+ int len = getDocument().getLength();
+ if (historyIndex < history.size()) {
+ String str = (String)history.elementAt(historyIndex);
+ replaceRange(str, outputMark, len);
+ caretPos = outputMark + str.length();
+ } else {
+ historyIndex = history.size();
+ replaceRange("", outputMark, len);
+ }
+ }
+ select(caretPos, caretPos);
+ e.consume();
+ }
+ }
+
+ /**
+ * Called when a key is typed.
+ */
+ public void keyTyped(KeyEvent e) {
+ int keyChar = e.getKeyChar();
+ if (keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) {
+ if (outputMark == getCaretPosition()) {
+ e.consume();
+ }
+ } else if (getCaretPosition() < outputMark) {
+ setCaretPosition(outputMark);
+ }
+ }
+
+ /**
+ * Called when a key is released.
+ */
+ public synchronized void keyReleased(KeyEvent e) {
+ }
+
+ // DocumentListener
+
+ /**
+ * Called when text was inserted into the text area.
+ */
+ public synchronized void insertUpdate(DocumentEvent e) {
+ int len = e.getLength();
+ int off = e.getOffset();
+ if (outputMark > off) {
+ outputMark += len;
+ }
+ }
+
+ /**
+ * Called when text was removed from the text area.
+ */
+ public synchronized void removeUpdate(DocumentEvent e) {
+ int len = e.getLength();
+ int off = e.getOffset();
+ if (outputMark > off) {
+ if (outputMark >= off + len) {
+ outputMark -= len;
+ } else {
+ outputMark = off;
+ }
+ }
+ }
+
+ /**
+ * Attempts to clean up the damage done by {@link #updateUI()}.
+ */
+ public synchronized void postUpdateUI() {
+ //requestFocus();
+ setCaret(getCaret());
+ select(outputMark, outputMark);
+ }
+
+ /**
+ * Called when text has changed in the text area.
+ */
+ public synchronized void changedUpdate(DocumentEvent e) {
+ }
+}
+
+/**
+ * An internal frame for evaluating script.
+ */
+class EvalWindow extends JInternalFrame implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -2860585845212160176L;
+
+ /**
+ * The text area into which expressions can be typed.
+ */
+ private EvalTextArea evalTextArea;
+
+ /**
+ * Creates a new EvalWindow.
+ */
+ public EvalWindow(String name, SwingGui debugGui) {
+ super(name, true, false, true, true);
+ evalTextArea = new EvalTextArea(debugGui);
+ evalTextArea.setRows(24);
+ evalTextArea.setColumns(80);
+ JScrollPane scroller = new JScrollPane(evalTextArea);
+ setContentPane(scroller);
+ //scroller.setPreferredSize(new Dimension(600, 400));
+ pack();
+ setVisible(true);
+ }
+
+ /**
+ * Sets whether the text area is enabled.
+ */
+ public void setEnabled(boolean b) {
+ super.setEnabled(b);
+ evalTextArea.setEnabled(b);
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action on the text area.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cut")) {
+ evalTextArea.cut();
+ } else if (cmd.equals("Copy")) {
+ evalTextArea.copy();
+ } else if (cmd.equals("Paste")) {
+ evalTextArea.paste();
+ }
+ }
+}
+
+/**
+ * Internal frame for the console.
+ */
+class JSInternalConsole extends JInternalFrame implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -5523468828771087292L;
+
+ /**
+ * Creates a new JSInternalConsole.
+ */
+ public JSInternalConsole(String name) {
+ super(name, true, false, true, true);
+ consoleTextArea = new ConsoleTextArea(null);
+ consoleTextArea.setRows(24);
+ consoleTextArea.setColumns(80);
+ JScrollPane scroller = new JScrollPane(consoleTextArea);
+ setContentPane(scroller);
+ pack();
+ addInternalFrameListener(new InternalFrameAdapter() {
+ public void internalFrameActivated(InternalFrameEvent e) {
+ // hack
+ if (consoleTextArea.hasFocus()) {
+ consoleTextArea.getCaret().setVisible(false);
+ consoleTextArea.getCaret().setVisible(true);
+ }
+ }
+ });
+ }
+
+ /**
+ * The console text area.
+ */
+ ConsoleTextArea consoleTextArea;
+
+ /**
+ * Returns the input stream of the console text area.
+ */
+ public InputStream getIn() {
+ return consoleTextArea.getIn();
+ }
+
+ /**
+ * Returns the output stream of the console text area.
+ */
+ public PrintStream getOut() {
+ return consoleTextArea.getOut();
+ }
+
+ /**
+ * Returns the error stream of the console text area.
+ */
+ public PrintStream getErr() {
+ return consoleTextArea.getErr();
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action on the text area.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cut")) {
+ consoleTextArea.cut();
+ } else if (cmd.equals("Copy")) {
+ consoleTextArea.copy();
+ } else if (cmd.equals("Paste")) {
+ consoleTextArea.paste();
+ }
+ }
+}
+
+/**
+ * Popup menu class for right-clicking on {@link FileTextArea}s.
+ */
+class FilePopupMenu extends JPopupMenu {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 3589525009546013565L;
+
+ /**
+ * The popup x position.
+ */
+ int x;
+
+ /**
+ * The popup y position.
+ */
+ int y;
+
+ /**
+ * Creates a new FilePopupMenu.
+ */
+ public FilePopupMenu(FileTextArea w) {
+ JMenuItem item;
+ add(item = new JMenuItem("Set Breakpoint"));
+ item.addActionListener(w);
+ add(item = new JMenuItem("Clear Breakpoint"));
+ item.addActionListener(w);
+ add(item = new JMenuItem("Run"));
+ item.addActionListener(w);
+ }
+
+ /**
+ * Displays the menu at the given coordinates.
+ */
+ public void show(JComponent comp, int x, int y) {
+ this.x = x;
+ this.y = y;
+ super.show(comp, x, y);
+ }
+}
+
+/**
+ * Text area to display script source.
+ */
+class FileTextArea
+ extends JTextArea
+ implements ActionListener, PopupMenuListener, KeyListener, MouseListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -25032065448563720L;
+
+ /**
+ * The owning {@link FileWindow}.
+ */
+ private FileWindow w;
+
+ /**
+ * The popup menu.
+ */
+ private FilePopupMenu popup;
+
+ /**
+ * Creates a new FileTextArea.
+ */
+ public FileTextArea(FileWindow w) {
+ this.w = w;
+ popup = new FilePopupMenu(this);
+ popup.addPopupMenuListener(this);
+ addMouseListener(this);
+ addKeyListener(this);
+ setFont(new Font("Monospaced", 0, 12));
+ }
+
+ /**
+ * Moves the selection to the given offset.
+ */
+ public void select(int pos) {
+ if (pos >= 0) {
+ try {
+ int line = getLineOfOffset(pos);
+ Rectangle rect = modelToView(pos);
+ if (rect == null) {
+ select(pos, pos);
+ } else {
+ try {
+ Rectangle nrect =
+ modelToView(getLineStartOffset(line + 1));
+ if (nrect != null) {
+ rect = nrect;
+ }
+ } catch (Exception exc) {
+ }
+ JViewport vp = (JViewport)getParent();
+ Rectangle viewRect = vp.getViewRect();
+ if (viewRect.y + viewRect.height > rect.y) {
+ // need to scroll up
+ select(pos, pos);
+ } else {
+ // need to scroll down
+ rect.y += (viewRect.height - rect.height)/2;
+ scrollRectToVisible(rect);
+ select(pos, pos);
+ }
+ }
+ } catch (BadLocationException exc) {
+ select(pos, pos);
+ //exc.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Checks if the popup menu should be shown.
+ */
+ private void checkPopup(MouseEvent e) {
+ if (e.isPopupTrigger()) {
+ popup.show(this, e.getX(), e.getY());
+ }
+ }
+
+ // MouseListener
+
+ /**
+ * Called when a mouse button is pressed.
+ */
+ public void mousePressed(MouseEvent e) {
+ checkPopup(e);
+ }
+
+ /**
+ * Called when the mouse is clicked.
+ */
+ public void mouseClicked(MouseEvent e) {
+ checkPopup(e);
+ requestFocus();
+ getCaret().setVisible(true);
+ }
+
+ /**
+ * Called when the mouse enters the component.
+ */
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ /**
+ * Called when the mouse exits the component.
+ */
+ public void mouseExited(MouseEvent e) {
+ }
+
+ /**
+ * Called when a mouse button is released.
+ */
+ public void mouseReleased(MouseEvent e) {
+ checkPopup(e);
+ }
+
+ // PopupMenuListener
+
+ /**
+ * Called before the popup menu will become visible.
+ */
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ }
+
+ /**
+ * Called before the popup menu will become invisible.
+ */
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+ }
+
+ /**
+ * Called when the popup menu is cancelled.
+ */
+ public void popupMenuCanceled(PopupMenuEvent e) {
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ int pos = viewToModel(new Point(popup.x, popup.y));
+ popup.setVisible(false);
+ String cmd = e.getActionCommand();
+ int line = -1;
+ try {
+ line = getLineOfOffset(pos);
+ } catch (Exception exc) {
+ }
+ if (cmd.equals("Set Breakpoint")) {
+ w.setBreakPoint(line + 1);
+ } else if (cmd.equals("Clear Breakpoint")) {
+ w.clearBreakPoint(line + 1);
+ } else if (cmd.equals("Run")) {
+ w.load();
+ }
+ }
+
+ // KeyListener
+
+ /**
+ * Called when a key is pressed.
+ */
+ public void keyPressed(KeyEvent e) {
+ switch (e.getKeyCode()) {
+ case KeyEvent.VK_BACK_SPACE:
+ case KeyEvent.VK_ENTER:
+ case KeyEvent.VK_DELETE:
+ case KeyEvent.VK_TAB:
+ e.consume();
+ break;
+ }
+ }
+
+ /**
+ * Called when a key is typed.
+ */
+ public void keyTyped(KeyEvent e) {
+ e.consume();
+ }
+
+ /**
+ * Called when a key is released.
+ */
+ public void keyReleased(KeyEvent e) {
+ e.consume();
+ }
+}
+
+/**
+ * Dialog to list the available windows.
+ */
+class MoreWindows extends JDialog implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 5177066296457377546L;
+
+ /**
+ * Last selected value.
+ */
+ private String value;
+
+ /**
+ * The list component.
+ */
+ private JList list;
+
+ /**
+ * Our parent frame.
+ */
+ private SwingGui swingGui;
+
+ /**
+ * The "Select" button.
+ */
+ private JButton setButton;
+
+ /**
+ * The "Cancel" button.
+ */
+ private JButton cancelButton;
+
+ /**
+ * Creates a new MoreWindows.
+ */
+ MoreWindows(SwingGui frame, Hashtable fileWindows, String title,
+ String labelText) {
+ super(frame, title, true);
+ this.swingGui = frame;
+ //buttons
+ cancelButton = new JButton("Cancel");
+ setButton = new JButton("Select");
+ cancelButton.addActionListener(this);
+ setButton.addActionListener(this);
+ getRootPane().setDefaultButton(setButton);
+
+ //dim part of the dialog
+ list = new JList(new DefaultListModel());
+ DefaultListModel model = (DefaultListModel)list.getModel();
+ model.clear();
+ //model.fireIntervalRemoved(model, 0, size);
+ Enumeration e = fileWindows.keys();
+ while (e.hasMoreElements()) {
+ String data = e.nextElement().toString();
+ model.addElement(data);
+ }
+ list.setSelectedIndex(0);
+ //model.fireIntervalAdded(model, 0, data.length);
+ setButton.setEnabled(true);
+ list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ list.addMouseListener(new MouseHandler());
+ JScrollPane listScroller = new JScrollPane(list);
+ listScroller.setPreferredSize(new Dimension(320, 240));
+ //XXX: Must do the following, too, or else the scroller thinks
+ //XXX: it's taller than it is:
+ listScroller.setMinimumSize(new Dimension(250, 80));
+ listScroller.setAlignmentX(LEFT_ALIGNMENT);
+
+ //Create a container so that we can add a title around
+ //the scroll pane. Can't add a title directly to the
+ //scroll pane because its background would be white.
+ //Lay out the label and scroll pane from top to button.
+ JPanel listPane = new JPanel();
+ listPane.setLayout(new BoxLayout(listPane, BoxLayout.Y_AXIS));
+ JLabel label = new JLabel(labelText);
+ label.setLabelFor (list);
+ listPane.add(label);
+ listPane.add(Box.createRigidArea(new Dimension(0,5)));
+ listPane.add(listScroller);
+ listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //Lay out the buttons from left to right.
+ JPanel buttonPane = new JPanel();
+ buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
+ buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
+ buttonPane.add(Box.createHorizontalGlue());
+ buttonPane.add(cancelButton);
+ buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
+ buttonPane.add(setButton);
+
+ //Put everything together, using the content pane's BorderLayout.
+ Container contentPane = getContentPane();
+ contentPane.add(listPane, BorderLayout.CENTER);
+ contentPane.add(buttonPane, BorderLayout.SOUTH);
+ pack();
+ addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent ke) {
+ int code = ke.getKeyCode();
+ if (code == KeyEvent.VK_ESCAPE) {
+ ke.consume();
+ value = null;
+ setVisible(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * Shows the dialog.
+ */
+ public String showDialog(Component comp) {
+ value = null;
+ setLocationRelativeTo(comp);
+ setVisible(true);
+ return value;
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cancel")) {
+ setVisible(false);
+ value = null;
+ } else if (cmd.equals("Select")) {
+ value = (String)list.getSelectedValue();
+ setVisible(false);
+ swingGui.showFileWindow(value, -1);
+ }
+ }
+
+ /**
+ * MouseListener implementation for {@link #list}.
+ */
+ private class MouseHandler extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ setButton.doClick();
+ }
+ }
+ }
+}
+
+/**
+ * Find function dialog.
+ */
+class FindFunction extends JDialog implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 559491015232880916L;
+
+ /**
+ * Last selected function.
+ */
+ private String value;
+
+ /**
+ * List of functions.
+ */
+ private JList list;
+
+ /**
+ * The debug GUI frame.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * The "Select" button.
+ */
+ private JButton setButton;
+
+ /**
+ * The "Cancel" button.
+ */
+ private JButton cancelButton;
+
+ /**
+ * Creates a new FindFunction.
+ */
+ public FindFunction(SwingGui debugGui, String title, String labelText) {
+ super(debugGui, title, true);
+ this.debugGui = debugGui;
+
+ cancelButton = new JButton("Cancel");
+ setButton = new JButton("Select");
+ cancelButton.addActionListener(this);
+ setButton.addActionListener(this);
+ getRootPane().setDefaultButton(setButton);
+
+ list = new JList(new DefaultListModel());
+ DefaultListModel model = (DefaultListModel)list.getModel();
+ model.clear();
+
+ String[] a = debugGui.dim.functionNames();
+ java.util.Arrays.sort(a);
+ for (int i = 0; i < a.length; i++) {
+ model.addElement(a[i]);
+ }
+ list.setSelectedIndex(0);
+
+ setButton.setEnabled(a.length > 0);
+ list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+ list.addMouseListener(new MouseHandler());
+ JScrollPane listScroller = new JScrollPane(list);
+ listScroller.setPreferredSize(new Dimension(320, 240));
+ listScroller.setMinimumSize(new Dimension(250, 80));
+ listScroller.setAlignmentX(LEFT_ALIGNMENT);
+
+ //Create a container so that we can add a title around
+ //the scroll pane. Can't add a title directly to the
+ //scroll pane because its background would be white.
+ //Lay out the label and scroll pane from top to button.
+ JPanel listPane = new JPanel();
+ listPane.setLayout(new BoxLayout(listPane, BoxLayout.Y_AXIS));
+ JLabel label = new JLabel(labelText);
+ label.setLabelFor (list);
+ listPane.add(label);
+ listPane.add(Box.createRigidArea(new Dimension(0,5)));
+ listPane.add(listScroller);
+ listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+ //Lay out the buttons from left to right.
+ JPanel buttonPane = new JPanel();
+ buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
+ buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
+ buttonPane.add(Box.createHorizontalGlue());
+ buttonPane.add(cancelButton);
+ buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
+ buttonPane.add(setButton);
+
+ //Put everything together, using the content pane's BorderLayout.
+ Container contentPane = getContentPane();
+ contentPane.add(listPane, BorderLayout.CENTER);
+ contentPane.add(buttonPane, BorderLayout.SOUTH);
+ pack();
+ addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent ke) {
+ int code = ke.getKeyCode();
+ if (code == KeyEvent.VK_ESCAPE) {
+ ke.consume();
+ value = null;
+ setVisible(false);
+ }
+ }
+ });
+ }
+
+ /**
+ * Shows the dialog.
+ */
+ public String showDialog(Component comp) {
+ value = null;
+ setLocationRelativeTo(comp);
+ setVisible(true);
+ return value;
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cancel")) {
+ setVisible(false);
+ value = null;
+ } else if (cmd.equals("Select")) {
+ if (list.getSelectedIndex() < 0) {
+ return;
+ }
+ try {
+ value = (String)list.getSelectedValue();
+ } catch (ArrayIndexOutOfBoundsException exc) {
+ return;
+ }
+ setVisible(false);
+ Dim.FunctionSource item = debugGui.dim.functionSourceByName(value);
+ if (item != null) {
+ Dim.SourceInfo si = item.sourceInfo();
+ String url = si.url();
+ int lineNumber = item.firstLine();
+ debugGui.showFileWindow(url, lineNumber);
+ }
+ }
+ }
+
+ /**
+ * MouseListener implementation for {@link #list}.
+ */
+ class MouseHandler extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ setButton.doClick();
+ }
+ }
+ }
+}
+
+/**
+ * Gutter for FileWindows.
+ */
+class FileHeader extends JPanel implements MouseListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -2858905404778259127L;
+
+ /**
+ * The line that the mouse was pressed on.
+ */
+ private int pressLine = -1;
+
+ /**
+ * The owning FileWindow.
+ */
+ private FileWindow fileWindow;
+
+ /**
+ * Creates a new FileHeader.
+ */
+ public FileHeader(FileWindow fileWindow) {
+ this.fileWindow = fileWindow;
+ addMouseListener(this);
+ update();
+ }
+
+ /**
+ * Updates the gutter.
+ */
+ public void update() {
+ FileTextArea textArea = fileWindow.textArea;
+ Font font = textArea.getFont();
+ setFont(font);
+ FontMetrics metrics = getFontMetrics(font);
+ int h = metrics.getHeight();
+ int lineCount = textArea.getLineCount() + 1;
+ String dummy = Integer.toString(lineCount);
+ if (dummy.length() < 2) {
+ dummy = "99";
+ }
+ Dimension d = new Dimension();
+ d.width = metrics.stringWidth(dummy) + 16;
+ d.height = lineCount * h + 100;
+ setPreferredSize(d);
+ setSize(d);
+ }
+
+ /**
+ * Paints the component.
+ */
+ public void paint(Graphics g) {
+ super.paint(g);
+ FileTextArea textArea = fileWindow.textArea;
+ Font font = textArea.getFont();
+ g.setFont(font);
+ FontMetrics metrics = getFontMetrics(font);
+ Rectangle clip = g.getClipBounds();
+ g.setColor(getBackground());
+ g.fillRect(clip.x, clip.y, clip.width, clip.height);
+ int ascent = metrics.getMaxAscent();
+ int h = metrics.getHeight();
+ int lineCount = textArea.getLineCount() + 1;
+ String dummy = Integer.toString(lineCount);
+ if (dummy.length() < 2) {
+ dummy = "99";
+ }
+ int startLine = clip.y / h;
+ int endLine = (clip.y + clip.height) / h + 1;
+ int width = getWidth();
+ if (endLine > lineCount) endLine = lineCount;
+ for (int i = startLine; i < endLine; i++) {
+ String text;
+ int pos = -2;
+ try {
+ pos = textArea.getLineStartOffset(i);
+ } catch (BadLocationException ignored) {
+ }
+ boolean isBreakPoint = fileWindow.isBreakPoint(i + 1);
+ text = Integer.toString(i + 1) + " ";
+ int y = i * h;
+ g.setColor(Color.blue);
+ g.drawString(text, 0, y + ascent);
+ int x = width - ascent;
+ if (isBreakPoint) {
+ g.setColor(new Color(0x80, 0x00, 0x00));
+ int dy = y + ascent - 9;
+ g.fillOval(x, dy, 9, 9);
+ g.drawOval(x, dy, 8, 8);
+ g.drawOval(x, dy, 9, 9);
+ }
+ if (pos == fileWindow.currentPos) {
+ Polygon arrow = new Polygon();
+ int dx = x;
+ y += ascent - 10;
+ int dy = y;
+ arrow.addPoint(dx, dy + 3);
+ arrow.addPoint(dx + 5, dy + 3);
+ for (x = dx + 5; x <= dx + 10; x++, y++) {
+ arrow.addPoint(x, y);
+ }
+ for (x = dx + 9; x >= dx + 5; x--, y++) {
+ arrow.addPoint(x, y);
+ }
+ arrow.addPoint(dx + 5, dy + 7);
+ arrow.addPoint(dx, dy + 7);
+ g.setColor(Color.yellow);
+ g.fillPolygon(arrow);
+ g.setColor(Color.black);
+ g.drawPolygon(arrow);
+ }
+ }
+ }
+
+ // MouseListener
+
+ /**
+ * Called when the mouse enters the component.
+ */
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ /**
+ * Called when a mouse button is pressed.
+ */
+ public void mousePressed(MouseEvent e) {
+ Font font = fileWindow.textArea.getFont();
+ FontMetrics metrics = getFontMetrics(font);
+ int h = metrics.getHeight();
+ pressLine = e.getY() / h;
+ }
+
+ /**
+ * Called when the mouse is clicked.
+ */
+ public void mouseClicked(MouseEvent e) {
+ }
+
+ /**
+ * Called when the mouse exits the component.
+ */
+ public void mouseExited(MouseEvent e) {
+ }
+
+ /**
+ * Called when a mouse button is released.
+ */
+ public void mouseReleased(MouseEvent e) {
+ if (e.getComponent() == this
+ && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
+ int y = e.getY();
+ Font font = fileWindow.textArea.getFont();
+ FontMetrics metrics = getFontMetrics(font);
+ int h = metrics.getHeight();
+ int line = y/h;
+ if (line == pressLine) {
+ fileWindow.toggleBreakPoint(line + 1);
+ } else {
+ pressLine = -1;
+ }
+ }
+ }
+}
+
+/**
+ * An internal frame for script files.
+ */
+class FileWindow extends JInternalFrame implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = -6212382604952082370L;
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * The SourceInfo object that describes the file.
+ */
+ private Dim.SourceInfo sourceInfo;
+
+ /**
+ * The FileTextArea that displays the file.
+ */
+ FileTextArea textArea;
+
+ /**
+ * The FileHeader that is the gutter for {@link #textArea}.
+ */
+ private FileHeader fileHeader;
+
+ /**
+ * Scroll pane for containing {@link #textArea}.
+ */
+ private JScrollPane p;
+
+ /**
+ * The current offset position.
+ */
+ int currentPos;
+
+ /**
+ * Loads the file.
+ */
+ void load() {
+ String url = getUrl();
+ if (url != null) {
+ RunProxy proxy = new RunProxy(debugGui, RunProxy.LOAD_FILE);
+ proxy.fileName = url;
+ proxy.text = sourceInfo.source();
+ new Thread(proxy).start();
+ }
+ }
+
+ /**
+ * Returns the offset position for the given line.
+ */
+ public int getPosition(int line) {
+ int result = -1;
+ try {
+ result = textArea.getLineStartOffset(line);
+ } catch (javax.swing.text.BadLocationException exc) {
+ }
+ return result;
+ }
+
+ /**
+ * Returns whether the given line has a breakpoint.
+ */
+ public boolean isBreakPoint(int line) {
+ return sourceInfo.breakableLine(line) && sourceInfo.breakpoint(line);
+ }
+
+ /**
+ * Toggles the breakpoint on the given line.
+ */
+ public void toggleBreakPoint(int line) {
+ if (!isBreakPoint(line)) {
+ setBreakPoint(line);
+ } else {
+ clearBreakPoint(line);
+ }
+ }
+
+ /**
+ * Sets a breakpoint on the given line.
+ */
+ public void setBreakPoint(int line) {
+ if (sourceInfo.breakableLine(line)) {
+ boolean changed = sourceInfo.breakpoint(line, true);
+ if (changed) {
+ fileHeader.repaint();
+ }
+ }
+ }
+
+ /**
+ * Clears a breakpoint from the given line.
+ */
+ public void clearBreakPoint(int line) {
+ if (sourceInfo.breakableLine(line)) {
+ boolean changed = sourceInfo.breakpoint(line, false);
+ if (changed) {
+ fileHeader.repaint();
+ }
+ }
+ }
+
+ /**
+ * Creates a new FileWindow.
+ */
+ public FileWindow(SwingGui debugGui, Dim.SourceInfo sourceInfo) {
+ super(SwingGui.getShortName(sourceInfo.url()),
+ true, true, true, true);
+ this.debugGui = debugGui;
+ this.sourceInfo = sourceInfo;
+ updateToolTip();
+ currentPos = -1;
+ textArea = new FileTextArea(this);
+ textArea.setRows(24);
+ textArea.setColumns(80);
+ p = new JScrollPane();
+ fileHeader = new FileHeader(this);
+ p.setViewportView(textArea);
+ p.setRowHeaderView(fileHeader);
+ setContentPane(p);
+ pack();
+ updateText(sourceInfo);
+ textArea.select(0);
+ }
+
+ /**
+ * Updates the tool tip contents.
+ */
+ private void updateToolTip() {
+ // Try to set tool tip on frame. On Mac OS X 10.5,
+ // the number of components is different, so try to be safe.
+ int n = getComponentCount() - 1;
+ if (n > 1) {
+ n = 1;
+ } else if (n < 0) {
+ return;
+ }
+ Component c = getComponent(n);
+ // this will work at least for Metal L&F
+ if (c != null && c instanceof JComponent) {
+ ((JComponent)c).setToolTipText(getUrl());
+ }
+ }
+
+ /**
+ * Returns the URL of the source.
+ */
+ public String getUrl() {
+ return sourceInfo.url();
+ }
+
+ /**
+ * Called when the text of the script has changed.
+ */
+ public void updateText(Dim.SourceInfo sourceInfo) {
+ this.sourceInfo = sourceInfo;
+ String newText = sourceInfo.source();
+ if (!textArea.getText().equals(newText)) {
+ textArea.setText(newText);
+ int pos = 0;
+ if (currentPos != -1) {
+ pos = currentPos;
+ }
+ textArea.select(pos);
+ }
+ fileHeader.update();
+ fileHeader.repaint();
+ }
+
+ /**
+ * Sets the cursor position.
+ */
+ public void setPosition(int pos) {
+ textArea.select(pos);
+ currentPos = pos;
+ fileHeader.repaint();
+ }
+
+ /**
+ * Selects a range of characters.
+ */
+ public void select(int start, int end) {
+ int docEnd = textArea.getDocument().getLength();
+ textArea.select(docEnd, docEnd);
+ textArea.select(start, end);
+ }
+
+ /**
+ * Disposes this FileWindow.
+ */
+ public void dispose() {
+ debugGui.removeWindow(this);
+ super.dispose();
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ if (cmd.equals("Cut")) {
+ // textArea.cut();
+ } else if (cmd.equals("Copy")) {
+ textArea.copy();
+ } else if (cmd.equals("Paste")) {
+ // textArea.paste();
+ }
+ }
+}
+
+/**
+ * Table model class for watched expressions.
+ */
+class MyTableModel extends AbstractTableModel {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 2971618907207577000L;
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * Vector of watched expressions.
+ */
+ private Vector expressions;
+
+ /**
+ * Vector of values from evaluated from {@link #expressions}.
+ */
+ private Vector values;
+
+ /**
+ * Creates a new MyTableModel.
+ */
+ public MyTableModel(SwingGui debugGui) {
+ this.debugGui = debugGui;
+ expressions = new Vector();
+ values = new Vector();
+ expressions.addElement("");
+ values.addElement("");
+ }
+
+ /**
+ * Returns the number of columns in the table (2).
+ */
+ public int getColumnCount() {
+ return 2;
+ }
+
+ /**
+ * Returns the number of rows in the table.
+ */
+ public int getRowCount() {
+ return expressions.size();
+ }
+
+ /**
+ * Returns the name of the given column.
+ */
+ public String getColumnName(int column) {
+ switch (column) {
+ case 0:
+ return "Expression";
+ case 1:
+ return "Value";
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether the given cell is editable.
+ */
+ public boolean isCellEditable(int row, int column) {
+ return true;
+ }
+
+ /**
+ * Returns the value in the given cell.
+ */
+ public Object getValueAt(int row, int column) {
+ switch (column) {
+ case 0:
+ return expressions.elementAt(row);
+ case 1:
+ return values.elementAt(row);
+ }
+ return "";
+ }
+
+ /**
+ * Sets the value in the given cell.
+ */
+ public void setValueAt(Object value, int row, int column) {
+ switch (column) {
+ case 0:
+ String expr = value.toString();
+ expressions.setElementAt(expr, row);
+ String result = "";
+ if (expr.length() > 0) {
+ result = debugGui.dim.eval(expr);
+ if (result == null) result = "";
+ }
+ values.setElementAt(result, row);
+ updateModel();
+ if (row + 1 == expressions.size()) {
+ expressions.addElement("");
+ values.addElement("");
+ fireTableRowsInserted(row + 1, row + 1);
+ }
+ break;
+ case 1:
+ // just reset column 2; ignore edits
+ fireTableDataChanged();
+ }
+ }
+
+ /**
+ * Re-evaluates the expressions in the table.
+ */
+ void updateModel() {
+ for (int i = 0; i < expressions.size(); ++i) {
+ Object value = expressions.elementAt(i);
+ String expr = value.toString();
+ String result = "";
+ if (expr.length() > 0) {
+ result = debugGui.dim.eval(expr);
+ if (result == null) result = "";
+ } else {
+ result = "";
+ }
+ result = result.replace('\n', ' ');
+ values.setElementAt(result, i);
+ }
+ fireTableDataChanged();
+ }
+}
+
+/**
+ * A table for evaluated expressions.
+ */
+class Evaluator extends JTable {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 8133672432982594256L;
+
+ /**
+ * The {@link TableModel} for this table.
+ */
+ MyTableModel tableModel;
+
+ /**
+ * Creates a new Evaluator.
+ */
+ public Evaluator(SwingGui debugGui) {
+ super(new MyTableModel(debugGui));
+ tableModel = (MyTableModel)getModel();
+ }
+}
+
+/**
+ * Tree model for script object inspection.
+ */
+class VariableModel implements TreeTableModel {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final String[] cNames = { " Name", " Value" };
+
+ /**
+ * Tree column types.
+ */
+ private static final Class[] cTypes =
+ { TreeTableModel.class, String.class };
+
+ /**
+ * Empty {@link VariableNode} array.
+ */
+ private static final VariableNode[] CHILDLESS = new VariableNode[0];
+
+ /**
+ * The debugger.
+ */
+ private Dim debugger;
+
+ /**
+ * The root node.
+ */
+ private VariableNode root;
+
+ /**
+ * Creates a new VariableModel.
+ */
+ public VariableModel() {
+ }
+
+ /**
+ * Creates a new VariableModel.
+ */
+ public VariableModel(Dim debugger, Object scope) {
+ this.debugger = debugger;
+ this.root = new VariableNode(scope, "this");
+ }
+
+ // TreeTableModel
+
+ /**
+ * Returns the root node of the tree.
+ */
+ public Object getRoot() {
+ if (debugger == null) {
+ return null;
+ }
+ return root;
+ }
+
+ /**
+ * Returns the number of children of the given node.
+ */
+ public int getChildCount(Object nodeObj) {
+ if (debugger == null) {
+ return 0;
+ }
+ VariableNode node = (VariableNode) nodeObj;
+ return children(node).length;
+ }
+
+ /**
+ * Returns a child of the given node.
+ */
+ public Object getChild(Object nodeObj, int i) {
+ if (debugger == null) {
+ return null;
+ }
+ VariableNode node = (VariableNode) nodeObj;
+ return children(node)[i];
+ }
+
+ /**
+ * Returns whether the given node is a leaf node.
+ */
+ public boolean isLeaf(Object nodeObj) {
+ if (debugger == null) {
+ return true;
+ }
+ VariableNode node = (VariableNode) nodeObj;
+ return children(node).length == 0;
+ }
+
+ /**
+ * Returns the index of a node under its parent.
+ */
+ public int getIndexOfChild(Object parentObj, Object childObj) {
+ if (debugger == null) {
+ return -1;
+ }
+ VariableNode parent = (VariableNode) parentObj;
+ VariableNode child = (VariableNode) childObj;
+ VariableNode[] children = children(parent);
+ for (int i = 0; i != children.length; i++) {
+ if (children[i] == child) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns whether the given cell is editable.
+ */
+ public boolean isCellEditable(Object node, int column) {
+ return column == 0;
+ }
+
+ /**
+ * Sets the value at the given cell.
+ */
+ public void setValueAt(Object value, Object node, int column) { }
+
+ /**
+ * Adds a TreeModelListener to this tree.
+ */
+ public void addTreeModelListener(TreeModelListener l) { }
+
+ /**
+ * Removes a TreeModelListener from this tree.
+ */
+ public void removeTreeModelListener(TreeModelListener l) { }
+
+ public void valueForPathChanged(TreePath path, Object newValue) { }
+
+ // TreeTableNode
+
+ /**
+ * Returns the number of columns.
+ */
+ public int getColumnCount() {
+ return cNames.length;
+ }
+
+ /**
+ * Returns the name of the given column.
+ */
+ public String getColumnName(int column) {
+ return cNames[column];
+ }
+
+ /**
+ * Returns the type of value stored in the given column.
+ */
+ public Class getColumnClass(int column) {
+ return cTypes[column];
+ }
+
+ /**
+ * Returns the value at the given cell.
+ */
+ public Object getValueAt(Object nodeObj, int column) {
+ if (debugger == null) { return null; }
+ VariableNode node = (VariableNode)nodeObj;
+ switch (column) {
+ case 0: // Name
+ return node.toString();
+ case 1: // Value
+ String result;
+ try {
+ result = debugger.objectToString(getValue(node));
+ } catch (RuntimeException exc) {
+ result = exc.getMessage();
+ }
+ StringBuffer buf = new StringBuffer();
+ int len = result.length();
+ for (int i = 0; i < len; i++) {
+ char ch = result.charAt(i);
+ if (Character.isISOControl(ch)) {
+ ch = ' ';
+ }
+ buf.append(ch);
+ }
+ return buf.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Returns an array of the children of the given node.
+ */
+ private VariableNode[] children(VariableNode node) {
+ if (node.children != null) {
+ return node.children;
+ }
+
+ VariableNode[] children;
+
+ Object value = getValue(node);
+ Object[] ids = debugger.getObjectIds(value);
+ if (ids == null || ids.length == 0) {
+ children = CHILDLESS;
+ } else {
+ Arrays.sort(ids, new Comparator() {
+ public int compare(Object l, Object r)
+ {
+ if (l instanceof String) {
+ if (r instanceof Integer) {
+ return -1;
+ }
+ return ((String)l).compareToIgnoreCase((String)r);
+ } else {
+ if (r instanceof String) {
+ return 1;
+ }
+ int lint = ((Integer)l).intValue();
+ int rint = ((Integer)r).intValue();
+ return lint - rint;
+ }
+ }
+ });
+ children = new VariableNode[ids.length];
+ for (int i = 0; i != ids.length; ++i) {
+ children[i] = new VariableNode(value, ids[i]);
+ }
+ }
+ node.children = children;
+ return children;
+ }
+
+ /**
+ * Returns the value of the given node.
+ */
+ public Object getValue(VariableNode node) {
+ try {
+ return debugger.getObjectProperty(node.object, node.id);
+ } catch (Exception exc) {
+ return "undefined";
+ }
+ }
+
+ /**
+ * A variable node in the tree.
+ */
+ private static class VariableNode {
+
+ /**
+ * The script object.
+ */
+ private Object object;
+
+ /**
+ * The object name. Either a String or an Integer.
+ */
+ private Object id;
+
+ /**
+ * Array of child nodes. This is filled with the properties of
+ * the object.
+ */
+ private VariableNode[] children;
+
+ /**
+ * Creates a new VariableNode.
+ */
+ public VariableNode(Object object, Object id) {
+ this.object = object;
+ this.id = id;
+ }
+
+ /**
+ * Returns a string representation of this node.
+ */
+ public String toString() {
+ return id instanceof String
+ ? (String) id : "[" + ((Integer) id).intValue() + "]";
+ }
+ }
+}
+
+/**
+ * A tree table for browsing script objects.
+ */
+class MyTreeTable extends JTreeTable {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 3457265548184453049L;
+
+ /**
+ * Creates a new MyTreeTable.
+ */
+ public MyTreeTable(VariableModel model) {
+ super(model);
+ }
+
+ /**
+ * Initializes a tree for this tree table.
+ */
+ public JTree resetTree(TreeTableModel treeTableModel) {
+ tree = new TreeTableCellRenderer(treeTableModel);
+
+ // Install a tableModel representing the visible rows in the tree.
+ super.setModel(new TreeTableModelAdapter(treeTableModel, tree));
+
+ // Force the JTable and JTree to share their row selection models.
+ ListToTreeSelectionModelWrapper selectionWrapper = new
+ ListToTreeSelectionModelWrapper();
+ tree.setSelectionModel(selectionWrapper);
+ setSelectionModel(selectionWrapper.getListSelectionModel());
+
+ // Make the tree and table row heights the same.
+ if (tree.getRowHeight() < 1) {
+ // Metal looks better like this.
+ setRowHeight(18);
+ }
+
+ // Install the tree editor renderer and editor.
+ setDefaultRenderer(TreeTableModel.class, tree);
+ setDefaultEditor(TreeTableModel.class, new TreeTableCellEditor());
+ setShowGrid(true);
+ setIntercellSpacing(new Dimension(1,1));
+ tree.setRootVisible(false);
+ tree.setShowsRootHandles(true);
+ DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)tree.getCellRenderer();
+ r.setOpenIcon(null);
+ r.setClosedIcon(null);
+ r.setLeafIcon(null);
+ return tree;
+ }
+
+ /**
+ * Returns whether the cell under the coordinates of the mouse
+ * in the {@link EventObject} is editable.
+ */
+ public boolean isCellEditable(EventObject e) {
+ if (e instanceof MouseEvent) {
+ MouseEvent me = (MouseEvent)e;
+ // If the modifiers are not 0 (or the left mouse button),
+ // tree may try and toggle the selection, and table
+ // will then try and toggle, resulting in the
+ // selection remaining the same. To avoid this, we
+ // only dispatch when the modifiers are 0 (or the left mouse
+ // button).
+ if (me.getModifiers() == 0 ||
+ ((me.getModifiers() & (InputEvent.BUTTON1_MASK|1024)) != 0 &&
+ (me.getModifiers() &
+ (InputEvent.SHIFT_MASK |
+ InputEvent.CTRL_MASK |
+ InputEvent.ALT_MASK |
+ InputEvent.BUTTON2_MASK |
+ InputEvent.BUTTON3_MASK |
+ 64 | //SHIFT_DOWN_MASK
+ 128 | //CTRL_DOWN_MASK
+ 512 | // ALT_DOWN_MASK
+ 2048 | //BUTTON2_DOWN_MASK
+ 4096 //BUTTON3_DOWN_MASK
+ )) == 0)) {
+ int row = rowAtPoint(me.getPoint());
+ for (int counter = getColumnCount() - 1; counter >= 0;
+ counter--) {
+ if (TreeTableModel.class == getColumnClass(counter)) {
+ MouseEvent newME = new MouseEvent
+ (MyTreeTable.this.tree, me.getID(),
+ me.getWhen(), me.getModifiers(),
+ me.getX() - getCellRect(row, counter, true).x,
+ me.getY(), me.getClickCount(),
+ me.isPopupTrigger());
+ MyTreeTable.this.tree.dispatchEvent(newME);
+ break;
+ }
+ }
+ }
+ if (me.getClickCount() >= 3) {
+ return true;
+ }
+ return false;
+ }
+ if (e == null) {
+ return true;
+ }
+ return false;
+ }
+}
+
+/**
+ * Panel that shows information about the context.
+ */
+class ContextWindow extends JPanel implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 2306040975490228051L;
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * The combo box that holds the stack frames.
+ */
+ JComboBox context;
+
+ /**
+ * Tool tips for the stack frames.
+ */
+ Vector toolTips;
+
+ /**
+ * Tabbed pane for "this" and "locals".
+ */
+ private JTabbedPane tabs;
+
+ /**
+ * Tabbed pane for "watch" and "evaluate".
+ */
+ private JTabbedPane tabs2;
+
+ /**
+ * The table showing the "this" object.
+ */
+ private MyTreeTable thisTable;
+
+ /**
+ * The table showing the stack local variables.
+ */
+ private MyTreeTable localsTable;
+
+ /**
+ * The {@link #evaluator}'s table model.
+ */
+ private MyTableModel tableModel;
+
+ /**
+ * The script evaluator table.
+ */
+ private Evaluator evaluator;
+
+ /**
+ * The script evaluation text area.
+ */
+ private EvalTextArea cmdLine;
+
+ /**
+ * The split pane.
+ */
+ JSplitPane split;
+
+ /**
+ * Whether the ContextWindow is enabled.
+ */
+ private boolean enabled;
+
+ /**
+ * Creates a new ContextWindow.
+ */
+ public ContextWindow(final SwingGui debugGui) {
+ this.debugGui = debugGui;
+ enabled = false;
+ JPanel left = new JPanel();
+ JToolBar t1 = new JToolBar();
+ t1.setName("Variables");
+ t1.setLayout(new GridLayout());
+ t1.add(left);
+ JPanel p1 = new JPanel();
+ p1.setLayout(new GridLayout());
+ JPanel p2 = new JPanel();
+ p2.setLayout(new GridLayout());
+ p1.add(t1);
+ JLabel label = new JLabel("Context:");
+ context = new JComboBox();
+ context.setLightWeightPopupEnabled(false);
+ toolTips = new java.util.Vector();
+ label.setBorder(context.getBorder());
+ context.addActionListener(this);
+ context.setActionCommand("ContextSwitch");
+ GridBagLayout layout = new GridBagLayout();
+ left.setLayout(layout);
+ GridBagConstraints lc = new GridBagConstraints();
+ lc.insets.left = 5;
+ lc.anchor = GridBagConstraints.WEST;
+ lc.ipadx = 5;
+ layout.setConstraints(label, lc);
+ left.add(label);
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.anchor = GridBagConstraints.WEST;
+ layout.setConstraints(context, c);
+ left.add(context);
+ tabs = new JTabbedPane(SwingConstants.BOTTOM);
+ tabs.setPreferredSize(new Dimension(500,300));
+ thisTable = new MyTreeTable(new VariableModel());
+ JScrollPane jsp = new JScrollPane(thisTable);
+ jsp.getViewport().setViewSize(new Dimension(5,2));
+ tabs.add("this", jsp);
+ localsTable = new MyTreeTable(new VariableModel());
+ localsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ localsTable.setPreferredSize(null);
+ jsp = new JScrollPane(localsTable);
+ tabs.add("Locals", jsp);
+ c.weightx = c.weighty = 1;
+ c.gridheight = GridBagConstraints.REMAINDER;
+ c.fill = GridBagConstraints.BOTH;
+ c.anchor = GridBagConstraints.WEST;
+ layout.setConstraints(tabs, c);
+ left.add(tabs);
+ evaluator = new Evaluator(debugGui);
+ cmdLine = new EvalTextArea(debugGui);
+ //cmdLine.requestFocus();
+ tableModel = evaluator.tableModel;
+ jsp = new JScrollPane(evaluator);
+ JToolBar t2 = new JToolBar();
+ t2.setName("Evaluate");
+ tabs2 = new JTabbedPane(SwingConstants.BOTTOM);
+ tabs2.add("Watch", jsp);
+ tabs2.add("Evaluate", new JScrollPane(cmdLine));
+ tabs2.setPreferredSize(new Dimension(500,300));
+ t2.setLayout(new GridLayout());
+ t2.add(tabs2);
+ p2.add(t2);
+ evaluator.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+ p1, p2);
+ split.setOneTouchExpandable(true);
+ SwingGui.setResizeWeight(split, 0.5);
+ setLayout(new BorderLayout());
+ add(split, BorderLayout.CENTER);
+
+ final JToolBar finalT1 = t1;
+ final JToolBar finalT2 = t2;
+ final JPanel finalP1 = p1;
+ final JPanel finalP2 = p2;
+ final JSplitPane finalSplit = split;
+ final JPanel finalThis = this;
+
+ ComponentListener clistener = new ComponentListener() {
+ boolean t2Docked = true;
+ void check(Component comp) {
+ Component thisParent = finalThis.getParent();
+ if (thisParent == null) {
+ return;
+ }
+ Component parent = finalT1.getParent();
+ boolean leftDocked = true;
+ boolean rightDocked = true;
+ boolean adjustVerticalSplit = false;
+ if (parent != null) {
+ if (parent != finalP1) {
+ while (!(parent instanceof JFrame)) {
+ parent = parent.getParent();
+ }
+ JFrame frame = (JFrame)parent;
+ debugGui.addTopLevel("Variables", frame);
+
+ // We need the following hacks because:
+ // - We want an undocked toolbar to be
+ // resizable.
+ // - We are using JToolbar as a container of a
+ // JComboBox. Without this JComboBox's popup
+ // can get left floating when the toolbar is
+ // re-docked.
+ //
+ // We make the frame resizable and then
+ // remove JToolbar's window listener
+ // and insert one of our own that first ensures
+ // the JComboBox's popup window is closed
+ // and then calls JToolbar's window listener.
+ if (!frame.isResizable()) {
+ frame.setResizable(true);
+ frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ final EventListener[] l =
+ frame.getListeners(WindowListener.class);
+ frame.removeWindowListener((WindowListener)l[0]);
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ context.hidePopup();
+ ((WindowListener)l[0]).windowClosing(e);
+ }
+ });
+ //adjustVerticalSplit = true;
+ }
+ leftDocked = false;
+ } else {
+ leftDocked = true;
+ }
+ }
+ parent = finalT2.getParent();
+ if (parent != null) {
+ if (parent != finalP2) {
+ while (!(parent instanceof JFrame)) {
+ parent = parent.getParent();
+ }
+ JFrame frame = (JFrame)parent;
+ debugGui.addTopLevel("Evaluate", frame);
+ frame.setResizable(true);
+ rightDocked = false;
+ } else {
+ rightDocked = true;
+ }
+ }
+ if (leftDocked && t2Docked && rightDocked && t2Docked) {
+ // no change
+ return;
+ }
+ t2Docked = rightDocked;
+ JSplitPane split = (JSplitPane)thisParent;
+ if (leftDocked) {
+ if (rightDocked) {
+ finalSplit.setDividerLocation(0.5);
+ } else {
+ finalSplit.setDividerLocation(1.0);
+ }
+ if (adjustVerticalSplit) {
+ split.setDividerLocation(0.66);
+ }
+
+ } else if (rightDocked) {
+ finalSplit.setDividerLocation(0.0);
+ split.setDividerLocation(0.66);
+ } else {
+ // both undocked
+ split.setDividerLocation(1.0);
+ }
+ }
+ public void componentHidden(ComponentEvent e) {
+ check(e.getComponent());
+ }
+ public void componentMoved(ComponentEvent e) {
+ check(e.getComponent());
+ }
+ public void componentResized(ComponentEvent e) {
+ check(e.getComponent());
+ }
+ public void componentShown(ComponentEvent e) {
+ check(e.getComponent());
+ }
+ };
+ p1.addContainerListener(new ContainerListener() {
+ public void componentAdded(ContainerEvent e) {
+ Component thisParent = finalThis.getParent();
+ JSplitPane split = (JSplitPane)thisParent;
+ if (e.getChild() == finalT1) {
+ if (finalT2.getParent() == finalP2) {
+ // both docked
+ finalSplit.setDividerLocation(0.5);
+ } else {
+ // left docked only
+ finalSplit.setDividerLocation(1.0);
+ }
+ split.setDividerLocation(0.66);
+ }
+ }
+ public void componentRemoved(ContainerEvent e) {
+ Component thisParent = finalThis.getParent();
+ JSplitPane split = (JSplitPane)thisParent;
+ if (e.getChild() == finalT1) {
+ if (finalT2.getParent() == finalP2) {
+ // right docked only
+ finalSplit.setDividerLocation(0.0);
+ split.setDividerLocation(0.66);
+ } else {
+ // both undocked
+ split.setDividerLocation(1.0);
+ }
+ }
+ }
+ });
+ t1.addComponentListener(clistener);
+ t2.addComponentListener(clistener);
+ disable();
+ }
+
+ /**
+ * Disables the component.
+ */
+ public void disable() {
+ context.setEnabled(false);
+ thisTable.setEnabled(false);
+ localsTable.setEnabled(false);
+ evaluator.setEnabled(false);
+ cmdLine.setEnabled(false);
+ }
+
+ /**
+ * Enables the component.
+ */
+ public void enable() {
+ context.setEnabled(true);
+ thisTable.setEnabled(true);
+ localsTable.setEnabled(true);
+ evaluator.setEnabled(true);
+ cmdLine.setEnabled(true);
+ }
+
+ /**
+ * Disables updating of the component.
+ */
+ public void disableUpdate() {
+ enabled = false;
+ }
+
+ /**
+ * Enables updating of the component.
+ */
+ public void enableUpdate() {
+ enabled = true;
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (!enabled) return;
+ if (e.getActionCommand().equals("ContextSwitch")) {
+ Dim.ContextData contextData = debugGui.dim.currentContextData();
+ if (contextData == null) { return; }
+ int frameIndex = context.getSelectedIndex();
+ context.setToolTipText(toolTips.elementAt(frameIndex).toString());
+ int frameCount = contextData.frameCount();
+ if (frameIndex >= frameCount) {
+ return;
+ }
+ Dim.StackFrame frame = contextData.getFrame(frameIndex);
+ Object scope = frame.scope();
+ Object thisObj = frame.thisObj();
+ thisTable.resetTree(new VariableModel(debugGui.dim, thisObj));
+ VariableModel scopeModel;
+ if (scope != thisObj) {
+ scopeModel = new VariableModel(debugGui.dim, scope);
+ } else {
+ scopeModel = new VariableModel();
+ }
+ localsTable.resetTree(scopeModel);
+ debugGui.dim.contextSwitch(frameIndex);
+ debugGui.showStopLine(frame);
+ tableModel.updateModel();
+ }
+ }
+}
+
+/**
+ * The debugger frame menu bar.
+ */
+class Menubar extends JMenuBar implements ActionListener {
+
+ /**
+ * Serializable magic number.
+ */
+ private static final long serialVersionUID = 3217170497245911461L;
+
+ /**
+ * Items that are enabled only when interrupted.
+ */
+ private Vector interruptOnlyItems = new Vector();
+
+ /**
+ * Items that are enabled only when running.
+ */
+ private Vector runOnlyItems = new Vector();
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * The menu listing the internal frames.
+ */
+ private JMenu windowMenu;
+
+ /**
+ * The "Break on exceptions" menu item.
+ */
+ private JCheckBoxMenuItem breakOnExceptions;
+
+ /**
+ * The "Break on enter" menu item.
+ */
+ private JCheckBoxMenuItem breakOnEnter;
+
+ /**
+ * The "Break on return" menu item.
+ */
+ private JCheckBoxMenuItem breakOnReturn;
+
+ /**
+ * Creates a new Menubar.
+ */
+ Menubar(SwingGui debugGui) {
+ super();
+ this.debugGui = debugGui;
+ String[] fileItems = {"Open...", "Run...", "", "Exit"};
+ String[] fileCmds = {"Open", "Load", "", "Exit"};
+ char[] fileShortCuts = {'0', 'N', 0, 'X'};
+ int[] fileAccelerators = {KeyEvent.VK_O,
+ KeyEvent.VK_N,
+ 0,
+ KeyEvent.VK_Q};
+ String[] editItems = {"Cut", "Copy", "Paste", "Go to function..."};
+ char[] editShortCuts = {'T', 'C', 'P', 'F'};
+ String[] debugItems = {"Break", "Go", "Step Into", "Step Over", "Step Out"};
+ char[] debugShortCuts = {'B', 'G', 'I', 'O', 'T'};
+ String[] plafItems = {"Metal", "Windows", "Motif"};
+ char [] plafShortCuts = {'M', 'W', 'F'};
+ int[] debugAccelerators = {KeyEvent.VK_PAUSE,
+ KeyEvent.VK_F5,
+ KeyEvent.VK_F11,
+ KeyEvent.VK_F7,
+ KeyEvent.VK_F8,
+ 0, 0};
+
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.setMnemonic('F');
+ JMenu editMenu = new JMenu("Edit");
+ editMenu.setMnemonic('E');
+ JMenu plafMenu = new JMenu("Platform");
+ plafMenu.setMnemonic('P');
+ JMenu debugMenu = new JMenu("Debug");
+ debugMenu.setMnemonic('D');
+ windowMenu = new JMenu("Window");
+ windowMenu.setMnemonic('W');
+ for (int i = 0; i < fileItems.length; ++i) {
+ if (fileItems[i].length() == 0) {
+ fileMenu.addSeparator();
+ } else {
+ JMenuItem item = new JMenuItem(fileItems[i],
+ fileShortCuts[i]);
+ item.setActionCommand(fileCmds[i]);
+ item.addActionListener(this);
+ fileMenu.add(item);
+ if (fileAccelerators[i] != 0) {
+ KeyStroke k = KeyStroke.getKeyStroke(fileAccelerators[i], Event.CTRL_MASK);
+ item.setAccelerator(k);
+ }
+ }
+ }
+ for (int i = 0; i < editItems.length; ++i) {
+ JMenuItem item = new JMenuItem(editItems[i],
+ editShortCuts[i]);
+ item.addActionListener(this);
+ editMenu.add(item);
+ }
+ for (int i = 0; i < plafItems.length; ++i) {
+ JMenuItem item = new JMenuItem(plafItems[i],
+ plafShortCuts[i]);
+ item.addActionListener(this);
+ plafMenu.add(item);
+ }
+ for (int i = 0; i < debugItems.length; ++i) {
+ JMenuItem item = new JMenuItem(debugItems[i],
+ debugShortCuts[i]);
+ item.addActionListener(this);
+ if (debugAccelerators[i] != 0) {
+ KeyStroke k = KeyStroke.getKeyStroke(debugAccelerators[i], 0);
+ item.setAccelerator(k);
+ }
+ if (i != 0) {
+ interruptOnlyItems.add(item);
+ } else {
+ runOnlyItems.add(item);
+ }
+ debugMenu.add(item);
+ }
+ breakOnExceptions = new JCheckBoxMenuItem("Break on Exceptions");
+ breakOnExceptions.setMnemonic('X');
+ breakOnExceptions.addActionListener(this);
+ breakOnExceptions.setSelected(false);
+ debugMenu.add(breakOnExceptions);
+
+ breakOnEnter = new JCheckBoxMenuItem("Break on Function Enter");
+ breakOnEnter.setMnemonic('E');
+ breakOnEnter.addActionListener(this);
+ breakOnEnter.setSelected(false);
+ debugMenu.add(breakOnEnter);
+
+ breakOnReturn = new JCheckBoxMenuItem("Break on Function Return");
+ breakOnReturn.setMnemonic('R');
+ breakOnReturn.addActionListener(this);
+ breakOnReturn.setSelected(false);
+ debugMenu.add(breakOnReturn);
+
+ add(fileMenu);
+ add(editMenu);
+ //add(plafMenu);
+ add(debugMenu);
+ JMenuItem item;
+ windowMenu.add(item = new JMenuItem("Cascade", 'A'));
+ item.addActionListener(this);
+ windowMenu.add(item = new JMenuItem("Tile", 'T'));
+ item.addActionListener(this);
+ windowMenu.addSeparator();
+ windowMenu.add(item = new JMenuItem("Console", 'C'));
+ item.addActionListener(this);
+ add(windowMenu);
+
+ updateEnabled(false);
+ }
+
+ /**
+ * Returns the "Break on exceptions" menu item.
+ */
+ public JCheckBoxMenuItem getBreakOnExceptions() {
+ return breakOnExceptions;
+ }
+
+ /**
+ * Returns the "Break on enter" menu item.
+ */
+ public JCheckBoxMenuItem getBreakOnEnter() {
+ return breakOnEnter;
+ }
+
+ /**
+ * Returns the "Break on return" menu item.
+ */
+ public JCheckBoxMenuItem getBreakOnReturn() {
+ return breakOnReturn;
+ }
+
+ /**
+ * Returns the "Debug" menu.
+ */
+ public JMenu getDebugMenu() {
+ return getMenu(2);
+ }
+
+ // ActionListener
+
+ /**
+ * Performs an action.
+ */
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ String plaf_name = null;
+ if (cmd.equals("Metal")) {
+ plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
+ } else if (cmd.equals("Windows")) {
+ plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
+ } else if (cmd.equals("Motif")) {
+ plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
+ } else {
+ Object source = e.getSource();
+ if (source == breakOnExceptions) {
+ debugGui.dim.setBreakOnExceptions(breakOnExceptions.isSelected());
+ } else if (source == breakOnEnter) {
+ debugGui.dim.setBreakOnEnter(breakOnEnter.isSelected());
+ } else if (source == breakOnReturn) {
+ debugGui.dim.setBreakOnReturn(breakOnReturn.isSelected());
+ } else {
+ debugGui.actionPerformed(e);
+ }
+ return;
+ }
+ try {
+ UIManager.setLookAndFeel(plaf_name);
+ SwingUtilities.updateComponentTreeUI(debugGui);
+ SwingUtilities.updateComponentTreeUI(debugGui.dlg);
+ } catch (Exception ignored) {
+ //ignored.printStackTrace();
+ }
+ }
+
+ /**
+ * Adds a file to the window menu.
+ */
+ public void addFile(String url) {
+ int count = windowMenu.getItemCount();
+ JMenuItem item;
+ if (count == 4) {
+ windowMenu.addSeparator();
+ count++;
+ }
+ JMenuItem lastItem = windowMenu.getItem(count -1);
+ boolean hasMoreWin = false;
+ int maxWin = 5;
+ if (lastItem != null &&
+ lastItem.getText().equals("More Windows...")) {
+ hasMoreWin = true;
+ maxWin++;
+ }
+ if (!hasMoreWin && count - 4 == 5) {
+ windowMenu.add(item = new JMenuItem("More Windows...", 'M'));
+ item.setActionCommand("More Windows...");
+ item.addActionListener(this);
+ return;
+ } else if (count - 4 <= maxWin) {
+ if (hasMoreWin) {
+ count--;
+ windowMenu.remove(lastItem);
+ }
+ String shortName = SwingGui.getShortName(url);
+
+ windowMenu.add(item = new JMenuItem((char)('0' + (count-4)) + " " + shortName, '0' + (count - 4)));
+ if (hasMoreWin) {
+ windowMenu.add(lastItem);
+ }
+ } else {
+ return;
+ }
+ item.setActionCommand(url);
+ item.addActionListener(this);
+ }
+
+ /**
+ * Updates the enabledness of menu items.
+ */
+ public void updateEnabled(boolean interrupted) {
+ for (int i = 0; i != interruptOnlyItems.size(); ++i) {
+ JMenuItem item = (JMenuItem)interruptOnlyItems.elementAt(i);
+ item.setEnabled(interrupted);
+ }
+
+ for (int i = 0; i != runOnlyItems.size(); ++i) {
+ JMenuItem item = (JMenuItem)runOnlyItems.elementAt(i);
+ item.setEnabled(!interrupted);
+ }
+ }
+}
+
+/**
+ * Class to consolidate all cases that require to implement Runnable
+ * to avoid class generation bloat.
+ */
+class RunProxy implements Runnable {
+
+ // Constants for 'type'.
+ static final int OPEN_FILE = 1;
+ static final int LOAD_FILE = 2;
+ static final int UPDATE_SOURCE_TEXT = 3;
+ static final int ENTER_INTERRUPT = 4;
+
+ /**
+ * The debugger GUI.
+ */
+ private SwingGui debugGui;
+
+ /**
+ * The type of Runnable this object is. Takes one of the constants
+ * defined in this class.
+ */
+ private int type;
+
+ /**
+ * The name of the file to open or load.
+ */
+ String fileName;
+
+ /**
+ * The source text to update.
+ */
+ String text;
+
+ /**
+ * The source for which to update the text.
+ */
+ Dim.SourceInfo sourceInfo;
+
+ /**
+ * The frame to interrupt in.
+ */
+ Dim.StackFrame lastFrame;
+
+ /**
+ * The name of the interrupted thread.
+ */
+ String threadTitle;
+
+ /**
+ * The message of the exception thrown that caused the thread
+ * interruption, if any.
+ */
+ String alertMessage;
+
+ /**
+ * Creates a new RunProxy.
+ */
+ public RunProxy(SwingGui debugGui, int type) {
+ this.debugGui = debugGui;
+ this.type = type;
+ }
+
+ /**
+ * Runs this Runnable.
+ */
+ public void run() {
+ switch (type) {
+ case OPEN_FILE:
+ try {
+ debugGui.dim.compileScript(fileName, text);
+ } catch (RuntimeException ex) {
+ MessageDialogWrapper.showMessageDialog(
+ debugGui, ex.getMessage(), "Error Compiling "+fileName,
+ JOptionPane.ERROR_MESSAGE);
+ }
+ break;
+
+ case LOAD_FILE:
+ try {
+ debugGui.dim.evalScript(fileName, text);
+ } catch (RuntimeException ex) {
+ MessageDialogWrapper.showMessageDialog(
+ debugGui, ex.getMessage(), "Run error for "+fileName,
+ JOptionPane.ERROR_MESSAGE);
+ }
+ break;
+
+ case UPDATE_SOURCE_TEXT:
+ {
+ String fileName = sourceInfo.url();
+ if (!debugGui.updateFileWindow(sourceInfo) &&
+ !fileName.equals("<stdin>")) {
+ debugGui.createFileWindow(sourceInfo, -1);
+ }
+ }
+ break;
+
+ case ENTER_INTERRUPT:
+ debugGui.enterInterruptImpl(lastFrame, threadTitle, alertMessage);
+ break;
+
+ default:
+ throw new IllegalArgumentException(String.valueOf(type));
+
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/build.xml b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/build.xml
new file mode 100644
index 0000000..c35fd40
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/debugger/build.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<project name="toolsrc" default="help" basedir=".">
+
+ <target name="properties">
+ <property name="swing-ex-url" value="http://java.sun.com/products/jfc/tsc/articles/treetable2/downloads/src.zip"/>
+ <available file="downloaded/AbstractCellEditor.java"
+ property="swing-ex-available"/>
+ </target>
+
+ <target name="get-swing-ex" unless="swing-ex-available">
+ <!-- Download source from Sun's site, unzip it, remove
+ the files we don't need, and change the package
+ -->
+ <mkdir dir="downloaded"/>
+ <get src="${swing-ex-url}" dest="downloaded/swingExSrc.zip"/>
+ <unzip src="downloaded/swingExSrc.zip" dest="downloaded/">
+ <patternset>
+ <include name="AbstractCellEditor.java"/>
+ <include name="JTreeTable.java"/>
+ <include name="TreeTableModel.java"/>
+ <include name="TreeTableModelAdapter.java"/>
+ </patternset>
+ </unzip>
+ <replace file="downloaded/AbstractCellEditor.java">
+ <replacetoken>import java.awt.Component;</replacetoken>
+ <replacevalue>
+package org.mozilla.javascript.tools.debugger.downloaded;
+ </replacevalue>
+ </replace>
+ <replace file="downloaded/AbstractCellEditor.java">
+ <replacetoken>import java.awt.event.*;</replacetoken>
+ <replacevalue></replacevalue>
+ </replace>
+ <replace file="downloaded/AbstractCellEditor.java">
+ <replacetoken>import java.awt.AWTEvent;</replacetoken>
+ <replacevalue></replacevalue>
+ </replace>
+ <replace file="downloaded/AbstractCellEditor.java">
+ <replacetoken>import java.io.Serializable;</replacetoken>
+ <replacevalue></replacevalue>
+ </replace>
+ <replace file="downloaded/JTreeTable.java">
+ <replacetoken>import javax.swing.*;</replacetoken>
+ <replacevalue>
+ package org.mozilla.javascript.tools.debugger.downloaded;
+ import javax.swing.*;
+ </replacevalue>
+ </replace>
+ <replace file="downloaded/JTreeTable.java">
+ <replacetoken>class ListToTreeSelectionModelWrapper</replacetoken>
+ <replacevalue>public class ListToTreeSelectionModelWrapper</replacevalue>
+ </replace>
+ <replace file="downloaded/JTreeTable.java">
+ <replacetoken>ListSelectionModel getListSelectionModel</replacetoken>
+ <replacevalue>public ListSelectionModel getListSelectionModel</replacevalue>
+ </replace>
+ <replace file="downloaded/JTreeTable.java">
+ <replacetoken>import java.awt.Rectangle;</replacetoken>
+ <replacevalue></replacevalue>
+ </replace>
+ <replace file="downloaded/TreeTableModel.java">
+ <replacetoken>import javax.swing.tree.TreeModel;</replacetoken>
+ <replacevalue>
+ package org.mozilla.javascript.tools.debugger.downloaded;
+ import javax.swing.tree.TreeModel;
+ </replacevalue>
+ </replace>
+ <replace file="downloaded/TreeTableModelAdapter.java">
+ <replacetoken>import javax.swing.JTree;</replacetoken>
+ <replacevalue>
+ package org.mozilla.javascript.tools.debugger.downloaded;
+ import javax.swing.JTree;
+ </replacevalue>
+ </replace>
+ <delete file="downloaded/swingExSrc.zip"/>
+ </target>
+
+ <target name="download" depends="properties,get-swing-ex"/>
+
+ <target name="help" depends="properties">
+<echo>The following targets are available with this build file:
+
+ download Download ${swing-ex-url}
+ and extract the necessary files from it.
+
+ help Print this help.
+
+</echo>
+ </target>
+
+</project>
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/CodePrinter.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/CodePrinter.java
new file mode 100644
index 0000000..dd4f689
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/CodePrinter.java
@@ -0,0 +1,212 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.idswitch;
+
+class CodePrinter {
+
+// length of u-type escape like \u12AB
+ private static final int LITERAL_CHAR_MAX_SIZE = 6;
+
+ private String lineTerminator = "\n";
+
+ private int indentStep = 4;
+ private int indentTabSize = 8;
+
+ private char[] buffer = new char[1 << 12]; // 4K
+ private int offset;
+
+ public String getLineTerminator() { return lineTerminator; }
+ public void setLineTerminator(String value) { lineTerminator = value; }
+
+ public int getIndentStep() { return indentStep; }
+ public void setIndentStep(int char_count) { indentStep = char_count; }
+
+ public int getIndentTabSize() { return indentTabSize; }
+ public void setIndentTabSize(int tab_size) { indentTabSize = tab_size; }
+
+ public void clear() {
+ offset = 0;
+ }
+
+ private int ensure_area(int area_size) {
+ int begin = offset;
+ int end = begin + area_size;
+ if (end > buffer.length) {
+ int new_capacity = buffer.length * 2;
+ if (end > new_capacity) { new_capacity = end; }
+ char[] tmp = new char[new_capacity];
+ System.arraycopy(buffer, 0, tmp, 0, begin);
+ buffer = tmp;
+ }
+ return begin;
+ }
+
+ private int add_area(int area_size) {
+ int pos = ensure_area(area_size);
+ offset = pos + area_size;
+ return pos;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public int getLastChar() {
+ return offset == 0 ? -1 : buffer[offset - 1];
+ }
+
+ public void p(char c) {
+ int pos = add_area(1);
+ buffer[pos] = c;
+ }
+
+ public void p(String s) {
+ int l = s.length();
+ int pos = add_area(l);
+ s.getChars(0, l, buffer, pos);
+ }
+
+ public final void p(char[] array) {
+ p(array, 0, array.length);
+ }
+
+ public void p(char[] array, int begin, int end) {
+ int l = end - begin;
+ int pos = add_area(l);
+ System.arraycopy(array, begin, buffer, pos, l);
+ }
+
+ public void p(int i) {
+ p(Integer.toString(i));
+ }
+
+ public void qchar(int c) {
+ int pos = ensure_area(2 + LITERAL_CHAR_MAX_SIZE);
+ buffer[pos] = '\'';
+ pos = put_string_literal_char(pos + 1, c, false);
+ buffer[pos] = '\'';
+ offset = pos + 1;
+ }
+
+ public void qstring(String s) {
+ int l = s.length();
+ int pos = ensure_area(2 + LITERAL_CHAR_MAX_SIZE * l);
+ buffer[pos] = '"';
+ ++pos;
+ for (int i = 0; i != l; ++i) {
+ pos = put_string_literal_char(pos, s.charAt(i), true);
+ }
+ buffer[pos] = '"';
+ offset = pos + 1;
+ }
+
+ private int put_string_literal_char(int pos, int c, boolean in_string) {
+ boolean backslash_symbol = true;
+ switch (c) {
+ case '\b': c = 'b'; break;
+ case '\t': c = 't'; break;
+ case '\n': c = 'n'; break;
+ case '\f': c = 'f'; break;
+ case '\r': c = 'r'; break;
+ case '\'': backslash_symbol = !in_string; break;
+ case '"': backslash_symbol = in_string; break;
+ default: backslash_symbol = false;
+ }
+
+ if (backslash_symbol) {
+ buffer[pos] = '\\';
+ buffer[pos + 1] = (char)c;
+ pos += 2;
+ }
+ else if (' ' <= c && c <= 126) {
+ buffer[pos] = (char)c;
+ ++pos;
+ }
+ else {
+ buffer[pos] = '\\';
+ buffer[pos + 1] = 'u';
+ buffer[pos + 2] = digit_to_hex_letter(0xF & (c >> 12));
+ buffer[pos + 3] = digit_to_hex_letter(0xF & (c >> 8));
+ buffer[pos + 4] = digit_to_hex_letter(0xF & (c >> 4));
+ buffer[pos + 5] = digit_to_hex_letter(0xF & c);
+ pos += 6;
+ }
+ return pos;
+ }
+
+ private static char digit_to_hex_letter(int d) {
+ return (char)((d < 10) ? '0' + d : 'A' - 10 + d);
+ }
+
+ public void indent(int level) {
+ int visible_size = indentStep * level;
+ int indent_size, tab_count;
+ if (indentTabSize <= 0) {
+ tab_count = 0; indent_size = visible_size;
+ }
+ else {
+ tab_count = visible_size / indentTabSize;
+ indent_size = tab_count + visible_size % indentTabSize;
+ }
+ int pos = add_area(indent_size);
+ int tab_end = pos + tab_count;
+ int indent_end = pos + indent_size;
+ for (; pos != tab_end; ++pos) { buffer[pos] = '\t'; }
+ for (; pos != indent_end; ++pos) { buffer[pos] = ' '; }
+ }
+
+ public void nl() {
+ p('\n');
+ }
+
+ public void line(int indent_level, String s) {
+ indent(indent_level); p(s); nl();
+ }
+
+ public void erase(int begin, int end) {
+ System.arraycopy(buffer, end, buffer, begin, offset - end);
+ offset -= end - begin;
+ }
+
+ public String toString() {
+ return new String(buffer, 0, offset);
+ }
+
+
+
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/FileBody.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/FileBody.java
new file mode 100644
index 0000000..60bdfb4
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/FileBody.java
@@ -0,0 +1,191 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.idswitch;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+public class FileBody {
+
+ private static class ReplaceItem {
+ ReplaceItem next;
+ int begin;
+ int end;
+ String replacement;
+
+ ReplaceItem(int begin, int end, String text) {
+ this.begin = begin;
+ this.end = end;
+ this.replacement = text;
+ }
+ }
+
+ private char[] buffer = new char[1 << 14]; // 16K
+ private int bufferEnd;
+ private int lineBegin;
+ private int lineEnd;
+ private int nextLineStart;
+
+ private int lineNumber;
+
+ ReplaceItem firstReplace;
+ ReplaceItem lastReplace;
+
+
+ public char[] getBuffer() { return buffer; }
+
+ public void readData(Reader r) throws IOException {
+ int capacity = buffer.length;
+ int offset = 0;
+ for (;;) {
+ int n_read = r.read(buffer, offset, capacity - offset);
+ if (n_read < 0) { break; }
+ offset += n_read;
+ if (capacity == offset) {
+ capacity *= 2;
+ char[] tmp = new char[capacity];
+ System.arraycopy(buffer, 0, tmp, 0, offset);
+ buffer = tmp;
+ }
+ }
+ bufferEnd = offset;
+ }
+
+ public void writeInitialData(Writer w) throws IOException {
+ w.write(buffer, 0, bufferEnd);
+ }
+
+ public void writeData(Writer w) throws IOException {
+ int offset = 0;
+ for (ReplaceItem x = firstReplace; x != null; x = x.next) {
+ int before_replace = x.begin - offset;
+ if (before_replace > 0) {
+ w.write(buffer, offset, before_replace);
+ }
+ w.write(x.replacement);
+ offset = x.end;
+ }
+ int tail = bufferEnd - offset;
+ if (tail != 0) {
+ w.write(buffer, offset, tail);
+ }
+ }
+
+ public boolean wasModified() { return firstReplace != null; }
+
+ public boolean setReplacement(int begin, int end, String text) {
+ if (equals(text, buffer, begin, end)) { return false; }
+
+ ReplaceItem item = new ReplaceItem(begin, end, text);
+ if (firstReplace == null) {
+ firstReplace = lastReplace = item;
+ }
+ else if (begin < firstReplace.begin) {
+ item.next = firstReplace;
+ firstReplace = item;
+ }
+ else {
+ ReplaceItem cursor = firstReplace;
+ ReplaceItem next = cursor.next;
+ while (next != null) {
+ if (begin < next.begin) {
+ item.next = next;
+ cursor.next = item;
+ break;
+ }
+ cursor = next;
+ next = next.next;
+ }
+ if (next == null) {
+ lastReplace.next = item;
+ }
+ }
+
+ return true;
+ }
+
+ public int getLineNumber() { return lineNumber; }
+
+ public int getLineBegin() { return lineBegin; }
+
+ public int getLineEnd() { return lineEnd; }
+
+ public void startLineLoop() {
+ lineNumber = 0;
+ lineBegin = lineEnd = nextLineStart = 0;
+ }
+
+ public boolean nextLine() {
+ if (nextLineStart == bufferEnd) {
+ lineNumber = 0; return false;
+ }
+ int i; int c = 0;
+ for (i = nextLineStart; i != bufferEnd; ++i) {
+ c = buffer[i];
+ if (c == '\n' || c == '\r') { break; }
+ }
+ lineBegin = nextLineStart;
+ lineEnd = i;
+ if (i == bufferEnd) {
+ nextLineStart = i;
+ }
+ else if (c == '\r' && i + 1 != bufferEnd && buffer[i + 1] == '\n') {
+ nextLineStart = i + 2;
+ }
+ else {
+ nextLineStart = i + 1;
+ }
+ ++lineNumber;
+ return true;
+ }
+
+ private static boolean equals(String str, char[] array, int begin, int end)
+ {
+ if (str.length() == end - begin) {
+ for (int i = begin, j = 0; i != end; ++i, ++j) {
+ if (array[i] != str.charAt(j)) { return false; }
+ }
+ return true;
+ }
+ return false;
+ }
+
+}
+
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/IdValuePair.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/IdValuePair.java
new file mode 100644
index 0000000..69d5065
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/IdValuePair.java
@@ -0,0 +1,58 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.idswitch;
+
+public class IdValuePair
+{
+ public final int idLength;
+ public final String id;
+ public final String value;
+
+ private int lineNumber;
+
+ public IdValuePair(String id, String value) {
+ this.idLength = id.length();
+ this.id = id;
+ this.value = value;
+ }
+
+ public int getLineNumber() { return lineNumber; }
+
+ public void setLineNumber(int value) { lineNumber = value; }
+}
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java
new file mode 100644
index 0000000..ae1d038
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/Main.java
@@ -0,0 +1,612 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.idswitch;
+
+import java.io.*;
+import java.util.*;
+import java.text.SimpleDateFormat;
+
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+public class Main {
+
+ private static final String SWITCH_TAG_STR = "string_id_map";
+ private static final String GENERATED_TAG_STR = "generated";
+ private static final String STRING_TAG_STR = "string";
+
+ private static final int
+ NORMAL_LINE = 0,
+ SWITCH_TAG = 1,
+ GENERATED_TAG = 2,
+ STRING_TAG = 3;
+
+ private final Vector all_pairs = new Vector();
+
+ private ToolErrorReporter R;
+ private CodePrinter P;
+ private FileBody body;
+ private String source_file;
+
+ private int tag_definition_end;
+
+ private int tag_value_start;
+ private int tag_value_end;
+
+ private static boolean is_value_type(int id) {
+ if (id == STRING_TAG) { return true; }
+ return false;
+ }
+
+ private static String tag_name(int id) {
+ switch (id) {
+ case SWITCH_TAG: return SWITCH_TAG_STR;
+ case -SWITCH_TAG: return "/" + SWITCH_TAG_STR;
+ case GENERATED_TAG: return GENERATED_TAG_STR;
+ case -GENERATED_TAG: return "/" + GENERATED_TAG_STR;
+ }
+ return "";
+ }
+
+ void process_file(String file_path) throws IOException {
+ source_file = file_path;
+
+ body = new FileBody();
+
+ InputStream is;
+ if (file_path.equals("-")) {
+ is = System.in;
+ }
+ else {
+ is = new FileInputStream(file_path);
+ }
+ try {
+ Reader r = new InputStreamReader(is, "ASCII");
+ body.readData(r);
+ }
+ finally { is.close(); }
+
+ process_file();
+
+ if (body.wasModified()) {
+ OutputStream os;
+ if (file_path.equals("-")) {
+ os = System.out;
+ }
+ else {
+ os = new FileOutputStream(file_path);
+ }
+
+ try {
+ Writer w = new OutputStreamWriter(os);
+ body.writeData(w);
+ w.flush();
+ }
+ finally { os.close(); }
+ }
+ }
+
+ private void process_file() {
+ int cur_state = 0;
+ char[] buffer = body.getBuffer();
+
+ int generated_begin = -1, generated_end = -1;
+ int time_stamp_begin = -1, time_stamp_end = -1;
+
+ body.startLineLoop();
+ while (body.nextLine()) {
+ int begin = body.getLineBegin();
+ int end = body.getLineEnd();
+
+ int tag_id = extract_line_tag_id(buffer, begin, end);
+ boolean bad_tag = false;
+ switch (cur_state) {
+ case NORMAL_LINE:
+ if (tag_id == SWITCH_TAG) {
+ cur_state = SWITCH_TAG;
+ all_pairs.removeAllElements();
+ generated_begin = -1;
+ }
+ else if (tag_id == -SWITCH_TAG) {
+ bad_tag = true;
+ }
+ break;
+ case SWITCH_TAG:
+ if (tag_id == 0) {
+ look_for_id_definitions(buffer, begin, end, false);
+ }
+ else if (tag_id == STRING_TAG) {
+ look_for_id_definitions(buffer, begin, end, true);
+ }
+ else if (tag_id == GENERATED_TAG) {
+ if (generated_begin >= 0) { bad_tag = true; }
+ else {
+ cur_state = GENERATED_TAG;
+ time_stamp_begin = tag_definition_end;
+ time_stamp_end = end;
+ }
+ }
+ else if (tag_id == -SWITCH_TAG) {
+ cur_state = 0;
+ if (generated_begin >= 0 && !all_pairs.isEmpty()) {
+ generate_java_code();
+ String code = P.toString();
+ boolean different = body.setReplacement
+ (generated_begin, generated_end, code);
+ if (different) {
+ String stamp = get_time_stamp();
+ body.setReplacement
+ (time_stamp_begin, time_stamp_end, stamp);
+ }
+ }
+
+ break;
+ }
+ else {
+ bad_tag = true;
+ }
+ break;
+ case GENERATED_TAG:
+ if (tag_id == 0) {
+ if (generated_begin < 0) { generated_begin = begin; }
+ }
+ else if (tag_id == -GENERATED_TAG) {
+ if (generated_begin < 0) { generated_begin = begin; }
+ cur_state = SWITCH_TAG;
+ generated_end = begin;
+ }
+ else {
+ bad_tag = true;
+ }
+ break;
+ }
+ if (bad_tag) {
+ String text = ToolErrorReporter.getMessage(
+ "msg.idswitch.bad_tag_order", tag_name(tag_id));
+ throw R.runtimeError
+ (text, source_file, body.getLineNumber(), null, 0);
+ }
+ }
+
+ if (cur_state != 0) {
+ String text = ToolErrorReporter.getMessage(
+ "msg.idswitch.file_end_in_switch", tag_name(cur_state));
+ throw R.runtimeError
+ (text, source_file, body.getLineNumber(), null, 0);
+ }
+ }
+
+ private String get_time_stamp() {
+ SimpleDateFormat f = new SimpleDateFormat
+ (" 'Last update:' yyyy-MM-dd HH:mm:ss z");
+ return f.format(new Date());
+ }
+
+ private void generate_java_code() {
+
+ P.clear();
+
+ IdValuePair[] pairs = new IdValuePair[all_pairs.size()];
+ all_pairs.copyInto(pairs);
+
+ SwitchGenerator g = new SwitchGenerator();
+ g.char_tail_test_threshold = 2;
+ g.setReporter(R);
+ g.setCodePrinter(P);
+
+ g.generateSwitch(pairs, "0");
+ }
+
+ private int extract_line_tag_id(char[] array, int cursor, int end) {
+ int id = 0;
+ cursor = skip_white_space(array, cursor, end);
+ int after_leading_white_space = cursor;
+ cursor = look_for_slash_slash(array, cursor, end);
+ if (cursor != end) {
+ boolean at_line_start = (after_leading_white_space + 2 == cursor);
+ cursor = skip_white_space(array, cursor, end);
+ if (cursor != end && array[cursor] == '#') {
+ ++cursor;
+
+ boolean end_tag = false;
+ if (cursor != end && array[cursor] == '/') {
+ ++cursor; end_tag = true;
+ }
+
+ int tag_start = cursor;
+
+ for (; cursor != end; ++cursor) {
+ int c = array[cursor];
+ if (c == '#' || c == '=' ||is_white_space(c)) { break; }
+ }
+
+ if (cursor != end) {
+ int tag_end = cursor;
+ cursor = skip_white_space(array, cursor, end);
+ if (cursor != end) {
+ int c = array[cursor];
+ if (c == '=' || c == '#') {
+ id = get_tag_id
+ (array, tag_start, tag_end, at_line_start);
+ if (id != 0) {
+ String bad = null;
+ if (c == '#') {
+ if (end_tag) {
+ id = -id;
+ if (is_value_type(id)) {
+ bad = "msg.idswitch.no_end_usage";
+ }
+ }
+ tag_definition_end = cursor + 1;
+ }
+ else {
+ if (end_tag) {
+ bad = "msg.idswitch.no_end_with_value";
+ }
+ else if (!is_value_type(id)) {
+ bad = "msg.idswitch.no_value_allowed";
+ }
+ id = extract_tag_value
+ (array, cursor + 1, end, id);
+ }
+ if (bad != null) {
+ String s = ToolErrorReporter.getMessage(
+ bad, tag_name(id));
+ throw R.runtimeError
+ (s, source_file, body.getLineNumber(),
+ null, 0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return id;
+ }
+
+// Return position after first of // or end if not found
+ private int look_for_slash_slash(char[] array, int cursor, int end) {
+ while (cursor + 2 <= end) {
+ int c = array[cursor++];
+ if (c == '/') {
+ c = array[cursor++];
+ if (c == '/') {
+ return cursor;
+ }
+ }
+ }
+ return end;
+ }
+
+ private int extract_tag_value(char[] array, int cursor, int end, int id) {
+ // cursor points after #[^#=]+=
+ // ALERT: implement support for quoted strings
+ boolean found = false;
+ cursor = skip_white_space(array, cursor, end);
+ if (cursor != end) {
+ int value_start = cursor;
+ int value_end = cursor;
+ while (cursor != end) {
+ int c = array[cursor];
+ if (is_white_space(c)) {
+ int after_space = skip_white_space(array, cursor + 1, end);
+ if (after_space != end && array[after_space] == '#') {
+ value_end = cursor;
+ cursor = after_space;
+ break;
+ }
+ cursor = after_space + 1;
+ }
+ else if (c == '#') {
+ value_end = cursor;
+ break;
+ }
+ else {
+ ++cursor;
+ }
+ }
+ if (cursor != end) {
+ // array[cursor] is '#' here
+ found = true;
+ tag_value_start = value_start;
+ tag_value_end = value_end;
+ tag_definition_end = cursor + 1;
+ }
+ }
+ return (found) ? id : 0;
+ }
+
+ private int get_tag_id
+ (char[] array, int begin, int end, boolean at_line_start)
+ {
+ if (at_line_start) {
+ if (equals(SWITCH_TAG_STR, array, begin, end)) {
+ return SWITCH_TAG;
+ }
+ if (equals(GENERATED_TAG_STR, array, begin, end)) {
+ return GENERATED_TAG;
+ }
+ }
+ if (equals(STRING_TAG_STR, array, begin, end)) {
+ return STRING_TAG;
+ }
+ return 0;
+ }
+
+ private void look_for_id_definitions
+ (char[] array, int begin, int end, boolean use_tag_value_as_string)
+ {
+ // Look for the pattern
+ // '^[ \t]+Id_([a-zA-Z0-9_]+)[ \t]*=.*$'
+ // where \1 gives field or method name
+ int cursor = begin;
+ // Skip tab and spaces at the beginning
+ cursor = skip_white_space(array, cursor, end);
+ int id_start = cursor;
+ int name_start = skip_matched_prefix("Id_", array, cursor, end);
+ if (name_start >= 0) {
+ // Found Id_ prefix
+ cursor = name_start;
+ cursor = skip_name_char(array, cursor, end);
+ int name_end = cursor;
+ if (name_start != name_end) {
+ cursor = skip_white_space(array, cursor, end);
+ if (cursor != end) {
+ if (array[cursor] == '=') {
+ int id_end = name_end;
+ if (use_tag_value_as_string) {
+ name_start = tag_value_start;
+ name_end = tag_value_end;
+ }
+ // Got the match
+ add_id(array, id_start, id_end, name_start, name_end);
+ }
+ }
+ }
+ }
+ }
+
+ private void add_id
+ (char[] array, int id_start, int id_end, int name_start, int name_end)
+ {
+ String name = new String(array, name_start, name_end - name_start);
+ String value = new String(array, id_start, id_end - id_start);
+
+ IdValuePair pair = new IdValuePair(name, value);
+
+ pair.setLineNumber(body.getLineNumber());
+
+ all_pairs.addElement(pair);
+ }
+
+ private static boolean is_white_space(int c) {
+ return c == ' ' || c == '\t';
+ }
+
+ private static int skip_white_space(char[] array, int begin, int end) {
+ int cursor = begin;
+ for (; cursor != end; ++cursor) {
+ int c = array[cursor];
+ if (!is_white_space(c)) { break; }
+ }
+ return cursor;
+ }
+
+ private static int skip_matched_prefix
+ (String prefix, char[] array, int begin, int end)
+ {
+ int cursor = -1;
+ int prefix_length = prefix.length();
+ if (prefix_length <= end - begin) {
+ cursor = begin;
+ for (int i = 0; i != prefix_length; ++i, ++cursor) {
+ if (prefix.charAt(i) != array[cursor]) {
+ cursor = -1; break;
+ }
+ }
+ }
+ return cursor;
+ }
+
+ private static boolean equals(String str, char[] array, int begin, int end)
+ {
+ if (str.length() == end - begin) {
+ for (int i = begin, j = 0; i != end; ++i, ++j) {
+ if (array[i] != str.charAt(j)) { return false; }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private static int skip_name_char(char[] array, int begin, int end) {
+ int cursor = begin;
+ for (; cursor != end; ++cursor) {
+ int c = array[cursor];
+ if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) {
+ if (!('0' <= c && c <= '9')) {
+ if (c != '_') {
+ break;
+ }
+ }
+ }
+ }
+ return cursor;
+ }
+
+ public static void main(String[] args) {
+ Main self = new Main();
+ int status = self.exec(args);
+ System.exit(status);
+ }
+
+ private int exec(String[] args) {
+ R = new ToolErrorReporter(true, System.err);
+
+ int arg_count = process_options(args);
+
+ if (arg_count == 0) {
+ option_error(ToolErrorReporter.getMessage(
+ "msg.idswitch.no_file_argument"));
+ return -1;
+ }
+ if (arg_count > 1) {
+ option_error(ToolErrorReporter.getMessage(
+ "msg.idswitch.too_many_arguments"));
+ return -1;
+ }
+
+ P = new CodePrinter();
+ P.setIndentStep(4);
+ P.setIndentTabSize(0);
+
+ try {
+ process_file(args[0]);
+ }
+ catch (IOException ex) {
+ print_error(ToolErrorReporter.getMessage(
+ "msg.idswitch.io_error", ex.toString()));
+ return -1;
+ }
+ catch (EvaluatorException ex) {
+ return -1;
+ }
+ return 0;
+ }
+
+ private int process_options(String[] args) {
+
+ int status = 1;
+
+ boolean show_usage = false;
+ boolean show_version = false;
+
+ int N = args.length;
+ L: for (int i = 0; i != N; ++i) {
+ String arg = args[i];
+ int arg_length = arg.length();
+ if (arg_length >= 2) {
+ if (arg.charAt(0) == '-') {
+ if (arg.charAt(1) == '-') {
+ if (arg_length == 2) {
+ args[i] = null; break;
+ }
+ if (arg.equals("--help")) {
+ show_usage = true;
+ }
+ else if (arg.equals("--version")) {
+ show_version = true;
+ }
+ else {
+ option_error(ToolErrorReporter.getMessage(
+ "msg.idswitch.bad_option", arg));
+ status = -1; break L;
+ }
+ }
+ else {
+ for (int j = 1; j != arg_length; ++j) {
+ char c = arg.charAt(j);
+ switch (c) {
+ case 'h': show_usage = true; break;
+ default:
+ option_error(
+ ToolErrorReporter.getMessage(
+ "msg.idswitch.bad_option_char",
+ String.valueOf(c)));
+ status = -1;
+ break L;
+ }
+
+ }
+ }
+ args[i] = null;
+ }
+ }
+ }
+
+ if (status == 1) {
+ if (show_usage) { show_usage(); status = 0; }
+ if (show_version) { show_version(); status = 0; }
+ }
+
+ if (status != 1) { System.exit(status); }
+
+ return remove_nulls(args);
+ }
+
+ private void show_usage() {
+ System.out.println(
+ ToolErrorReporter.getMessage("msg.idswitch.usage"));
+ System.out.println();
+ }
+
+ private void show_version() {
+ System.out.println(
+ ToolErrorReporter.getMessage("msg.idswitch.version"));
+ }
+
+ private void option_error(String str) {
+ print_error(
+ ToolErrorReporter.getMessage("msg.idswitch.bad_invocation", str));
+ }
+
+ private void print_error(String text) {
+ System.err.println(text);
+ }
+
+ private int remove_nulls(String[] array) {
+ int N = array.length;
+ int cursor = 0;
+ for (; cursor != N; ++cursor) {
+ if (array[cursor] == null) { break; }
+ }
+ int destination = cursor;
+ if (cursor != N) {
+ ++cursor;
+ for (; cursor != N; ++cursor) {
+ String elem = array[cursor];
+ if (elem != null) {
+ array[destination] = elem; ++destination;
+ }
+ }
+ }
+ return destination;
+ }
+}
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/SwitchGenerator.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/SwitchGenerator.java
new file mode 100644
index 0000000..3db99d6
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/idswitch/SwitchGenerator.java
@@ -0,0 +1,491 @@
+/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.idswitch;
+
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+public class SwitchGenerator {
+
+ String v_switch_label = "L0";
+ String v_label = "L";
+ String v_s = "s";
+ String v_c = "c";
+ String v_guess = "X";
+ String v_id = "id";
+ String v_length_suffix = "_length";
+
+ int use_if_threshold = 3;
+ int char_tail_test_threshold = 2;
+
+ private IdValuePair[] pairs;
+ private String default_value;
+ private int[] columns;
+ private boolean c_was_defined;
+
+ private CodePrinter P;
+ private ToolErrorReporter R;
+ private String source_file;
+
+ public CodePrinter getCodePrinter() { return P; }
+ public void setCodePrinter(CodePrinter value) { P = value; }
+
+ public ToolErrorReporter getReporter() { return R; }
+ public void setReporter(ToolErrorReporter value) { R = value; }
+
+ public String getSourceFileName() { return source_file; }
+ public void setSourceFileName(String value) { source_file = value; }
+
+ public void generateSwitch(String[] pairs, String default_value) {
+ int N = pairs.length / 2;
+ IdValuePair[] id_pairs = new IdValuePair[N];
+ for (int i = 0; i != N; ++i) {
+ id_pairs[i] = new IdValuePair(pairs[2 * i], pairs[2 * i + 1]);
+ }
+ generateSwitch(id_pairs, default_value);
+
+ }
+
+ public void generateSwitch(IdValuePair[] pairs, String default_value) {
+ int begin = 0;
+ int end = pairs.length;
+ if (begin == end) { return; }
+ this.pairs = pairs;
+ this.default_value = default_value;
+
+ generate_body(begin, end, 2);
+ }
+
+ private void generate_body(int begin, int end, int indent_level) {
+ P.indent(indent_level);
+ P.p(v_switch_label); P.p(": { ");
+ P.p(v_id); P.p(" = "); P.p(default_value);
+ P.p("; String "); P.p(v_guess); P.p(" = null;");
+
+ c_was_defined = false;
+ int c_def_begin = P.getOffset();
+ P.p(" int "); P.p(v_c); P.p(';');
+ int c_def_end = P.getOffset();
+ P.nl();
+
+ generate_length_switch(begin, end, indent_level + 1);
+
+ if (!c_was_defined) {
+ P.erase(c_def_begin, c_def_end);
+ }
+
+ P.indent(indent_level + 1);
+ P.p("if ("); P.p(v_guess); P.p("!=null && ");
+ P.p(v_guess); P.p("!="); P.p(v_s);
+ P.p(" && !"); P.p(v_guess); P.p(".equals("); P.p(v_s); P.p(")) ");
+ P.p(v_id); P.p(" = "); P.p(default_value); P.p(";"); P.nl();
+
+ // Add break at end of block to suppress warning for unused label
+ P.indent(indent_level + 1);
+ P.p("break "); P.p(v_switch_label); P.p(";"); P.nl();
+
+ P.line(indent_level, "}");
+ }
+
+ private void generate_length_switch(int begin, int end, int indent_level) {
+
+ sort_pairs(begin, end, -1);
+
+ check_all_is_different(begin, end);
+
+ int lengths_count = count_different_lengths(begin, end);
+
+ columns = new int[pairs[end - 1].idLength];
+
+ boolean use_if;
+ if (lengths_count <= use_if_threshold) {
+ use_if = true;
+ if (lengths_count != 1) {
+ P.indent(indent_level);
+ P.p("int "); P.p(v_s); P.p(v_length_suffix);
+ P.p(" = "); P.p(v_s); P.p(".length();");
+ P.nl();
+ }
+ }
+ else {
+ use_if = false;
+ P.indent(indent_level);
+ P.p(v_label); P.p(": switch (");
+ P.p(v_s); P.p(".length()) {");
+ P.nl();
+ }
+
+ int same_length_begin = begin;
+ int cur_l = pairs[begin].idLength, l = 0;
+ for (int i = begin;;) {
+ ++i;
+ if (i == end || (l = pairs[i].idLength) != cur_l) {
+ int next_indent;
+ if (use_if) {
+ P.indent(indent_level);
+ if (same_length_begin != begin) { P.p("else "); }
+ P.p("if (");
+ if (lengths_count == 1) {
+ P.p(v_s); P.p(".length()==");
+ }
+ else {
+ P.p(v_s); P.p(v_length_suffix); P.p("==");
+ }
+ P.p(cur_l);
+ P.p(") {");
+ next_indent = indent_level + 1;
+ }
+ else {
+ P.indent(indent_level);
+ P.p("case "); P.p(cur_l); P.p(":");
+ next_indent = indent_level + 1;
+ }
+ generate_letter_switch
+ (same_length_begin, i, next_indent, !use_if, use_if);
+ if (use_if) {
+ P.p("}"); P.nl();
+ }
+ else {
+ P.p("break "); P.p(v_label); P.p(";"); P.nl();
+ }
+
+ if (i == end) { break; }
+ same_length_begin = i;
+ cur_l = l;
+ }
+ }
+
+ if (!use_if) {
+ P.indent(indent_level); P.p("}"); P.nl();
+ }
+
+ }
+
+ private void generate_letter_switch
+ (int begin, int end,
+ int indent_level, boolean label_was_defined, boolean inside_if)
+ {
+ int L = pairs[begin].idLength;
+
+ for (int i = 0; i != L; ++i) {
+ columns[i] = i;
+ }
+
+ generate_letter_switch_r
+ (begin, end, L, indent_level, label_was_defined, inside_if);
+ }
+
+
+ private boolean generate_letter_switch_r
+ (int begin, int end, int L,
+ int indent_level, boolean label_was_defined, boolean inside_if)
+ {
+ boolean next_is_unreachable = false;
+ if (begin + 1 == end) {
+ P.p(' ');
+ IdValuePair pair = pairs[begin];
+ if (L > char_tail_test_threshold) {
+ P.p(v_guess); P.p("="); P.qstring(pair.id); P.p(";");
+ P.p(v_id); P.p("="); P.p(pair.value); P.p(";");
+ }
+ else {
+ if (L == 0) {
+ next_is_unreachable = true;
+ P.p(v_id); P.p("="); P.p(pair.value);
+ P.p("; break "); P.p(v_switch_label); P.p(";");
+ }
+ else {
+ P.p("if (");
+ int column = columns[0];
+ P.p(v_s); P.p(".charAt("); P.p(column); P.p(")==");
+ P.qchar(pair.id.charAt(column));
+ for (int i = 1; i != L; ++i) {
+ P.p(" && ");
+ column = columns[i];
+ P.p(v_s); P.p(".charAt("); P.p(column); P.p(")==");
+ P.qchar(pair.id.charAt(column));
+ }
+ P.p(") {");
+ P.p(v_id); P.p("="); P.p(pair.value);
+ P.p("; break "); P.p(v_switch_label); P.p(";}");
+ }
+ }
+ P.p(' ');
+ return next_is_unreachable;
+ }
+
+ int max_column_index = find_max_different_column(begin, end, L);
+ int max_column = columns[max_column_index];
+ int count = count_different_chars(begin, end, max_column);
+
+ columns[max_column_index] = columns[L - 1];
+
+ if (inside_if) { P.nl(); P.indent(indent_level); }
+ else { P.p(' '); }
+
+ boolean use_if;
+ if (count <= use_if_threshold) {
+ use_if = true;
+ c_was_defined = true;
+ P.p(v_c); P.p("="); P.p(v_s);
+ P.p(".charAt("); P.p(max_column); P.p(");");
+ }
+ else {
+ use_if = false;
+ if (!label_was_defined) {
+ label_was_defined = true;
+ P.p(v_label); P.p(": ");
+ }
+ P.p("switch ("); P.p(v_s);
+ P.p(".charAt("); P.p(max_column); P.p(")) {");
+ }
+
+ int same_char_begin = begin;
+ int cur_ch = pairs[begin].id.charAt(max_column), ch = 0;
+ for (int i = begin;;) {
+ ++i;
+ if (i == end || (ch = pairs[i].id.charAt(max_column)) != cur_ch) {
+ int next_indent;
+ if (use_if) {
+ P.nl(); P.indent(indent_level);
+ if (same_char_begin != begin) { P.p("else "); }
+ P.p("if ("); P.p(v_c); P.p("==");
+ P.qchar(cur_ch); P.p(") {");
+ next_indent = indent_level + 1;
+ }
+ else {
+ P.nl(); P.indent(indent_level);
+ P.p("case "); P.qchar(cur_ch); P.p(":");
+ next_indent = indent_level + 1;
+ }
+ boolean after_unreachable = generate_letter_switch_r
+ (same_char_begin, i, L - 1,
+ next_indent, label_was_defined, use_if);
+ if (use_if) {
+ P.p("}");
+ }
+ else {
+ if (!after_unreachable) {
+ P.p("break "); P.p(v_label); P.p(";");
+ }
+ }
+ if (i == end) { break; }
+ same_char_begin = i;
+ cur_ch = ch;
+ }
+ }
+
+ if (use_if) {
+ P.nl();
+ if (inside_if) { P.indent(indent_level - 1); }
+ else { P.indent(indent_level); }
+ }
+ else {
+ P.nl(); P.indent(indent_level); P.p("}");
+ if (inside_if) { P.nl(); P.indent(indent_level - 1);}
+ else { P.p(' '); }
+ }
+
+ columns[max_column_index] = max_column;
+
+ return next_is_unreachable;
+ }
+
+
+ private int count_different_lengths(int begin, int end) {
+ int lengths_count = 0;
+ int cur_l = -1;
+ for (; begin != end; ++begin) {
+ int l = pairs[begin].idLength;
+ if (cur_l != l) {
+ ++lengths_count; cur_l = l;
+ }
+ }
+ return lengths_count;
+ }
+
+ private int find_max_different_column(int begin, int end, int L) {
+ int max_count = 0;
+ int max_index = 0;
+
+ for (int i = 0; i != L; ++i) {
+ int column = columns[i];
+ sort_pairs(begin, end, column);
+ int count = count_different_chars(begin, end, column);
+ if (count == end - begin) { return i; }
+ if (max_count < count) {
+ max_count = count;
+ max_index = i;
+ }
+ }
+
+ if (max_index != L - 1) {
+ sort_pairs(begin, end, columns[max_index]);
+ }
+
+ return max_index;
+ }
+
+ private int count_different_chars(int begin, int end, int column) {
+ int chars_count = 0;
+ int cur_ch = -1;
+ for (; begin != end; ++begin) {
+ int ch = pairs[begin].id.charAt(column);
+ if (ch != cur_ch) {
+ ++chars_count; cur_ch = ch;
+ }
+ }
+ return chars_count;
+ }
+
+ private void check_all_is_different(int begin, int end) {
+ if (begin != end) {
+ IdValuePair prev = pairs[begin];
+ while (++begin != end) {
+ IdValuePair current = pairs[begin];
+ if (prev.id.equals(current.id)) {
+ throw on_same_pair_fail(prev, current);
+ }
+ prev = current;
+ }
+ }
+ }
+
+ private EvaluatorException on_same_pair_fail(IdValuePair a, IdValuePair b) {
+ int line1 = a.getLineNumber(), line2 = b.getLineNumber();
+ if (line2 > line1) { int tmp = line1; line1 = line2; line2 = tmp; }
+ String error_text = ToolErrorReporter.getMessage(
+ "msg.idswitch.same_string", a.id, new Integer(line2));
+ return R.runtimeError(error_text, source_file, line1, null, 0);
+ }
+
+ private void sort_pairs(int begin, int end, int comparator) {
+ heap4Sort(pairs, begin, end - begin, comparator);
+ }
+
+ private static boolean bigger
+ (IdValuePair a, IdValuePair b, int comparator)
+ {
+ if (comparator < 0) {
+ // For length selection switch it is enough to compare just length,
+ // but to detect same strings full comparison is essential
+ //return a.idLength > b.idLength;
+ int diff = a.idLength - b.idLength;
+ if (diff != 0) { return diff > 0; }
+ return a.id.compareTo(b.id) > 0;
+ }
+ else {
+ return a.id.charAt(comparator) > b.id.charAt(comparator);
+ }
+ }
+
+ private static void heap4Sort
+ (IdValuePair[] array, int offset, int size, int comparator)
+ {
+ if (size <= 1) { return; }
+ makeHeap4(array, offset, size, comparator);
+ while (size > 1) {
+ --size;
+ IdValuePair v1 = array[offset + size];
+ IdValuePair v2 = array[offset + 0];
+ array[offset + size] = v2;
+ array[offset + 0] = v1;
+ heapify4(array, offset, size, 0, comparator);
+ }
+ }
+
+ private static void makeHeap4
+ (IdValuePair[] array, int offset, int size, int comparator)
+ {
+ for (int i = ((size + 2) >> 2); i != 0;) {
+ --i;
+ heapify4(array, offset, size, i, comparator);
+ }
+ }
+
+ private static void heapify4
+ (IdValuePair[] array, int offset, int size, int i, int comparator)
+ {
+ int new_i1, new_i2, new_i3;
+ IdValuePair i_val = array[offset + i];
+ for (;;) {
+ int base = (i << 2);
+ new_i1 = base | 1;
+ new_i2 = base | 2;
+ new_i3 = base | 3;
+ int new_i4 = base + 4;
+ if (new_i4 >= size) { break; }
+ IdValuePair val1 = array[offset + new_i1];
+ IdValuePair val2 = array[offset + new_i2];
+ IdValuePair val3 = array[offset + new_i3];
+ IdValuePair val4 = array[offset + new_i4];
+ if (bigger(val2, val1, comparator)) {
+ val1 = val2; new_i1 = new_i2;
+ }
+ if (bigger(val4, val3, comparator)) {
+ val3 = val4; new_i3 = new_i4;
+ }
+ if (bigger(val3, val1, comparator)) {
+ val1 = val3; new_i1 = new_i3;
+ }
+ if (bigger(i_val, val1, comparator)) { return; }
+ array[offset + i] = val1;
+ array[offset + new_i1] = i_val;
+ i = new_i1;
+ }
+ if (new_i1 < size) {
+ IdValuePair val1 = array[offset + new_i1];
+ if (new_i2 != size) {
+ IdValuePair val2 = array[offset + new_i2];
+ if (bigger(val2, val1, comparator)) {
+ val1 = val2; new_i1 = new_i2;
+ }
+ if (new_i3 != size) {
+ IdValuePair val3 = array[offset + new_i3];
+ if (bigger(val3, val1, comparator)) {
+ val1 = val3; new_i1 = new_i3;
+ }
+ }
+ }
+ if (bigger(val1, i_val, comparator)) {
+ array[offset + i] = val1;
+ array[offset + new_i1] = i_val;
+ }
+ }
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java
new file mode 100644
index 0000000..2da4f2f
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java
@@ -0,0 +1,395 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christine Begle
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.jsc;
+
+import java.io.*;
+import java.util.*;
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.optimizer.ClassCompiler;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+/**
+ * @author Norris Boyd
+ */
+public class Main {
+
+ /**
+ * Main entry point.
+ *
+ * Process arguments as would a normal Java program.
+ * Then set up the execution environment and begin to
+ * compile scripts.
+ */
+ public static void main(String args[])
+ {
+ Main main = new Main();
+ args = main.processOptions(args);
+ if (args == null) {
+ if (main.printHelp) {
+ System.out.println(ToolErrorReporter.getMessage(
+ "msg.jsc.usage", Main.class.getName()));
+ System.exit(0);
+ }
+ System.exit(1);
+ }
+ if (!main.reporter.hasReportedError()) {
+ main.processSource(args);
+ }
+ }
+
+ public Main()
+ {
+ reporter = new ToolErrorReporter(true);
+ compilerEnv = new CompilerEnvirons();
+ compilerEnv.setErrorReporter(reporter);
+ compiler = new ClassCompiler(compilerEnv);
+ }
+
+ /**
+ * Parse arguments.
+ *
+ */
+ public String[] processOptions(String args[])
+ {
+ targetPackage = ""; // default to no package
+ compilerEnv.setGenerateDebugInfo(false); // default to no symbols
+ for (int i=0; i < args.length; i++) {
+ String arg = args[i];
+ if (!arg.startsWith("-")) {
+ int tail = args.length - i;
+ if (targetName != null && tail > 1) {
+ addError("msg.multiple.js.to.file", targetName);
+ return null;
+ }
+ String[] result = new String[tail];
+ for (int j = 0; j != tail; ++j) {
+ result[j] = args[i + j];
+ }
+ return result;
+ }
+ if (arg.equals("-help") || arg.equals("-h")
+ || arg.equals("--help"))
+ {
+ printHelp = true;
+ return null;
+ }
+
+ try {
+ if (arg.equals("-version") && ++i < args.length) {
+ int version = Integer.parseInt(args[i]);
+ compilerEnv.setLanguageVersion(version);
+ continue;
+ }
+ if ((arg.equals("-opt") || arg.equals("-O")) &&
+ ++i < args.length)
+ {
+ int optLevel = Integer.parseInt(args[i]);
+ compilerEnv.setOptimizationLevel(optLevel);
+ continue;
+ }
+ }
+ catch (NumberFormatException e) {
+ badUsage(args[i]);
+ return null;
+ }
+ if (arg.equals("-nosource")) {
+ compilerEnv.setGeneratingSource(false);
+ continue;
+ }
+ if (arg.equals("-debug") || arg.equals("-g")) {
+ compilerEnv.setGenerateDebugInfo(true);
+ continue;
+ }
+ if (arg.equals("-main-method-class") && ++i < args.length) {
+ compiler.setMainMethodClass(args[i]);
+ continue;
+ }
+ if (arg.equals("-o") && ++i < args.length) {
+ String name = args[i];
+ int end = name.length();
+ if (end == 0
+ || !Character.isJavaIdentifierStart(name.charAt(0)))
+ {
+ addError("msg.invalid.classfile.name", name);
+ continue;
+ }
+ for (int j = 1; j < end; j++) {
+ char c = name.charAt(j);
+ if (!Character.isJavaIdentifierPart(c)) {
+ if (c == '.') {
+ // check if it is the dot in .class
+ if (j == end - 6 && name.endsWith(".class")) {
+ name = name.substring(0, j);
+ break;
+ }
+ }
+ addError("msg.invalid.classfile.name", name);
+ break;
+ }
+ }
+ targetName = name;
+ continue;
+ }
+ if (arg.equals("-observe-instruction-count")) {
+ compilerEnv.setGenerateObserverCount(true);
+ }
+ if (arg.equals("-package") && ++i < args.length) {
+ String pkg = args[i];
+ int end = pkg.length();
+ for (int j = 0; j != end; ++j) {
+ char c = pkg.charAt(j);
+ if (Character.isJavaIdentifierStart(c)) {
+ for (++j; j != end; ++j) {
+ c = pkg.charAt(j);
+ if (!Character.isJavaIdentifierPart(c)) {
+ break;
+ }
+ }
+ if (j == end) {
+ break;
+ }
+ if (c == '.' && j != end - 1) {
+ continue;
+ }
+ }
+ addError("msg.package.name", targetPackage);
+ return null;
+ }
+ targetPackage = pkg;
+ continue;
+ }
+ if (arg.equals("-extends") && ++i < args.length) {
+ String targetExtends = args[i];
+ Class superClass;
+ try {
+ superClass = Class.forName(targetExtends);
+ } catch (ClassNotFoundException e) {
+ throw new Error(e.toString()); // TODO: better error
+ }
+ compiler.setTargetExtends(superClass);
+ continue;
+ }
+ if (arg.equals("-implements") && ++i < args.length) {
+ // TODO: allow for multiple comma-separated interfaces.
+ String targetImplements = args[i];
+ StringTokenizer st = new StringTokenizer(targetImplements,
+ ",");
+ Vector v = new Vector();
+ while (st.hasMoreTokens()) {
+ String className = st.nextToken();
+ try {
+ v.addElement(Class.forName(className));
+ } catch (ClassNotFoundException e) {
+ throw new Error(e.toString()); // TODO: better error
+ }
+ }
+ Class[] implementsClasses = new Class[v.size()];
+ v.copyInto(implementsClasses);
+ compiler.setTargetImplements(implementsClasses);
+ continue;
+ }
+ if (arg.equals("-d") && ++i < args.length) {
+ destinationDir = args[i];
+ continue;
+ }
+ badUsage(arg);
+ return null;
+ }
+ // no file name
+ p(ToolErrorReporter.getMessage("msg.no.file"));
+ return null;
+ }
+ /**
+ * Print a usage message.
+ */
+ private static void badUsage(String s) {
+ System.err.println(ToolErrorReporter.getMessage(
+ "msg.jsc.bad.usage", Main.class.getName(), s));
+ }
+
+ /**
+ * Compile JavaScript source.
+ *
+ */
+ public void processSource(String[] filenames)
+ {
+ for (int i = 0; i != filenames.length; ++i) {
+ String filename = filenames[i];
+ if (!filename.endsWith(".js")) {
+ addError("msg.extension.not.js", filename);
+ return;
+ }
+ File f = new File(filename);
+ String source = readSource(f);
+ if (source == null) return;
+
+ String mainClassName = targetName;
+ if (mainClassName == null) {
+ String name = f.getName();
+ String nojs = name.substring(0, name.length() - 3);
+ mainClassName = getClassName(nojs);
+ }
+ if (targetPackage.length() != 0) {
+ mainClassName = targetPackage+"."+mainClassName;
+ }
+
+ Object[] compiled
+ = compiler.compileToClassFiles(source, filename, 1,
+ mainClassName);
+ if (compiled == null || compiled.length == 0) {
+ return;
+ }
+
+ File targetTopDir = null;
+ if (destinationDir != null) {
+ targetTopDir = new File(destinationDir);
+ } else {
+ String parent = f.getParent();
+ if (parent != null) {
+ targetTopDir = new File(parent);
+ }
+ }
+ for (int j = 0; j != compiled.length; j += 2) {
+ String className = (String)compiled[j];
+ byte[] bytes = (byte[])compiled[j + 1];
+ File outfile = getOutputFile(targetTopDir, className);
+ try {
+ FileOutputStream os = new FileOutputStream(outfile);
+ try {
+ os.write(bytes);
+ } finally {
+ os.close();
+ }
+ } catch (IOException ioe) {
+ addFormatedError(ioe.toString());
+ }
+ }
+ }
+ }
+
+ private String readSource(File f)
+ {
+ if (!f.exists()) {
+ addError("msg.jsfile.not.found", f.getAbsolutePath());
+ return null;
+ }
+ try {
+ Reader in = new FileReader(f);
+ try {
+ return Kit.readReader(in);
+ } finally {
+ in.close();
+ }
+ } catch (FileNotFoundException ex) {
+ addError("msg.couldnt.open", f.getAbsolutePath());
+ } catch (IOException ioe) {
+ addFormatedError(ioe.toString());
+ }
+ return null;
+ }
+
+ private File getOutputFile(File parentDir, String className)
+ {
+ String path = className.replace('.', File.separatorChar);
+ path = path.concat(".class");
+ File f = new File(parentDir, path);
+ String dirPath = f.getParent();
+ if (dirPath != null) {
+ File dir = new File(dirPath);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ }
+ return f;
+ }
+
+ /**
+ * Verify that class file names are legal Java identifiers. Substitute
+ * illegal characters with underscores, and prepend the name with an
+ * underscore if the file name does not begin with a JavaLetter.
+ */
+
+ String getClassName(String name) {
+ char[] s = new char[name.length()+1];
+ char c;
+ int j = 0;
+
+ if (!Character.isJavaIdentifierStart(name.charAt(0))) {
+ s[j++] = '_';
+ }
+ for (int i=0; i < name.length(); i++, j++) {
+ c = name.charAt(i);
+ if ( Character.isJavaIdentifierPart(c) ) {
+ s[j] = c;
+ } else {
+ s[j] = '_';
+ }
+ }
+ return (new String(s)).trim();
+ }
+
+ private static void p(String s) {
+ System.out.println(s);
+ }
+
+ private void addError(String messageId, String arg)
+ {
+ String msg;
+ if (arg == null) {
+ msg = ToolErrorReporter.getMessage(messageId);
+ } else {
+ msg = ToolErrorReporter.getMessage(messageId, arg);
+ }
+ addFormatedError(msg);
+ }
+
+ private void addFormatedError(String message)
+ {
+ reporter.error(message, null, -1, null, -1);
+ }
+
+ private boolean printHelp;
+ private ToolErrorReporter reporter;
+ private CompilerEnvirons compilerEnv;
+ private ClassCompiler compiler;
+ private String targetName;
+ private String targetPackage;
+ private String destinationDir;
+}
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties
new file mode 100644
index 0000000..76615e9
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/resources/Messages.properties
@@ -0,0 +1,268 @@
+#
+# JavaScript tools messages file.
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Rhino code, released
+# May 6, 1999.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1997-1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# the GNU General Public License Version 2 or later (the "GPL"), in which
+# case the provisions of the GPL are applicable instead of those above. If
+# you wish to allow use of your version of this file only under the terms of
+# the GPL and not to allow others to use your version of this file under the
+# MPL, indicate your decision by deleting the provisions above and replacing
+# them with the notice and other provisions required by the GPL. If you do
+# not delete the provisions above, a recipient may use your version of this
+# file under either the MPL or the GPL.
+#
+# ***** END LICENSE BLOCK *****
+
+msg.expected.string.arg =\
+ Expected a string argument.
+
+msg.class.not.found =\
+ Class "{0}" not found.
+
+msg.couldnt.open =\
+ Couldn''t open file "{0}".
+
+msg.couldnt.open.url =\
+ Couldn''t open URL "{0}: {1}".
+
+msg.no-opt =\
+ Must have the org.mozilla.javascript.optimizer package available \
+ to compile to class files.
+
+msg.shell.invalid =\
+ Invalid option "{0}"
+
+msg.shell.usage =\
+ Usage: java {0} [options...] [files]\n\
+ Valid options are:\n\
+ \ -?, -help Displays help messages.\n\
+ \ -w Enable warnings.\n\
+ \ -version 100|110|120|130|140|150|160|170\n\
+ \ Set a specific language version.\n\
+ \ -opt [-1|0-9] Set optimization level.\n\
+ \ -f script-filename Execute script file.\n\
+ \ -e script-source Evaluate inline script.\n\
+ \ -debug Generate debug code.\n\
+ \ -strict Enable strict mode warnings.\n\
+ \ -fatal-warnings Treat warnings as errors.
+
+msg.help =\
+ \n\
+ Command Description \n\
+ ======= =========== \n\
+ help() Display usage and help messages. \n\
+ defineClass(className) Define an extension using the Java class \n\
+ \ named with the string argument. \n\
+ \ Uses ScriptableObject.defineClass(). \n\
+ load(["foo.js", ...]) Load JavaScript source files named by \n\
+ \ string arguments. \n\
+ loadClass(className) Load a class named by a string argument. \n\
+ \ The class must be a script compiled to a \n\
+ \ class file. \n\
+ print([expr ...]) Evaluate and print expressions. \n\
+ quit() Quit the shell. \n\
+ version([number]) Get or set the JavaScript version number. \n\
+ gc() Runs the garbage collector.\n\
+ spawn(arg) Evaluate function or scriptname on a new thread \n\
+ sync(function) Creates a synchronized version of the function, \n\
+ \ where the synchronization object is "this" \n\
+ readFile(fileName [, encoding])\n\
+ \ Returns the content of the file as a string. \n\
+ \ Encoding of the string can be optionally specified. \n\
+ readUrl(url [, encoding]) \n\
+ \ Similar to readFile, reads the contents of the url.\n\
+ runCommand(name ...) Runs a specified shell command. Additional arguments are \n\
+ \ passed to the command \n\
+ seal(args ...) Seals the supplied objects \n\
+ toint32(arg) Converts the argument into a 32-bit integer \n\
+ serialize(obj, fileName) \n\
+ \ Serializes an object and saves it to a file \n\
+ deserialise(fileName) Reconstructs a serialized object \n\
+ environment Returns the current environment object \n\
+ history Displays the shell command history \n\
+ \n\
+ For full description of all available commands see shell.html in\n\
+ the docs directory of Rhino distribution.\n\
+
+msg.warning =\
+ warning: {0}
+
+msg.format1 =\
+ {0}
+
+msg.format2 =\
+ line {0}: {1}
+
+msg.format3 =\
+ "{0}", line {1}: {2}
+
+msg.uncaughtJSException =\
+ exception from uncaught JavaScript throw: {0}
+
+msg.uncaughtEcmaError =\
+ uncaught JavaScript runtime exception: {0}
+
+msg.jsc.bad.usage =\
+ Didn''t understand "{1}". \n\
+ For more information, try java {0} -h
+
+msg.jsc.usage =\
+Usage: java {0} [OPTION]... SOURCE...\n\
+Valid options are: \n\
+\ -version VERSION Use the specified language version.\n\
+\ VERSION should be one of 100|110|120|130|140|150|160|170.\n\
+\ -opt LEVEL Use optimization with the specified level.\n\
+\ LEVEL should be one of 0..9.\n\
+\ -debug, -g Include debug information.\n\
+\ -nosource Do not include source to function objects.\n\
+\ It makes f.toString() useless and violates ECMAScript\n\
+\ standard but makes generated classes smaller and\n\
+\ saves memory.\n\
+\ -o CLASSNAME Use specified name as the last component of the main\n\
+\ generated class name. When specified, only one script\n\
+\ SOURCE is allowed. If omitted, it defaults to source\n\
+\ name with stripped .js suffix.\n\
+\ -package PACKAGE Place generated classes in the specified package.\n\
+\ -d DIRECTORY Use DIRECTORY as destination directory for generated\n\
+\ classes. If omitted, it defaults to parent directory\n\
+\ of SOURCE.\n\
+\ -extends CLASS The main generated class will extend the specified\n\
+\ class CLASS.\n\
+\ -implements INTERFACE1,INTERFACE2,... The main generated class will\n\
+\ implement the specified list of interfaces.\n\
+\ -main-method-class CLASS Specify the class name used for main method \n\
+\ implementation. The class must have a method matching\n\
+\ "public static void main(Script sc, String[] args)"\n\
+\ -observe-instruction-count Generate code that contains callbacks to \n\
+\ accumulate counts of executed instructions. Code \n\
+\ compiled with this flag can be monitored using \n\
+\ Context.setInstructionObserverThreshold. \n\
+\ -help, --help, -h Print this help and exit.\n\
+
+
+msg.no.file =\
+ A file name must be specified to compile.
+
+msg.invalid.classfile.name =\
+ File "{0}" is not a valid class file name.
+
+msg.extension.not.js =\
+ File "{0}" is not a valid js file name.
+
+msg.jsfile.not.found=\
+ File "{0}" not found.
+
+msg.multiple.js.to.file =\
+ Cannot compile multiple js files to "{0}".
+
+msg.package.name =\
+ "{0}" is not a valid package name.
+
+msg.spawn.args =\
+ Argument to spawn() must be a function or script.
+
+msg.must.implement.Script =\
+ Argument to loadClass() must be the name of a class that implements \
+ the Script interface. Class files generated by compiling scripts \
+ will implement Script.
+
+msg.runCommand.bad.args =\
+ The first argument to runCommand must be a command name.
+
+msg.runCommand.bad.env =\
+ A value of the env property of option object for runCommnad must be an \
+ object.
+
+msg.shell.seal.not.object =\
+ seal function can only be applied to objects
+
+msg.shell.seal.not.scriptable =\
+ seal function supports only sealing of ScriptableObject instances
+
+msg.shell.readFile.bad.args =\
+ readFile require at least file path to be specified
+
+msg.shell.readUrl.bad.args =\
+ readUrl require at least file path to be specified
+
+msg.shell.bad.function.scope =\
+ Wrong scope object for shell function: {0}
+
+msg.idswitch.same_string =\
+ The string {0} is used second time in the switch code. \
+ Previous occurrence was at line {1}
+
+msg.idswitch.file_end_in_switch =\
+ End of file inside tag {0}
+
+msg.idswitch.bad_tag_order =\
+ String switch tag {0} is not allowed here
+
+msg.idswitch.no_end_with_value =\
+ End for tag {0} can not contain value
+
+msg.idswitch.no_value_allowed =\
+ Tag {0} can not contain value
+
+msg.idswitch.no_end_usage =\
+ Tag {0} can not be used as end tag
+
+msg.idswitch.no_file_argument =\
+ File argument should be given
+
+msg.idswitch.too_many_arguments =\
+ Too many arguments are given
+
+msg.idswitch.bad_option =\
+ Invalid option {0}
+
+msg.idswitch.bad_option_char =\
+ Invalid option letter {0}
+
+msg.idswitch.bad_invocation =\
+StringIdMap: {0}\n\
+For more information, try\n\
+java org.mozilla.javascript.tools.idswitch.StringIdMap --help
+
+msg.idswitch.io_error =\
+StringIdMap: IO error, {0}
+
+msg.idswitch.usage = \
+Usage: java org.mozilla.javascript.tools.idswitch.StringIdMap [OPTIONS] JAVA_SOURCE_FILE\n\
+Generates efficient string dispatch code in JAVA_SOURCE_FILE.\n\
+The resulting Java source fragment replaces the old dispatch code.\n\
+If JAVA_SOURCE_FILE is -, standard input is used for Java source and the\n\
+result is sent to standard output.\n\
+\n\
+\ -h, --help display this help and exit\n\
+\ --version display version information and exit\n\
+\n\
+Note: the original file will be overwritten without any backup actions\n\
+\ and all code inside #generated# tag will be replaced by new one.
+
+msg.idswitch.version = \
+org.mozilla.javascript.tools.idswitch.StringIdMap version 0.2
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ConsoleTextArea.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ConsoleTextArea.java
new file mode 100644
index 0000000..08cac62
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ConsoleTextArea.java
@@ -0,0 +1,300 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * See Beyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christopher Oliver
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.shell;
+import java.io.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.Document;
+import javax.swing.text.Segment;
+
+class ConsoleWrite implements Runnable {
+ private ConsoleTextArea textArea;
+ private String str;
+
+ public ConsoleWrite(ConsoleTextArea textArea, String str) {
+ this.textArea = textArea;
+ this.str = str;
+ }
+
+ public void run() {
+ textArea.write(str);
+ }
+}
+
+class ConsoleWriter extends java.io.OutputStream {
+
+ private ConsoleTextArea textArea;
+ private StringBuffer buffer;
+
+ public ConsoleWriter(ConsoleTextArea textArea) {
+ this.textArea = textArea;
+ buffer = new StringBuffer();
+ }
+
+ public synchronized void write(int ch) {
+ buffer.append((char)ch);
+ if(ch == '\n') {
+ flushBuffer();
+ }
+ }
+
+ public synchronized void write (char[] data, int off, int len) {
+ for(int i = off; i < len; i++) {
+ buffer.append(data[i]);
+ if(data[i] == '\n') {
+ flushBuffer();
+ }
+ }
+ }
+
+ public synchronized void flush() {
+ if (buffer.length() > 0) {
+ flushBuffer();
+ }
+ }
+
+ public void close () {
+ flush();
+ }
+
+ private void flushBuffer() {
+ String str = buffer.toString();
+ buffer.setLength(0);
+ SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));
+ }
+}
+
+public class ConsoleTextArea
+ extends JTextArea implements KeyListener, DocumentListener
+{
+ static final long serialVersionUID = 8557083244830872961L;
+
+ private ConsoleWriter console1;
+ private ConsoleWriter console2;
+ private PrintStream out;
+ private PrintStream err;
+ private PrintWriter inPipe;
+ private PipedInputStream in;
+ private java.util.Vector history;
+ private int historyIndex = -1;
+ private int outputMark = 0;
+
+ public void select(int start, int end) {
+ requestFocus();
+ super.select(start, end);
+ }
+
+ public ConsoleTextArea(String[] argv) {
+ super();
+ history = new java.util.Vector();
+ console1 = new ConsoleWriter(this);
+ console2 = new ConsoleWriter(this);
+ out = new PrintStream(console1);
+ err = new PrintStream(console2);
+ PipedOutputStream outPipe = new PipedOutputStream();
+ inPipe = new PrintWriter(outPipe);
+ in = new PipedInputStream();
+ try {
+ outPipe.connect(in);
+ } catch(IOException exc) {
+ exc.printStackTrace();
+ }
+ getDocument().addDocumentListener(this);
+ addKeyListener(this);
+ setLineWrap(true);
+ setFont(new Font("Monospaced", 0, 12));
+ }
+
+
+ synchronized void returnPressed() {
+ Document doc = getDocument();
+ int len = doc.getLength();
+ Segment segment = new Segment();
+ try {
+ doc.getText(outputMark, len - outputMark, segment);
+ } catch(javax.swing.text.BadLocationException ignored) {
+ ignored.printStackTrace();
+ }
+ if(segment.count > 0) {
+ history.addElement(segment.toString());
+ }
+ historyIndex = history.size();
+ inPipe.write(segment.array, segment.offset, segment.count);
+ append("\n");
+ outputMark = doc.getLength();
+ inPipe.write("\n");
+ inPipe.flush();
+ console1.flush();
+ }
+
+ public void eval(String str) {
+ inPipe.write(str);
+ inPipe.write("\n");
+ inPipe.flush();
+ console1.flush();
+ }
+
+ public void keyPressed(KeyEvent e) {
+ int code = e.getKeyCode();
+ if(code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
+ if(outputMark == getCaretPosition()) {
+ e.consume();
+ }
+ } else if(code == KeyEvent.VK_HOME) {
+ int caretPos = getCaretPosition();
+ if(caretPos == outputMark) {
+ e.consume();
+ } else if(caretPos > outputMark) {
+ if(!e.isControlDown()) {
+ if(e.isShiftDown()) {
+ moveCaretPosition(outputMark);
+ } else {
+ setCaretPosition(outputMark);
+ }
+ e.consume();
+ }
+ }
+ } else if(code == KeyEvent.VK_ENTER) {
+ returnPressed();
+ e.consume();
+ } else if(code == KeyEvent.VK_UP) {
+ historyIndex--;
+ if(historyIndex >= 0) {
+ if(historyIndex >= history.size()) {
+ historyIndex = history.size() -1;
+ }
+ if(historyIndex >= 0) {
+ String str = (String)history.elementAt(historyIndex);
+ int len = getDocument().getLength();
+ replaceRange(str, outputMark, len);
+ int caretPos = outputMark + str.length();
+ select(caretPos, caretPos);
+ } else {
+ historyIndex++;
+ }
+ } else {
+ historyIndex++;
+ }
+ e.consume();
+ } else if(code == KeyEvent.VK_DOWN) {
+ int caretPos = outputMark;
+ if(history.size() > 0) {
+ historyIndex++;
+ if(historyIndex < 0) {historyIndex = 0;}
+ int len = getDocument().getLength();
+ if(historyIndex < history.size()) {
+ String str = (String)history.elementAt(historyIndex);
+ replaceRange(str, outputMark, len);
+ caretPos = outputMark + str.length();
+ } else {
+ historyIndex = history.size();
+ replaceRange("", outputMark, len);
+ }
+ }
+ select(caretPos, caretPos);
+ e.consume();
+ }
+ }
+
+ public void keyTyped(KeyEvent e) {
+ int keyChar = e.getKeyChar();
+ if(keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) {
+ if(outputMark == getCaretPosition()) {
+ e.consume();
+ }
+ } else if(getCaretPosition() < outputMark) {
+ setCaretPosition(outputMark);
+ }
+ }
+
+ public synchronized void keyReleased(KeyEvent e) {
+ }
+
+ public synchronized void write(String str) {
+ insert(str, outputMark);
+ int len = str.length();
+ outputMark += len;
+ select(outputMark, outputMark);
+ }
+
+ public synchronized void insertUpdate(DocumentEvent e) {
+ int len = e.getLength();
+ int off = e.getOffset();
+ if(outputMark > off) {
+ outputMark += len;
+ }
+ }
+
+ public synchronized void removeUpdate(DocumentEvent e) {
+ int len = e.getLength();
+ int off = e.getOffset();
+ if(outputMark > off) {
+ if(outputMark >= off + len) {
+ outputMark -= len;
+ } else {
+ outputMark = off;
+ }
+ }
+ }
+
+ public synchronized void postUpdateUI() {
+ // this attempts to cleanup the damage done by updateComponentTreeUI
+ requestFocus();
+ setCaret(getCaret());
+ select(outputMark, outputMark);
+ }
+
+ public synchronized void changedUpdate(DocumentEvent e) {
+ }
+
+
+ public InputStream getIn() {
+ return in;
+ }
+
+ public PrintStream getOut() {
+ return out;
+ }
+
+ public PrintStream getErr() {
+ return err;
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Environment.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Environment.java
new file mode 100644
index 0000000..19904b9
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Environment.java
@@ -0,0 +1,141 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ Environment.java
+
+ Wraps java.lang.System properties.
+
+ by Patrick C. Beard <beard@netscape.com>
+ */
+
+package org.mozilla.javascript.tools.shell;
+
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptRuntime;
+import org.mozilla.javascript.ScriptableObject;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * Environment, intended to be instantiated at global scope, provides
+ * a natural way to access System properties from JavaScript.
+ *
+ * @author Patrick C. Beard
+ */
+public class Environment extends ScriptableObject
+{
+ static final long serialVersionUID = -430727378460177065L;
+
+ private Environment thePrototypeInstance = null;
+
+ public static void defineClass(ScriptableObject scope) {
+ try {
+ ScriptableObject.defineClass(scope, Environment.class);
+ } catch (Exception e) {
+ throw new Error(e.getMessage());
+ }
+ }
+
+ public String getClassName() {
+ return "Environment";
+ }
+
+ public Environment() {
+ if (thePrototypeInstance == null)
+ thePrototypeInstance = this;
+ }
+
+ public Environment(ScriptableObject scope) {
+ setParentScope(scope);
+ Object ctor = ScriptRuntime.getTopLevelProp(scope, "Environment");
+ if (ctor != null && ctor instanceof Scriptable) {
+ Scriptable s = (Scriptable) ctor;
+ setPrototype((Scriptable) s.get("prototype", s));
+ }
+ }
+
+ public boolean has(String name, Scriptable start) {
+ if (this == thePrototypeInstance)
+ return super.has(name, start);
+
+ return (System.getProperty(name) != null);
+ }
+
+ public Object get(String name, Scriptable start) {
+ if (this == thePrototypeInstance)
+ return super.get(name, start);
+
+ String result = System.getProperty(name);
+ if (result != null)
+ return ScriptRuntime.toObject(getParentScope(), result);
+ else
+ return Scriptable.NOT_FOUND;
+ }
+
+ public void put(String name, Scriptable start, Object value) {
+ if (this == thePrototypeInstance)
+ super.put(name, start, value);
+ else
+ System.getProperties().put(name, ScriptRuntime.toString(value));
+ }
+
+ private Object[] collectIds() {
+ Properties props = System.getProperties();
+ Enumeration names = props.propertyNames();
+ Vector keys = new Vector();
+ while (names.hasMoreElements())
+ keys.addElement(names.nextElement());
+ Object[] ids = new Object[keys.size()];
+ keys.copyInto(ids);
+ return ids;
+ }
+
+ public Object[] getIds() {
+ if (this == thePrototypeInstance)
+ return super.getIds();
+ return collectIds();
+ }
+
+ public Object[] getAllIds() {
+ if (this == thePrototypeInstance)
+ return super.getAllIds();
+ return collectIds();
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Global.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Global.java
new file mode 100644
index 0000000..fdb8f4e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Global.java
@@ -0,0 +1,1038 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ * Igor Bukanov
+ * Norris Boyd
+ * Rob Ginda
+ * Kurt Westerfeld
+ * Matthias Radestock
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import java.io.*;
+import java.net.*;
+import java.lang.reflect.*;
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+import org.mozilla.javascript.serialize.*;
+
+/**
+ * This class provides for sharing functions across multiple threads.
+ * This is of particular interest to server applications.
+ *
+ * @author Norris Boyd
+ */
+public class Global extends ImporterTopLevel
+{
+ static final long serialVersionUID = 4029130780977538005L;
+
+ NativeArray history;
+ private InputStream inStream;
+ private PrintStream outStream;
+ private PrintStream errStream;
+ private boolean sealedStdLib = false;
+ boolean initialized;
+ private QuitAction quitAction;
+ private String[] prompts = { "js> ", " > " };
+
+ public Global()
+ {
+ }
+
+ public Global(Context cx)
+ {
+ init(cx);
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ /**
+ * Set the action to call from quit().
+ */
+ public void initQuitAction(QuitAction quitAction)
+ {
+ if (quitAction == null)
+ throw new IllegalArgumentException("quitAction is null");
+ if (this.quitAction != null)
+ throw new IllegalArgumentException("The method is once-call.");
+
+ this.quitAction = quitAction;
+ }
+
+ public void init(ContextFactory factory)
+ {
+ factory.call(new ContextAction() {
+ public Object run(Context cx)
+ {
+ init(cx);
+ return null;
+ }
+ });
+ }
+
+ public void init(Context cx)
+ {
+ // Define some global functions particular to the shell. Note
+ // that these functions are not part of ECMA.
+ initStandardObjects(cx, sealedStdLib);
+ String[] names = {
+ "defineClass",
+ "deserialize",
+ "gc",
+ "help",
+ "load",
+ "loadClass",
+ "print",
+ "quit",
+ "readFile",
+ "readUrl",
+ "runCommand",
+ "seal",
+ "serialize",
+ "spawn",
+ "sync",
+ "toint32",
+ "version",
+ };
+ defineFunctionProperties(names, Global.class,
+ ScriptableObject.DONTENUM);
+
+ // Set up "environment" in the global scope to provide access to the
+ // System environment variables.
+ Environment.defineClass(this);
+ Environment environment = new Environment(this);
+ defineProperty("environment", environment,
+ ScriptableObject.DONTENUM);
+
+ history = (NativeArray) cx.newArray(this, 0);
+ defineProperty("history", history, ScriptableObject.DONTENUM);
+ initialized = true;
+ }
+
+ /**
+ * Print a help message.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public static void help(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ PrintStream out = getInstance(funObj).getOut();
+ out.println(ToolErrorReporter.getMessage("msg.help"));
+ }
+
+ public static void gc(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ System.gc();
+ }
+
+
+ /**
+ * Print the string values of its arguments.
+ *
+ * This method is defined as a JavaScript function.
+ * Note that its arguments are of the "varargs" form, which
+ * allows it to handle an arbitrary number of arguments
+ * supplied to the JavaScript function.
+ *
+ */
+ public static Object print(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ PrintStream out = getInstance(funObj).getOut();
+ for (int i=0; i < args.length; i++) {
+ if (i > 0)
+ out.print(" ");
+
+ // Convert the arbitrary JavaScript value into a string form.
+ String s = Context.toString(args[i]);
+
+ out.print(s);
+ }
+ out.println();
+ return Context.getUndefinedValue();
+ }
+
+ /**
+ * Call embedding-specific quit action passing its argument as
+ * int32 exit code.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public static void quit(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ Global global = getInstance(funObj);
+ if (global.quitAction != null) {
+ int exitCode = (args.length == 0 ? 0
+ : ScriptRuntime.toInt32(args[0]));
+ global.quitAction.quit(cx, exitCode);
+ }
+ }
+
+ /**
+ * Get and set the language version.
+ *
+ * This method is defined as a JavaScript function.
+ */
+ public static double version(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ double result = cx.getLanguageVersion();
+ if (args.length > 0) {
+ double d = Context.toNumber(args[0]);
+ cx.setLanguageVersion((int) d);
+ }
+ return result;
+ }
+
+ /**
+ * Load and execute a set of JavaScript source files.
+ *
+ * This method is defined as a JavaScript function.
+ *
+ */
+ public static void load(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ {
+ for (int i = 0; i < args.length; i++) {
+ Main.processFile(cx, thisObj, Context.toString(args[i]));
+ }
+ }
+
+ /**
+ * Load a Java class that defines a JavaScript object using the
+ * conventions outlined in ScriptableObject.defineClass.
+ * <p>
+ * This method is defined as a JavaScript function.
+ * @exception IllegalAccessException if access is not available
+ * to a reflected class member
+ * @exception InstantiationException if unable to instantiate
+ * the named class
+ * @exception InvocationTargetException if an exception is thrown
+ * during execution of methods of the named class
+ * @see org.mozilla.javascript.ScriptableObject#defineClass(Scriptable,Class)
+ */
+ public static void defineClass(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IllegalAccessException, InstantiationException,
+ InvocationTargetException
+ {
+ Class clazz = getClass(args);
+ ScriptableObject.defineClass(thisObj, clazz);
+ }
+
+ /**
+ * Load and execute a script compiled to a class file.
+ * <p>
+ * This method is defined as a JavaScript function.
+ * When called as a JavaScript function, a single argument is
+ * expected. This argument should be the name of a class that
+ * implements the Script interface, as will any script
+ * compiled by jsc.
+ *
+ * @exception IllegalAccessException if access is not available
+ * to the class
+ * @exception InstantiationException if unable to instantiate
+ * the named class
+ */
+ public static void loadClass(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IllegalAccessException, InstantiationException
+ {
+ Class clazz = getClass(args);
+ if (!Script.class.isAssignableFrom(clazz)) {
+ throw reportRuntimeError("msg.must.implement.Script");
+ }
+ Script script = (Script) clazz.newInstance();
+ script.exec(cx, thisObj);
+ }
+
+ private static Class getClass(Object[] args) {
+ if (args.length == 0) {
+ throw reportRuntimeError("msg.expected.string.arg");
+ }
+ Object arg0 = args[0];
+ if (arg0 instanceof Wrapper) {
+ Object wrapped = ((Wrapper)arg0).unwrap();
+ if (wrapped instanceof Class)
+ return (Class)wrapped;
+ }
+ String className = Context.toString(args[0]);
+ try {
+ return Class.forName(className);
+ }
+ catch (ClassNotFoundException cnfe) {
+ throw reportRuntimeError("msg.class.not.found", className);
+ }
+ }
+
+ public static void serialize(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IOException
+ {
+ if (args.length < 2) {
+ throw Context.reportRuntimeError(
+ "Expected an object to serialize and a filename to write " +
+ "the serialization to");
+ }
+ Object obj = args[0];
+ String filename = Context.toString(args[1]);
+ FileOutputStream fos = new FileOutputStream(filename);
+ Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
+ ScriptableOutputStream out = new ScriptableOutputStream(fos, scope);
+ out.writeObject(obj);
+ out.close();
+ }
+
+ public static Object deserialize(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IOException, ClassNotFoundException
+ {
+ if (args.length < 1) {
+ throw Context.reportRuntimeError(
+ "Expected a filename to read the serialization from");
+ }
+ String filename = Context.toString(args[0]);
+ FileInputStream fis = new FileInputStream(filename);
+ Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
+ ObjectInputStream in = new ScriptableInputStream(fis, scope);
+ Object deserialized = in.readObject();
+ in.close();
+ return Context.toObject(deserialized, scope);
+ }
+
+ public String[] getPrompts(Context cx) {
+ if (ScriptableObject.hasProperty(this, "prompts")) {
+ Object promptsJS = ScriptableObject.getProperty(this,
+ "prompts");
+ if (promptsJS instanceof Scriptable) {
+ Scriptable s = (Scriptable) promptsJS;
+ if (ScriptableObject.hasProperty(s, 0) &&
+ ScriptableObject.hasProperty(s, 1))
+ {
+ Object elem0 = ScriptableObject.getProperty(s, 0);
+ if (elem0 instanceof Function) {
+ elem0 = ((Function) elem0).call(cx, this, s,
+ new Object[0]);
+ }
+ prompts[0] = Context.toString(elem0);
+ Object elem1 = ScriptableObject.getProperty(s, 1);
+ if (elem1 instanceof Function) {
+ elem1 = ((Function) elem1).call(cx, this, s,
+ new Object[0]);
+ }
+ prompts[1] = Context.toString(elem1);
+ }
+ }
+ }
+ return prompts;
+ }
+
+ /**
+ * The spawn function runs a given function or script in a different
+ * thread.
+ *
+ * js> function g() { a = 7; }
+ * js> a = 3;
+ * 3
+ * js> spawn(g)
+ * Thread[Thread-1,5,main]
+ * js> a
+ * 3
+ */
+ public static Object spawn(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ {
+ Scriptable scope = funObj.getParentScope();
+ Runner runner;
+ if (args.length != 0 && args[0] instanceof Function) {
+ Object[] newArgs = null;
+ if (args.length > 1 && args[1] instanceof Scriptable) {
+ newArgs = cx.getElements((Scriptable) args[1]);
+ }
+ if (newArgs == null) { newArgs = ScriptRuntime.emptyArgs; }
+ runner = new Runner(scope, (Function) args[0], newArgs);
+ } else if (args.length != 0 && args[0] instanceof Script) {
+ runner = new Runner(scope, (Script) args[0]);
+ } else {
+ throw reportRuntimeError("msg.spawn.args");
+ }
+ runner.factory = cx.getFactory();
+ Thread thread = new Thread(runner);
+ thread.start();
+ return thread;
+ }
+
+ /**
+ * The sync function creates a synchronized function (in the sense
+ * of a Java synchronized method) from an existing function. The
+ * new function synchronizes on the <code>this</code> object of
+ * its invocation.
+ * js> var o = { f : sync(function(x) {
+ * print("entry");
+ * Packages.java.lang.Thread.sleep(x*1000);
+ * print("exit");
+ * })};
+ * js> spawn(function() {o.f(5);});
+ * Thread[Thread-0,5,main]
+ * entry
+ * js> spawn(function() {o.f(5);});
+ * Thread[Thread-1,5,main]
+ * js>
+ * exit
+ * entry
+ * exit
+ */
+ public static Object sync(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ {
+ if (args.length == 1 && args[0] instanceof Function) {
+ return new Synchronizer((Function)args[0]);
+ }
+ else {
+ throw reportRuntimeError("msg.sync.args");
+ }
+ }
+
+ /**
+ * Execute the specified command with the given argument and options
+ * as a separate process and return the exit status of the process.
+ * <p>
+ * Usage:
+ * <pre>
+ * runCommand(command)
+ * runCommand(command, arg1, ..., argN)
+ * runCommand(command, arg1, ..., argN, options)
+ * </pre>
+ * All except the last arguments to runCommand are converted to strings
+ * and denote command name and its arguments. If the last argument is a
+ * JavaScript object, it is an option object. Otherwise it is converted to
+ * string denoting the last argument and options objects assumed to be
+ * empty.
+ * Te following properties of the option object are processed:
+ * <ul>
+ * <li><tt>args</tt> - provides an array of additional command arguments
+ * <li><tt>env</tt> - explicit environment object. All its enumeratable
+ * properties define the corresponding environment variable names.
+ * <li><tt>input</tt> - the process input. If it is not
+ * java.io.InputStream, it is converted to string and sent to the process
+ * as its input. If not specified, no input is provided to the process.
+ * <li><tt>output</tt> - the process output instead of
+ * java.lang.System.out. If it is not instance of java.io.OutputStream,
+ * the process output is read, converted to a string, appended to the
+ * output property value converted to string and put as the new value of
+ * the output property.
+ * <li><tt>err</tt> - the process error output instead of
+ * java.lang.System.err. If it is not instance of java.io.OutputStream,
+ * the process error output is read, converted to a string, appended to
+ * the err property value converted to string and put as the new
+ * value of the err property.
+ * </ul>
+ */
+ public static Object runCommand(Context cx, Scriptable thisObj,
+ Object[] args, Function funObj)
+ throws IOException
+ {
+ int L = args.length;
+ if (L == 0 || (L == 1 && args[0] instanceof Scriptable)) {
+ throw reportRuntimeError("msg.runCommand.bad.args");
+ }
+
+ InputStream in = null;
+ OutputStream out = null, err = null;
+ ByteArrayOutputStream outBytes = null, errBytes = null;
+ Object outObj = null, errObj = null;
+ String[] environment = null;
+ Scriptable params = null;
+ Object[] addArgs = null;
+ if (args[L - 1] instanceof Scriptable) {
+ params = (Scriptable)args[L - 1];
+ --L;
+ Object envObj = ScriptableObject.getProperty(params, "env");
+ if (envObj != Scriptable.NOT_FOUND) {
+ if (envObj == null) {
+ environment = new String[0];
+ } else {
+ if (!(envObj instanceof Scriptable)) {
+ throw reportRuntimeError("msg.runCommand.bad.env");
+ }
+ Scriptable envHash = (Scriptable)envObj;
+ Object[] ids = ScriptableObject.getPropertyIds(envHash);
+ environment = new String[ids.length];
+ for (int i = 0; i != ids.length; ++i) {
+ Object keyObj = ids[i], val;
+ String key;
+ if (keyObj instanceof String) {
+ key = (String)keyObj;
+ val = ScriptableObject.getProperty(envHash, key);
+ } else {
+ int ikey = ((Number)keyObj).intValue();
+ key = Integer.toString(ikey);
+ val = ScriptableObject.getProperty(envHash, ikey);
+ }
+ if (val == ScriptableObject.NOT_FOUND) {
+ val = Undefined.instance;
+ }
+ environment[i] = key+'='+ScriptRuntime.toString(val);
+ }
+ }
+ }
+ Object inObj = ScriptableObject.getProperty(params, "input");
+ if (inObj != Scriptable.NOT_FOUND) {
+ in = toInputStream(inObj);
+ }
+ outObj = ScriptableObject.getProperty(params, "output");
+ if (outObj != Scriptable.NOT_FOUND) {
+ out = toOutputStream(outObj);
+ if (out == null) {
+ outBytes = new ByteArrayOutputStream();
+ out = outBytes;
+ }
+ }
+ errObj = ScriptableObject.getProperty(params, "err");
+ if (errObj != Scriptable.NOT_FOUND) {
+ err = toOutputStream(errObj);
+ if (err == null) {
+ errBytes = new ByteArrayOutputStream();
+ err = errBytes;
+ }
+ }
+ Object addArgsObj = ScriptableObject.getProperty(params, "args");
+ if (addArgsObj != Scriptable.NOT_FOUND) {
+ Scriptable s = Context.toObject(addArgsObj,
+ getTopLevelScope(thisObj));
+ addArgs = cx.getElements(s);
+ }
+ }
+ Global global = getInstance(funObj);
+ if (out == null) {
+ out = (global != null) ? global.getOut() : System.out;
+ }
+ if (err == null) {
+ err = (global != null) ? global.getErr() : System.err;
+ }
+ // If no explicit input stream, do not send any input to process,
+ // in particular, do not use System.in to avoid deadlocks
+ // when waiting for user input to send to process which is already
+ // terminated as it is not always possible to interrupt read method.
+
+ String[] cmd = new String[(addArgs == null) ? L : L + addArgs.length];
+ for (int i = 0; i != L; ++i) {
+ cmd[i] = ScriptRuntime.toString(args[i]);
+ }
+ if (addArgs != null) {
+ for (int i = 0; i != addArgs.length; ++i) {
+ cmd[L + i] = ScriptRuntime.toString(addArgs[i]);
+ }
+ }
+
+ int exitCode = runProcess(cmd, environment, in, out, err);
+ if (outBytes != null) {
+ String s = ScriptRuntime.toString(outObj) + outBytes.toString();
+ ScriptableObject.putProperty(params, "output", s);
+ }
+ if (errBytes != null) {
+ String s = ScriptRuntime.toString(errObj) + errBytes.toString();
+ ScriptableObject.putProperty(params, "err", s);
+ }
+
+ return new Integer(exitCode);
+ }
+
+ /**
+ * The seal function seals all supplied arguments.
+ */
+ public static void seal(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ {
+ for (int i = 0; i != args.length; ++i) {
+ Object arg = args[i];
+ if (!(arg instanceof ScriptableObject) || arg == Undefined.instance)
+ {
+ if (!(arg instanceof Scriptable) || arg == Undefined.instance)
+ {
+ throw reportRuntimeError("msg.shell.seal.not.object");
+ } else {
+ throw reportRuntimeError("msg.shell.seal.not.scriptable");
+ }
+ }
+ }
+
+ for (int i = 0; i != args.length; ++i) {
+ Object arg = args[i];
+ ((ScriptableObject)arg).sealObject();
+ }
+ }
+
+ /**
+ * The readFile reads the given file content and convert it to a string
+ * using the specified character coding or default character coding if
+ * explicit coding argument is not given.
+ * <p>
+ * Usage:
+ * <pre>
+ * readFile(filePath)
+ * readFile(filePath, charCoding)
+ * </pre>
+ * The first form converts file's context to string using the default
+ * character coding.
+ */
+ public static Object readFile(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ throws IOException
+ {
+ if (args.length == 0) {
+ throw reportRuntimeError("msg.shell.readFile.bad.args");
+ }
+ String path = ScriptRuntime.toString(args[0]);
+ String charCoding = null;
+ if (args.length >= 2) {
+ charCoding = ScriptRuntime.toString(args[1]);
+ }
+
+ return readUrl(path, charCoding, true);
+ }
+
+ /**
+ * The readUrl opens connection to the given URL, read all its data
+ * and converts them to a string
+ * using the specified character coding or default character coding if
+ * explicit coding argument is not given.
+ * <p>
+ * Usage:
+ * <pre>
+ * readUrl(url)
+ * readUrl(url, charCoding)
+ * </pre>
+ * The first form converts file's context to string using the default
+ * charCoding.
+ */
+ public static Object readUrl(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ throws IOException
+ {
+ if (args.length == 0) {
+ throw reportRuntimeError("msg.shell.readUrl.bad.args");
+ }
+ String url = ScriptRuntime.toString(args[0]);
+ String charCoding = null;
+ if (args.length >= 2) {
+ charCoding = ScriptRuntime.toString(args[1]);
+ }
+
+ return readUrl(url, charCoding, false);
+ }
+
+ /**
+ * Convert the argumnet to int32 number.
+ */
+ public static Object toint32(Context cx, Scriptable thisObj, Object[] args,
+ Function funObj)
+ {
+ Object arg = (args.length != 0 ? args[0] : Undefined.instance);
+ if (arg instanceof Integer)
+ return arg;
+ return ScriptRuntime.wrapInt(ScriptRuntime.toInt32(arg));
+ }
+
+ public InputStream getIn() {
+ return inStream == null ? System.in : inStream;
+ }
+
+ public void setIn(InputStream in) {
+ inStream = in;
+ }
+
+ public PrintStream getOut() {
+ return outStream == null ? System.out : outStream;
+ }
+
+ public void setOut(PrintStream out) {
+ outStream = out;
+ }
+
+ public PrintStream getErr() {
+ return errStream == null ? System.err : errStream;
+ }
+
+ public void setErr(PrintStream err) {
+ errStream = err;
+ }
+
+ public void setSealedStdLib(boolean value)
+ {
+ sealedStdLib = value;
+ }
+
+ private static Global getInstance(Function function)
+ {
+ Scriptable scope = function.getParentScope();
+ if (!(scope instanceof Global))
+ throw reportRuntimeError("msg.bad.shell.function.scope",
+ String.valueOf(scope));
+ return (Global)scope;
+ }
+
+ /**
+ * Runs the given process using Runtime.exec().
+ * If any of in, out, err is null, the corresponding process stream will
+ * be closed immediately, otherwise it will be closed as soon as
+ * all data will be read from/written to process
+ *
+ * @return Exit value of process.
+ * @throws IOException If there was an error executing the process.
+ */
+ private static int runProcess(String[] cmd, String[] environment,
+ InputStream in, OutputStream out,
+ OutputStream err)
+ throws IOException
+ {
+ Process p;
+ if (environment == null) {
+ p = Runtime.getRuntime().exec(cmd);
+ } else {
+ p = Runtime.getRuntime().exec(cmd, environment);
+ }
+
+ try {
+ PipeThread inThread = null;
+ if (in != null) {
+ inThread = new PipeThread(false, in, p.getOutputStream());
+ inThread.start();
+ } else {
+ p.getOutputStream().close();
+ }
+
+ PipeThread outThread = null;
+ if (out != null) {
+ outThread = new PipeThread(true, p.getInputStream(), out);
+ outThread.start();
+ } else {
+ p.getInputStream().close();
+ }
+
+ PipeThread errThread = null;
+ if (err != null) {
+ errThread = new PipeThread(true, p.getErrorStream(), err);
+ errThread.start();
+ } else {
+ p.getErrorStream().close();
+ }
+
+ // wait for process completion
+ for (;;) {
+ try {
+ p.waitFor();
+ if (outThread != null) {
+ outThread.join();
+ }
+ if (inThread != null) {
+ inThread.join();
+ }
+ if (errThread != null) {
+ errThread.join();
+ }
+ break;
+ } catch (InterruptedException ignore) {
+ }
+ }
+
+ return p.exitValue();
+ } finally {
+ p.destroy();
+ }
+ }
+
+ static void pipe(boolean fromProcess, InputStream from, OutputStream to)
+ throws IOException
+ {
+ try {
+ final int SIZE = 4096;
+ byte[] buffer = new byte[SIZE];
+ for (;;) {
+ int n;
+ if (!fromProcess) {
+ n = from.read(buffer, 0, SIZE);
+ } else {
+ try {
+ n = from.read(buffer, 0, SIZE);
+ } catch (IOException ex) {
+ // Ignore exception as it can be cause by closed pipe
+ break;
+ }
+ }
+ if (n < 0) { break; }
+ if (fromProcess) {
+ to.write(buffer, 0, n);
+ to.flush();
+ } else {
+ try {
+ to.write(buffer, 0, n);
+ to.flush();
+ } catch (IOException ex) {
+ // Ignore exception as it can be cause by closed pipe
+ break;
+ }
+ }
+ }
+ } finally {
+ try {
+ if (fromProcess) {
+ from.close();
+ } else {
+ to.close();
+ }
+ } catch (IOException ex) {
+ // Ignore errors on close. On Windows JVM may throw invalid
+ // refrence exception if process terminates too fast.
+ }
+ }
+ }
+
+ private static InputStream toInputStream(Object value)
+ throws IOException
+ {
+ InputStream is = null;
+ String s = null;
+ if (value instanceof Wrapper) {
+ Object unwrapped = ((Wrapper)value).unwrap();
+ if (unwrapped instanceof InputStream) {
+ is = (InputStream)unwrapped;
+ } else if (unwrapped instanceof byte[]) {
+ is = new ByteArrayInputStream((byte[])unwrapped);
+ } else if (unwrapped instanceof Reader) {
+ s = readReader((Reader)unwrapped);
+ } else if (unwrapped instanceof char[]) {
+ s = new String((char[])unwrapped);
+ }
+ }
+ if (is == null) {
+ if (s == null) { s = ScriptRuntime.toString(value); }
+ is = new ByteArrayInputStream(s.getBytes());
+ }
+ return is;
+ }
+
+ private static OutputStream toOutputStream(Object value) {
+ OutputStream os = null;
+ if (value instanceof Wrapper) {
+ Object unwrapped = ((Wrapper)value).unwrap();
+ if (unwrapped instanceof OutputStream) {
+ os = (OutputStream)unwrapped;
+ }
+ }
+ return os;
+ }
+
+ private static String readUrl(String filePath, String charCoding,
+ boolean urlIsFile)
+ throws IOException
+ {
+ int chunkLength;
+ InputStream is = null;
+ try {
+ if (!urlIsFile) {
+ URL urlObj = new URL(filePath);
+ URLConnection uc = urlObj.openConnection();
+ is = uc.getInputStream();
+ chunkLength = uc.getContentLength();
+ if (chunkLength <= 0)
+ chunkLength = 1024;
+ if (charCoding == null) {
+ String type = uc.getContentType();
+ if (type != null) {
+ charCoding = getCharCodingFromType(type);
+ }
+ }
+ } else {
+ File f = new File(filePath);
+
+ long length = f.length();
+ chunkLength = (int)length;
+ if (chunkLength != length)
+ throw new IOException("Too big file size: "+length);
+
+ if (chunkLength == 0) { return ""; }
+
+ is = new FileInputStream(f);
+ }
+
+ Reader r;
+ if (charCoding == null) {
+ r = new InputStreamReader(is);
+ } else {
+ r = new InputStreamReader(is, charCoding);
+ }
+ return readReader(r, chunkLength);
+
+ } finally {
+ if (is != null)
+ is.close();
+ }
+ }
+
+ private static String getCharCodingFromType(String type)
+ {
+ int i = type.indexOf(';');
+ if (i >= 0) {
+ int end = type.length();
+ ++i;
+ while (i != end && type.charAt(i) <= ' ') {
+ ++i;
+ }
+ String charset = "charset";
+ if (charset.regionMatches(true, 0, type, i, charset.length()))
+ {
+ i += charset.length();
+ while (i != end && type.charAt(i) <= ' ') {
+ ++i;
+ }
+ if (i != end && type.charAt(i) == '=') {
+ ++i;
+ while (i != end && type.charAt(i) <= ' ') {
+ ++i;
+ }
+ if (i != end) {
+ // i is at the start of non-empty
+ // charCoding spec
+ while (type.charAt(end -1) <= ' ') {
+ --end;
+ }
+ return type.substring(i, end);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String readReader(Reader reader)
+ throws IOException
+ {
+ return readReader(reader, 4096);
+ }
+
+ private static String readReader(Reader reader, int initialBufferSize)
+ throws IOException
+ {
+ char[] buffer = new char[initialBufferSize];
+ int offset = 0;
+ for (;;) {
+ int n = reader.read(buffer, offset, buffer.length - offset);
+ if (n < 0) { break; }
+ offset += n;
+ if (offset == buffer.length) {
+ char[] tmp = new char[buffer.length * 2];
+ System.arraycopy(buffer, 0, tmp, 0, offset);
+ buffer = tmp;
+ }
+ }
+ return new String(buffer, 0, offset);
+ }
+
+ static RuntimeException reportRuntimeError(String msgId) {
+ String message = ToolErrorReporter.getMessage(msgId);
+ return Context.reportRuntimeError(message);
+ }
+
+ static RuntimeException reportRuntimeError(String msgId, String msgArg)
+ {
+ String message = ToolErrorReporter.getMessage(msgId, msgArg);
+ return Context.reportRuntimeError(message);
+ }
+}
+
+
+class Runner implements Runnable, ContextAction {
+
+ Runner(Scriptable scope, Function func, Object[] args) {
+ this.scope = scope;
+ f = func;
+ this.args = args;
+ }
+
+ Runner(Scriptable scope, Script script) {
+ this.scope = scope;
+ s = script;
+ }
+
+ public void run()
+ {
+ factory.call(this);
+ }
+
+ public Object run(Context cx)
+ {
+ if (f != null)
+ return f.call(cx, scope, scope, args);
+ else
+ return s.exec(cx, scope);
+ }
+
+ ContextFactory factory;
+ private Scriptable scope;
+ private Function f;
+ private Script s;
+ private Object[] args;
+}
+
+class PipeThread extends Thread {
+
+ PipeThread(boolean fromProcess, InputStream from, OutputStream to) {
+ setDaemon(true);
+ this.fromProcess = fromProcess;
+ this.from = from;
+ this.to = to;
+ }
+
+ public void run() {
+ try {
+ Global.pipe(fromProcess, from, to);
+ } catch (IOException ex) {
+ throw Context.throwAsScriptRuntimeEx(ex);
+ }
+ }
+
+ private boolean fromProcess;
+ private InputStream from;
+ private OutputStream to;
+}
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JSConsole.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JSConsole.java
new file mode 100644
index 0000000..f6fe3a1
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JSConsole.java
@@ -0,0 +1,225 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino JavaScript Debugger code, released
+ * November 21, 2000.
+ *
+ * The Initial Developer of the Original Code is
+ * See Beyond Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christopher Oliver
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+package org.mozilla.javascript.tools.shell;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+import org.mozilla.javascript.SecurityUtilities;
+
+public class JSConsole extends JFrame implements ActionListener
+{
+ static final long serialVersionUID = 2551225560631876300L;
+
+ private File CWD;
+ private JFileChooser dlg;
+ private ConsoleTextArea consoleTextArea;
+
+ public String chooseFile() {
+ if(CWD == null) {
+ String dir = SecurityUtilities.getSystemProperty("user.dir");
+ if(dir != null) {
+ CWD = new File(dir);
+ }
+ }
+ if(CWD != null) {
+ dlg.setCurrentDirectory(CWD);
+ }
+ dlg.setDialogTitle("Select a file to load");
+ int returnVal = dlg.showOpenDialog(this);
+ if(returnVal == JFileChooser.APPROVE_OPTION) {
+ String result = dlg.getSelectedFile().getPath();
+ CWD = new File(dlg.getSelectedFile().getParent());
+ return result;
+ }
+ return null;
+ }
+
+ public static void main(String args[]) {
+ new JSConsole(args);
+ }
+
+ public void createFileChooser() {
+ dlg = new JFileChooser();
+ javax.swing.filechooser.FileFilter filter =
+ new javax.swing.filechooser.FileFilter() {
+ public boolean accept(File f) {
+ if(f.isDirectory()) {
+ return true;
+ }
+ String name = f.getName();
+ int i = name.lastIndexOf('.');
+ if(i > 0 && i < name.length() -1) {
+ String ext = name.substring(i + 1).toLowerCase();
+ if(ext.equals("js")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ return "JavaScript Files (*.js)";
+ }
+ };
+ dlg.addChoosableFileFilter(filter);
+
+ }
+
+ public JSConsole(String[] args) {
+ super("Rhino JavaScript Console");
+ JMenuBar menubar = new JMenuBar();
+ createFileChooser();
+ String[] fileItems = {"Load...", "Exit"};
+ String[] fileCmds = {"Load", "Exit"};
+ char[] fileShortCuts = {'L', 'X'};
+ String[] editItems = {"Cut", "Copy", "Paste"};
+ char[] editShortCuts = {'T', 'C', 'P'};
+ String[] plafItems = {"Metal", "Windows", "Motif"};
+ boolean [] plafState = {true, false, false};
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.setMnemonic('F');
+ JMenu editMenu = new JMenu("Edit");
+ editMenu.setMnemonic('E');
+ JMenu plafMenu = new JMenu("Platform");
+ plafMenu.setMnemonic('P');
+ for(int i = 0; i < fileItems.length; ++i) {
+ JMenuItem item = new JMenuItem(fileItems[i],
+ fileShortCuts[i]);
+ item.setActionCommand(fileCmds[i]);
+ item.addActionListener(this);
+ fileMenu.add(item);
+ }
+ for(int i = 0; i < editItems.length; ++i) {
+ JMenuItem item = new JMenuItem(editItems[i],
+ editShortCuts[i]);
+ item.addActionListener(this);
+ editMenu.add(item);
+ }
+ ButtonGroup group = new ButtonGroup();
+ for(int i = 0; i < plafItems.length; ++i) {
+ JRadioButtonMenuItem item = new JRadioButtonMenuItem(plafItems[i],
+ plafState[i]);
+ group.add(item);
+ item.addActionListener(this);
+ plafMenu.add(item);
+ }
+ menubar.add(fileMenu);
+ menubar.add(editMenu);
+ menubar.add(plafMenu);
+ setJMenuBar(menubar);
+ consoleTextArea = new ConsoleTextArea(args);
+ JScrollPane scroller = new JScrollPane(consoleTextArea);
+ setContentPane(scroller);
+ consoleTextArea.setRows(24);
+ consoleTextArea.setColumns(80);
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+ pack();
+ setVisible(true);
+ // System.setIn(consoleTextArea.getIn());
+ // System.setOut(consoleTextArea.getOut());
+ // System.setErr(consoleTextArea.getErr());
+ Main.setIn(consoleTextArea.getIn());
+ Main.setOut(consoleTextArea.getOut());
+ Main.setErr(consoleTextArea.getErr());
+ Main.main(args);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String cmd = e.getActionCommand();
+ String plaf_name = null;
+ if(cmd.equals("Load")) {
+ String f = chooseFile();
+ if(f != null) {
+ f = f.replace('\\', '/');
+ consoleTextArea.eval("load(\"" + f + "\");");
+ }
+ } else if(cmd.equals("Exit")) {
+ System.exit(0);
+ } else if(cmd.equals("Cut")) {
+ consoleTextArea.cut();
+ } else if(cmd.equals("Copy")) {
+ consoleTextArea.copy();
+ } else if(cmd.equals("Paste")) {
+ consoleTextArea.paste();
+ } else {
+ if(cmd.equals("Metal")) {
+ plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
+ } else if(cmd.equals("Windows")) {
+ plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
+ } else if(cmd.equals("Motif")) {
+ plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
+ }
+ if(plaf_name != null) {
+ try {
+ UIManager.setLookAndFeel(plaf_name);
+ SwingUtilities.updateComponentTreeUI(this);
+ consoleTextArea.postUpdateUI();
+ // updateComponentTreeUI seems to mess up the file
+ // chooser dialog, so just create a new one
+ createFileChooser();
+ } catch(Exception exc) {
+ JOptionPane.showMessageDialog(this,
+ exc.getMessage(),
+ "Platform",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java
new file mode 100644
index 0000000..de39a5e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java
@@ -0,0 +1,240 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import java.security.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.mozilla.javascript.*;
+
+public class JavaPolicySecurity extends SecurityProxy
+{
+
+ public Class getStaticSecurityDomainClassInternal() {
+ return ProtectionDomain.class;
+ }
+
+ private static class Loader extends ClassLoader
+ implements GeneratedClassLoader
+ {
+ private ProtectionDomain domain;
+
+ Loader(ClassLoader parent, ProtectionDomain domain) {
+ super(parent != null ? parent : getSystemClassLoader());
+ this.domain = domain;
+ }
+
+ public Class defineClass(String name, byte[] data) {
+ return super.defineClass(name, data, 0, data.length, domain);
+ }
+
+ public void linkClass(Class cl) {
+ resolveClass(cl);
+ }
+ }
+
+ private static class ContextPermissions extends PermissionCollection
+ {
+ static final long serialVersionUID = -1721494496320750721L;
+
+// Construct PermissionCollection that permits an action only
+// if it is permitted by staticDomain and by security context of Java stack on
+// the moment of constructor invocation
+ ContextPermissions(ProtectionDomain staticDomain) {
+ _context = AccessController.getContext();
+ if (staticDomain != null) {
+ _statisPermissions = staticDomain.getPermissions();
+ }
+ setReadOnly();
+ }
+
+ public void add(Permission permission) {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ public boolean implies(Permission permission) {
+ if (_statisPermissions != null) {
+ if (!_statisPermissions.implies(permission)) {
+ return false;
+ }
+ }
+ try {
+ _context.checkPermission(permission);
+ return true;
+ }catch (AccessControlException ex) {
+ return false;
+ }
+ }
+
+ public Enumeration elements()
+ {
+ return new Enumeration() {
+ public boolean hasMoreElements() { return false; }
+ public Object nextElement() { return null; }
+ };
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append('@');
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" (context=");
+ sb.append(_context);
+ sb.append(", static_permitions=");
+ sb.append(_statisPermissions);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ AccessControlContext _context;
+ PermissionCollection _statisPermissions;
+ }
+
+ public JavaPolicySecurity()
+ {
+ // To trigger error on jdk-1.1 with lazy load
+ new CodeSource(null, (java.security.cert.Certificate[])null);
+ }
+
+ protected void callProcessFileSecure(final Context cx,
+ final Scriptable scope,
+ final String filename)
+ {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ URL url = getUrlObj(filename);
+ ProtectionDomain staticDomain = getUrlDomain(url);
+ Main.processFileSecure(cx, scope, url.toExternalForm(),
+ staticDomain);
+ return null;
+ }
+ });
+ }
+
+ private URL getUrlObj(String url)
+ {
+ URL urlObj;
+ try {
+ urlObj = new URL(url);
+ } catch (MalformedURLException ex) {
+ // Assume as Main.processFileSecure it is file, need to build its
+ // URL
+ String curDir = System.getProperty("user.dir");
+ curDir = curDir.replace('\\', '/');
+ if (!curDir.endsWith("/")) {
+ curDir = curDir+'/';
+ }
+ try {
+ URL curDirURL = new URL("file:"+curDir);
+ urlObj = new URL(curDirURL, url);
+ } catch (MalformedURLException ex2) {
+ throw new RuntimeException
+ ("Can not construct file URL for '"+url+"':"
+ +ex2.getMessage());
+ }
+ }
+ return urlObj;
+ }
+
+ private ProtectionDomain getUrlDomain(URL url)
+ {
+ CodeSource cs;
+ cs = new CodeSource(url, (java.security.cert.Certificate[])null);
+ PermissionCollection pc = Policy.getPolicy().getPermissions(cs);
+ return new ProtectionDomain(cs, pc);
+ }
+
+ public GeneratedClassLoader
+ createClassLoader(ClassLoader parentLoader, Object securityDomain)
+ {
+ ProtectionDomain domain = (ProtectionDomain)securityDomain;
+ return new Loader(parentLoader, domain);
+ }
+
+ public Object getDynamicSecurityDomain(Object securityDomain)
+ {
+ ProtectionDomain staticDomain = (ProtectionDomain)securityDomain;
+ return getDynamicDomain(staticDomain);
+ }
+
+ private ProtectionDomain getDynamicDomain(ProtectionDomain staticDomain) {
+ ContextPermissions p = new ContextPermissions(staticDomain);
+ ProtectionDomain contextDomain = new ProtectionDomain(null, p);
+ return contextDomain;
+ }
+
+ public Object callWithDomain(Object securityDomain,
+ final Context cx,
+ final Callable callable,
+ final Scriptable scope,
+ final Scriptable thisObj,
+ final Object[] args)
+ {
+ ProtectionDomain staticDomain = (ProtectionDomain)securityDomain;
+ // There is no direct way in Java to intersect permitions according
+ // stack context with additional domain.
+ // The following implementation first constructs ProtectionDomain
+ // that allows actions only allowed by both staticDomain and current
+ // stack context, and then constructs AccessController for this dynamic
+ // domain.
+ // If this is too slow, alternative solution would be to generate
+ // class per domain with a proxy method to call to infect
+ // java stack.
+ // Another optimization in case of scripts coming from "world" domain,
+ // that is having minimal default privileges is to construct
+ // one AccessControlContext based on ProtectionDomain
+ // with least possible privileges and simply call
+ // AccessController.doPrivileged with this untrusted context
+
+ ProtectionDomain dynamicDomain = getDynamicDomain(staticDomain);
+ ProtectionDomain[] tmp = { dynamicDomain };
+ AccessControlContext restricted = new AccessControlContext(tmp);
+
+ PrivilegedAction action = new PrivilegedAction() {
+ public Object run() {
+ return callable.call(cx, scope, thisObj, args);
+ }
+ };
+
+ return AccessController.doPrivileged(action, restricted);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Main.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Main.java
new file mode 100644
index 0000000..9120892
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/Main.java
@@ -0,0 +1,638 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Patrick Beard
+ * Norris Boyd
+ * Igor Bukanov
+ * Rob Ginda
+ * Kurt Westerfeld
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.MalformedURLException;
+import java.util.*;
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+/**
+ * The shell program.
+ *
+ * Can execute scripts interactively or in batch mode at the command line.
+ * An example of controlling the JavaScript engine.
+ *
+ * @author Norris Boyd
+ */
+public class Main
+{
+ public static ShellContextFactory
+ shellContextFactory = new ShellContextFactory();
+
+ public static Global global = new Global();
+ static protected ToolErrorReporter errorReporter;
+ static protected int exitCode = 0;
+ static private final int EXITCODE_RUNTIME_ERROR = 3;
+ static private final int EXITCODE_FILE_NOT_FOUND = 4;
+ static boolean processStdin = true;
+ static Vector fileList = new Vector(5);
+ private static SecurityProxy securityImpl;
+
+ static {
+ global.initQuitAction(new IProxy(IProxy.SYSTEM_EXIT));
+ }
+
+ /**
+ * Proxy class to avoid proliferation of anonymous classes.
+ */
+ private static class IProxy implements ContextAction, QuitAction
+ {
+ private static final int PROCESS_FILES = 1;
+ private static final int EVAL_INLINE_SCRIPT = 2;
+ private static final int SYSTEM_EXIT = 3;
+
+ private int type;
+ String[] args;
+ String scriptText;
+
+ IProxy(int type)
+ {
+ this.type = type;
+ }
+
+ public Object run(Context cx)
+ {
+ if (type == PROCESS_FILES) {
+ processFiles(cx, args);
+ } else if (type == EVAL_INLINE_SCRIPT) {
+ Script script = loadScriptFromSource(cx, scriptText,
+ "<command>", 1, null);
+ if (script != null) {
+ evaluateScript(script, cx, getGlobal());
+ }
+ } else {
+ throw Kit.codeBug();
+ }
+ return null;
+ }
+
+ public void quit(Context cx, int exitCode)
+ {
+ if (type == SYSTEM_EXIT) {
+ System.exit(exitCode);
+ return;
+ }
+ throw Kit.codeBug();
+ }
+ }
+
+ /**
+ * Main entry point.
+ *
+ * Process arguments as would a normal Java program. Also
+ * create a new Context and associate it with the current thread.
+ * Then set up the execution environment and begin to
+ * execute scripts.
+ */
+ public static void main(String args[]) {
+ try {
+ if (Boolean.getBoolean("rhino.use_java_policy_security")) {
+ initJavaPolicySecuritySupport();
+ }
+ } catch (SecurityException ex) {
+ ex.printStackTrace(System.err);
+ }
+
+ int result = exec(args);
+ if (result != 0) {
+ System.exit(result);
+ }
+ }
+
+ /**
+ * Execute the given arguments, but don't System.exit at the end.
+ */
+ public static int exec(String origArgs[])
+ {
+ errorReporter = new ToolErrorReporter(false, global.getErr());
+ shellContextFactory.setErrorReporter(errorReporter);
+ String[] args = processOptions(origArgs);
+ if (processStdin)
+ fileList.addElement(null);
+
+ if (!global.initialized) {
+ global.init(shellContextFactory);
+ }
+ IProxy iproxy = new IProxy(IProxy.PROCESS_FILES);
+ iproxy.args = args;
+ shellContextFactory.call(iproxy);
+
+ return exitCode;
+ }
+
+ static void processFiles(Context cx, String[] args)
+ {
+ // define "arguments" array in the top-level object:
+ // need to allocate new array since newArray requires instances
+ // of exactly Object[], not ObjectSubclass[]
+ Object[] array = new Object[args.length];
+ System.arraycopy(args, 0, array, 0, args.length);
+ Scriptable argsObj = cx.newArray(global, array);
+ global.defineProperty("arguments", argsObj,
+ ScriptableObject.DONTENUM);
+
+ for (int i=0; i < fileList.size(); i++) {
+ processSource(cx, (String) fileList.elementAt(i));
+ }
+
+ }
+
+ public static Global getGlobal()
+ {
+ return global;
+ }
+
+ /**
+ * Parse arguments.
+ */
+ public static String[] processOptions(String args[])
+ {
+ String usageError;
+ goodUsage: for (int i = 0; ; ++i) {
+ if (i == args.length) {
+ return new String[0];
+ }
+ String arg = args[i];
+ if (!arg.startsWith("-")) {
+ processStdin = false;
+ fileList.addElement(arg);
+ String[] result = new String[args.length - i - 1];
+ System.arraycopy(args, i+1, result, 0, args.length - i - 1);
+ return result;
+ }
+ if (arg.equals("-version")) {
+ if (++i == args.length) {
+ usageError = arg;
+ break goodUsage;
+ }
+ int version;
+ try {
+ version = Integer.parseInt(args[i]);
+ } catch (NumberFormatException ex) {
+ usageError = args[i];
+ break goodUsage;
+ }
+ if (!Context.isValidLanguageVersion(version)) {
+ usageError = args[i];
+ break goodUsage;
+ }
+ shellContextFactory.setLanguageVersion(version);
+ continue;
+ }
+ if (arg.equals("-opt") || arg.equals("-O")) {
+ if (++i == args.length) {
+ usageError = arg;
+ break goodUsage;
+ }
+ int opt;
+ try {
+ opt = Integer.parseInt(args[i]);
+ } catch (NumberFormatException ex) {
+ usageError = args[i];
+ break goodUsage;
+ }
+ if (opt == -2) {
+ // Compatibility with Cocoon Rhino fork
+ opt = -1;
+ } else if (!Context.isValidOptimizationLevel(opt)) {
+ usageError = args[i];
+ break goodUsage;
+ }
+ shellContextFactory.setOptimizationLevel(opt);
+ continue;
+ }
+ if (arg.equals("-strict")) {
+ shellContextFactory.setStrictMode(true);
+ errorReporter.setIsReportingWarnings(true);
+ continue;
+ }
+ if (arg.equals("-fatal-warnings")) {
+ shellContextFactory.setWarningAsError(true);
+ continue;
+ }
+ if (arg.equals("-e")) {
+ processStdin = false;
+ if (++i == args.length) {
+ usageError = arg;
+ break goodUsage;
+ }
+ if (!global.initialized) {
+ global.init(shellContextFactory);
+ }
+ IProxy iproxy = new IProxy(IProxy.EVAL_INLINE_SCRIPT);
+ iproxy.scriptText = args[i];
+ shellContextFactory.call(iproxy);
+ continue;
+ }
+ if (arg.equals("-w")) {
+ errorReporter.setIsReportingWarnings(true);
+ continue;
+ }
+ if (arg.equals("-f")) {
+ processStdin = false;
+ if (++i == args.length) {
+ usageError = arg;
+ break goodUsage;
+ }
+ fileList.addElement(args[i].equals("-") ? null : args[i]);
+ continue;
+ }
+ if (arg.equals("-sealedlib")) {
+ global.setSealedStdLib(true);
+ continue;
+ }
+ if (arg.equals("-debug")) {
+ shellContextFactory.setGeneratingDebug(true);
+ continue;
+ }
+ if (arg.equals("-?") ||
+ arg.equals("-help")) {
+ // print usage message
+ global.getOut().println(
+ ToolErrorReporter.getMessage("msg.shell.usage", Main.class.getName()));
+ System.exit(1);
+ }
+ usageError = arg;
+ break goodUsage;
+ }
+ // print error and usage message
+ global.getOut().println(
+ ToolErrorReporter.getMessage("msg.shell.invalid", usageError));
+ global.getOut().println(
+ ToolErrorReporter.getMessage("msg.shell.usage", Main.class.getName()));
+ System.exit(1);
+ return null;
+ }
+
+ private static void initJavaPolicySecuritySupport()
+ {
+ Throwable exObj;
+ try {
+ Class cl = Class.forName
+ ("org.mozilla.javascript.tools.shell.JavaPolicySecurity");
+ securityImpl = (SecurityProxy)cl.newInstance();
+ SecurityController.initGlobal(securityImpl);
+ return;
+ } catch (ClassNotFoundException ex) {
+ exObj = ex;
+ } catch (IllegalAccessException ex) {
+ exObj = ex;
+ } catch (InstantiationException ex) {
+ exObj = ex;
+ } catch (LinkageError ex) {
+ exObj = ex;
+ }
+ throw Kit.initCause(new IllegalStateException(
+ "Can not load security support: "+exObj), exObj);
+ }
+
+ /**
+ * Evaluate JavaScript source.
+ *
+ * @param cx the current context
+ * @param filename the name of the file to compile, or null
+ * for interactive mode.
+ */
+ public static void processSource(Context cx, String filename)
+ {
+ if (filename == null || filename.equals("-")) {
+ PrintStream ps = global.getErr();
+ if (filename == null) {
+ // print implementation version
+ ps.println(cx.getImplementationVersion());
+ }
+
+ // Use the interpreter for interactive input
+ cx.setOptimizationLevel(-1);
+
+ BufferedReader in = new BufferedReader
+ (new InputStreamReader(global.getIn()));
+ int lineno = 1;
+ boolean hitEOF = false;
+ while (!hitEOF) {
+ String[] prompts = global.getPrompts(cx);
+ if (filename == null)
+ ps.print(prompts[0]);
+ ps.flush();
+ String source = "";
+
+ // Collect lines of source to compile.
+ while (true) {
+ String newline;
+ try {
+ newline = in.readLine();
+ }
+ catch (IOException ioe) {
+ ps.println(ioe.toString());
+ break;
+ }
+ if (newline == null) {
+ hitEOF = true;
+ break;
+ }
+ source = source + newline + "\n";
+ lineno++;
+ if (cx.stringIsCompilableUnit(source))
+ break;
+ ps.print(prompts[1]);
+ }
+ Script script = loadScriptFromSource(cx, source, "<stdin>",
+ lineno, null);
+ if (script != null) {
+ Object result = evaluateScript(script, cx, global);
+ // Avoid printing out undefined or function definitions.
+ if (result != Context.getUndefinedValue() &&
+ !(result instanceof Function &&
+ source.trim().startsWith("function")))
+ {
+ try {
+ ps.println(Context.toString(result));
+ } catch (RhinoException rex) {
+ ToolErrorReporter.reportException(
+ cx.getErrorReporter(), rex);
+ }
+ }
+ NativeArray h = global.history;
+ h.put((int)h.getLength(), h, source);
+ }
+ }
+ ps.println();
+ } else {
+ processFile(cx, global, filename);
+ }
+ System.gc();
+ }
+
+ public static void processFile(Context cx, Scriptable scope,
+ String filename)
+ {
+ if (securityImpl == null) {
+ processFileSecure(cx, scope, filename, null);
+ } else {
+ securityImpl.callProcessFileSecure(cx, scope, filename);
+ }
+ }
+
+ static void processFileSecure(Context cx, Scriptable scope,
+ String path, Object securityDomain)
+ {
+ Script script;
+ if (path.endsWith(".class")) {
+ script = loadCompiledScript(cx, path, securityDomain);
+ } else {
+ String source = (String)readFileOrUrl(path, true);
+ if (source == null) {
+ exitCode = EXITCODE_FILE_NOT_FOUND;
+ return;
+ }
+
+ // Support the executable script #! syntax: If
+ // the first line begins with a '#', treat the whole
+ // line as a comment.
+ if (source.length() > 0 && source.charAt(0) == '#') {
+ for (int i = 1; i != source.length(); ++i) {
+ int c = source.charAt(i);
+ if (c == '\n' || c == '\r') {
+ source = source.substring(i);
+ break;
+ }
+ }
+ }
+ script = loadScriptFromSource(cx, source, path, 1, securityDomain);
+ }
+ if (script != null) {
+ evaluateScript(script, cx, scope);
+ }
+ }
+
+ public static Script loadScriptFromSource(Context cx, String scriptSource,
+ String path, int lineno,
+ Object securityDomain)
+ {
+ try {
+ return cx.compileString(scriptSource, path, lineno,
+ securityDomain);
+ } catch (EvaluatorException ee) {
+ // Already printed message.
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ } catch (RhinoException rex) {
+ ToolErrorReporter.reportException(
+ cx.getErrorReporter(), rex);
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ } catch (VirtualMachineError ex) {
+ // Treat StackOverflow and OutOfMemory as runtime errors
+ ex.printStackTrace();
+ String msg = ToolErrorReporter.getMessage(
+ "msg.uncaughtJSException", ex.toString());
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ Context.reportError(msg);
+ }
+ return null;
+ }
+
+ private static Script loadCompiledScript(Context cx, String path,
+ Object securityDomain)
+ {
+ byte[] data = (byte[])readFileOrUrl(path, false);
+ if (data == null) {
+ exitCode = EXITCODE_FILE_NOT_FOUND;
+ return null;
+ }
+ // XXX: For now extract class name of compiled Script from path
+ // instead of parsing class bytes
+ int nameStart = path.lastIndexOf('/');
+ if (nameStart < 0) {
+ nameStart = 0;
+ } else {
+ ++nameStart;
+ }
+ int nameEnd = path.lastIndexOf('.');
+ if (nameEnd < nameStart) {
+ // '.' does not exist in path (nameEnd < 0)
+ // or it comes before nameStart
+ nameEnd = path.length();
+ }
+ String name = path.substring(nameStart, nameEnd);
+ try {
+ GeneratedClassLoader loader = SecurityController.createLoader(cx.getApplicationClassLoader(), securityDomain);
+ Class clazz = loader.defineClass(name, data);
+ loader.linkClass(clazz);
+ if (!Script.class.isAssignableFrom(clazz)) {
+ throw Context.reportRuntimeError("msg.must.implement.Script");
+ }
+ return (Script) clazz.newInstance();
+ } catch (RhinoException rex) {
+ ToolErrorReporter.reportException(
+ cx.getErrorReporter(), rex);
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ } catch (IllegalAccessException iaex) {
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ Context.reportError(iaex.toString());
+ } catch (InstantiationException inex) {
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ Context.reportError(inex.toString());
+ }
+ return null;
+ }
+
+ public static Object evaluateScript(Script script, Context cx,
+ Scriptable scope)
+ {
+ try {
+ return script.exec(cx, scope);
+ } catch (RhinoException rex) {
+ ToolErrorReporter.reportException(
+ cx.getErrorReporter(), rex);
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ } catch (VirtualMachineError ex) {
+ // Treat StackOverflow and OutOfMemory as runtime errors
+ ex.printStackTrace();
+ String msg = ToolErrorReporter.getMessage(
+ "msg.uncaughtJSException", ex.toString());
+ exitCode = EXITCODE_RUNTIME_ERROR;
+ Context.reportError(msg);
+ }
+ return Context.getUndefinedValue();
+ }
+
+ public static InputStream getIn() {
+ return getGlobal().getIn();
+ }
+
+ public static void setIn(InputStream in) {
+ getGlobal().setIn(in);
+ }
+
+ public static PrintStream getOut() {
+ return getGlobal().getOut();
+ }
+
+ public static void setOut(PrintStream out) {
+ getGlobal().setOut(out);
+ }
+
+ public static PrintStream getErr() {
+ return getGlobal().getErr();
+ }
+
+ public static void setErr(PrintStream err) {
+ getGlobal().setErr(err);
+ }
+
+ /**
+ * Read file or url specified by <tt>path</tt>.
+ * @return file or url content as <tt>byte[]</tt> or as <tt>String</tt> if
+ * <tt>convertToString</tt> is true.
+ */
+ private static Object readFileOrUrl(String path, boolean convertToString)
+ {
+ URL url = null;
+ // Assume path is URL if it contains dot and there are at least
+ // 2 characters in the protocol part. The later allows under Windows
+ // to interpret paths with driver letter as file, not URL.
+ if (path.indexOf(':') >= 2) {
+ try {
+ url = new URL(path);
+ } catch (MalformedURLException ex) {
+ }
+ }
+
+ InputStream is = null;
+ int capacityHint = 0;
+ if (url == null) {
+ File file = new File(path);
+ capacityHint = (int)file.length();
+ try {
+ is = new FileInputStream(file);
+ } catch (IOException ex) {
+ Context.reportError(ToolErrorReporter.getMessage(
+ "msg.couldnt.open", path));
+ return null;
+ }
+ } else {
+ try {
+ URLConnection uc = url.openConnection();
+ is = uc.getInputStream();
+ capacityHint = uc.getContentLength();
+ // Ignore insane values for Content-Length
+ if (capacityHint > (1 << 20)) {
+ capacityHint = -1;
+ }
+ } catch (IOException ex) {
+ Context.reportError(ToolErrorReporter.getMessage(
+ "msg.couldnt.open.url", url.toString(), ex.toString()));
+ return null;
+ }
+ }
+ if (capacityHint <= 0) {
+ capacityHint = 4096;
+ }
+
+ byte[] data;
+ try {
+ try {
+ data = Kit.readStream(is, capacityHint);
+ } finally {
+ is.close();
+ }
+ } catch (IOException ex) {
+ Context.reportError(ex.toString());
+ return null;
+ }
+
+ Object result;
+ if (!convertToString) {
+ result = data;
+ } else {
+ // Convert to String using the default encoding
+ // XXX: Use 'charset=' argument of Content-Type if URL?
+ result = new String(data);
+ }
+ return result;
+ }
+
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/QuitAction.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/QuitAction.java
new file mode 100644
index 0000000..dcad90e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/QuitAction.java
@@ -0,0 +1,50 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import org.mozilla.javascript.Context;
+
+/**
+ * Defines action to perform in response to quit command.
+ */
+public interface QuitAction
+{
+ public void quit(Context cx, int exitCode);
+}
+
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/SecurityProxy.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/SecurityProxy.java
new file mode 100644
index 0000000..8f029ea
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/SecurityProxy.java
@@ -0,0 +1,48 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import org.mozilla.javascript.*;
+
+public abstract class SecurityProxy extends SecurityController
+{
+ protected abstract void callProcessFileSecure(Context cx, Scriptable scope,
+ String filename);
+
+}
diff --git a/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ShellContextFactory.java b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ShellContextFactory.java
new file mode 100644
index 0000000..ba7e62c
--- /dev/null
+++ b/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/ShellContextFactory.java
@@ -0,0 +1,114 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Bob Jervis
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import org.mozilla.javascript.*;
+
+public class ShellContextFactory extends ContextFactory
+{
+ private boolean strictMode;
+ private boolean warningAsError;
+ private int languageVersion;
+ private int optimizationLevel;
+ private boolean generatingDebug;
+ private ErrorReporter errorReporter;
+
+ protected boolean hasFeature(Context cx, int featureIndex)
+ {
+ switch (featureIndex) {
+ case Context.FEATURE_STRICT_VARS:
+ case Context.FEATURE_STRICT_EVAL:
+ case Context.FEATURE_STRICT_MODE:
+ return strictMode;
+
+ case Context.FEATURE_WARNING_AS_ERROR:
+ return warningAsError;
+ }
+ return super.hasFeature(cx, featureIndex);
+ }
+
+ protected void onContextCreated(Context cx)
+ {
+ cx.setLanguageVersion(languageVersion);
+ cx.setOptimizationLevel(optimizationLevel);
+ if (errorReporter != null) {
+ cx.setErrorReporter(errorReporter);
+ }
+ cx.setGeneratingDebug(generatingDebug);
+ super.onContextCreated(cx);
+ }
+
+ public void setStrictMode(boolean flag)
+ {
+ checkNotSealed();
+ this.strictMode = flag;
+ }
+
+ public void setWarningAsError(boolean flag)
+ {
+ checkNotSealed();
+ this.warningAsError = flag;
+ }
+
+ public void setLanguageVersion(int version)
+ {
+ Context.checkLanguageVersion(version);
+ checkNotSealed();
+ this.languageVersion = version;
+ }
+
+ public void setOptimizationLevel(int optimizationLevel)
+ {
+ Context.checkOptimizationLevel(optimizationLevel);
+ checkNotSealed();
+ this.optimizationLevel = optimizationLevel;
+ }
+
+ public void setErrorReporter(ErrorReporter errorReporter)
+ {
+ if (errorReporter == null) throw new IllegalArgumentException();
+ this.errorReporter = errorReporter;
+ }
+
+ public void setGeneratingDebug(boolean generatingDebug)
+ {
+ this.generatingDebug = generatingDebug;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/build.xml b/infrastructure/rhino1_7R1/xmlimplsrc/build.xml
new file mode 100644
index 0000000..1aedece
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/build.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Rhino code, released May 6, 1999.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 1997-1999
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - the GNU General Public License Version 2 or later (the "GPL"), in which
+ - case the provisions of the GPL are applicable instead of those above. If
+ - you wish to allow use of your version of this file only under the terms of
+ - the GPL and not to allow others to use your version of this file under the
+ - MPL, indicate your decision by deleting the provisions above and replacing
+ - them with the notice and other provisions required by the GPL. If you do
+ - not delete the provisions above, a recipient may use your version of this
+ - file under either the MPL or the GPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<project name="xmlimplsrc" basedir=".." default="compile">
+ <!--
+ Properties which affect this build file:
+
+ no-e4x: Will cause E4X not to be built
+ no-xmlbeans: Will cause the old, XMLBeans-based implementation of E4X not to be built
+ -->
+
+ <property file="build.local.properties"/>
+ <property file="build.properties"/>
+
+ <!--
+ Provide support for the old name for skipping E4X compilation, in case someone is still using it
+ -->
+ <condition property="no-e4x">
+ <isset property="without-xmlimpl" />
+ </condition>
+
+ <path id="xmlbeans.classpath">
+ <pathelement location="${xbean.jar}"/>
+ <pathelement location="${jsr173.jar}"/>
+ </path>
+
+ <target name="compile" unless="no-e4x">
+ <antcall target="e4x-compile" />
+ <antcall target="no-e4x-compile" />
+
+ <antcall target="old-e4x" />
+ </target>
+
+ <available property="jdk1.5?" classname="java.lang.ProcessBuilder" />
+
+ <target name="e4x-compile" if="jdk1.5?">
+ <javac
+ srcdir="xmlimplsrc"
+ destdir="${classes}"
+ deprecation="on"
+ debug="${debug}"
+ target="${target-jvm}"
+ source="${source-level}"
+ />
+ </target>
+
+ <target name="no-e4x-compile" unless="jdk1.5?">
+ <echo>
+ Skipping DOM E4X implementation; JDK 1.5+ currently required for compilation.
+ <!--
+ If the compiler is outfitted with DOM3 using the endorsed standards override mechanism, presumably the code
+ could be built under 1.4. Not tested.
+ -->
+ </echo>
+ </target>
+
+ <target name="old-e4x" unless="no-xmlbeans">
+ <antcall target="old-e4x-compile" />
+ <antcall target="no-old-e4x-compile" />
+ </target>
+
+ <target name="old-e4x-compile" depends="xmlbeans-unzip">
+ <echo>Compiling XMLBeans E4X implementation using ${xbean.jar} and ${jsr173.jar}</echo>
+ <javac
+ srcdir="deprecatedsrc"
+ destdir="${classes}"
+ includes="org/mozilla/javascript/xml/impl/xmlbeans/*.java"
+ deprecation="on"
+ debug="${debug}"
+ classpathref="xmlbeans.classpath"
+ failonerror="${xmlimpl.compile.failonerror}"
+ target="${target-jvm}"
+ source="${source-level}"
+ />
+ </target>
+
+ <target name="no-old-e4x-compile" if="no-xmlbeans">
+ <echo>
+ Skipping compilation of XMLBeans E4X implementation due to missing XMLBeans files
+ </echo>
+ </target>
+
+ <target name="copy-source">
+ <mkdir dir="${dist.dir}/xmlimplsrc"/>
+ <copy todir="${dist.dir}/xmlimplsrc">
+ <fileset
+ dir="xmlimplsrc"
+ includes="**/*.java,**/*.properties,**/*.xml"
+ />
+ </copy>
+ </target>
+
+ <target name="clean">
+ <delete includeEmptyDirs="true">
+ <fileset
+ dir="${classes}"
+ includes="org/mozilla/javascript/xmlimpl/**"
+ />
+ </delete>
+ </target>
+
+ <property name="xmlbeans.tmp" location="${build.dir}/tmp-xbean" />
+ <property name="xmlbeans.zip" location="${xmlbeans.tmp}/xbean.zip" />
+
+ <condition property="xmlbeans-present?">
+ <and>
+ <available file="${xbean.jar}" />
+ <available file="${jsr173.jar}" />
+ </and>
+ </condition>
+
+ <condition property="xmlbeans-zip-present?">
+ <available file="${xmlbeans.zip}" />
+ </condition>
+
+ <target name="xmlbeans-get" unless="xmlbeans-zip-present?">
+ <property
+ name="xmlbeans.url"
+ value="http://www.apache.org/dist/xmlbeans/binaries/xmlbeans-2.2.0.zip"
+ />
+
+ <mkdir dir="${xmlbeans.tmp}" />
+ <get src="${xmlbeans.url}" dest="${xmlbeans.zip}" ignoreerrors="true" />
+ </target>
+
+ <target name="xmlbeans-unzip" unless="xmlbeans-present?">
+ <antcall target="xmlbeans-get" />
+ <unzip src="${xmlbeans.zip}" dest="${xmlbeans.tmp}" />
+ <copy tofile="${xbean.jar}" file="${xmlbeans.tmp}/xmlbeans-2.2.0/lib/xbean.jar" />
+ <copy tofile="${jsr173.jar}" file="${xmlbeans.tmp}/xmlbeans-2.2.0/lib/jsr173_1.0_api.jar" />
+ <delete dir="${xmlbeans.tmp}" />
+ </target>
+</project>
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java
new file mode 100644
index 0000000..a4cf585
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/Namespace.java
@@ -0,0 +1,367 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class Namespace
+ *
+ */
+class Namespace extends IdScriptableObject
+{
+ static final long serialVersionUID = -5765755238131301744L;
+
+ private static final Object NAMESPACE_TAG = new Object();
+
+ private Namespace prototype;
+ private XmlNode.Namespace ns;
+
+ private Namespace() {
+ }
+
+ static Namespace create(Scriptable scope, Namespace prototype, XmlNode.Namespace namespace) {
+ Namespace rv = new Namespace();
+ rv.setParentScope(scope);
+ rv.prototype = prototype;
+ rv.setPrototype(prototype);
+ rv.ns = namespace;
+ return rv;
+ }
+
+ final XmlNode.Namespace getDelegate() {
+ return ns;
+ }
+
+ public void exportAsJSClass(boolean sealed) {
+ exportAsJSClass(MAX_PROTOTYPE_ID, this.getParentScope(), sealed);
+ }
+
+ public String uri() {
+ return ns.getUri();
+ }
+
+ public String prefix() {
+ return ns.getPrefix();
+ }
+
+ public String toString() {
+ return uri();
+ }
+
+ public String toLocaleString() {
+ return toString();
+ }
+
+ private boolean equals(Namespace n) {
+ return uri().equals(n.uri());
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Namespace)) return false;
+ return equals((Namespace)obj);
+ }
+
+ protected Object equivalentValues(Object value) {
+ if (!(value instanceof Namespace)) return Scriptable.NOT_FOUND;
+ boolean result = equals((Namespace)value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public String getClassName() {
+ return "Namespace";
+ }
+
+ public Object getDefaultValue(Class hint) {
+ return uri();
+ }
+
+// #string_id_map#
+ private static final int
+ Id_prefix = 1,
+ Id_uri = 2,
+ MAX_INSTANCE_ID = 2;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-08-20 08:23:22 EDT
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==3) { X="uri";id=Id_uri; }
+ else if (s_length==6) { X="prefix";id=Id_prefix; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_prefix:
+ case Id_uri:
+ attr = PERMANENT | READONLY;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_prefix: return "prefix";
+ case Id_uri: return "uri";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_prefix:
+ if (ns.getPrefix() == null) return Undefined.instance;
+ return ns.getPrefix();
+ case Id_uri:
+ return ns.getUri();
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+
+// #string_id_map#
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-08-20 08:23:22 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=2; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(NAMESPACE_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f,
+ Context cx,
+ Scriptable scope,
+ Scriptable thisObj,
+ Object[] args)
+ {
+ if (!f.hasTag(NAMESPACE_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return jsConstructor(cx, (thisObj == null), args);
+ case Id_toString:
+ return realThis(thisObj, f).toString();
+ case Id_toSource:
+ return realThis(thisObj, f).js_toSource();
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private Namespace realThis(Scriptable thisObj, IdFunctionObject f) {
+ if(!(thisObj instanceof Namespace))
+ throw incompatibleCallError(f);
+ return (Namespace)thisObj;
+ }
+
+ Namespace newNamespace(String uri) {
+ Namespace prototype = (this.prototype == null) ? this : this.prototype;
+ return create( this.getParentScope(), prototype, XmlNode.Namespace.create(uri) );
+ }
+
+ Namespace newNamespace(String prefix, String uri) {
+ if (prefix == null) return newNamespace(uri);
+ Namespace prototype = (this.prototype == null) ? this : this.prototype;
+ return create( this.getParentScope(), prototype, XmlNode.Namespace.create(prefix, uri) );
+ }
+
+ Namespace constructNamespace(Object uriValue) {
+ String prefix;
+ String uri;
+
+ if (uriValue instanceof Namespace) {
+ Namespace ns = (Namespace)uriValue;
+ prefix = ns.prefix();
+ uri = ns.uri();
+ } else if (uriValue instanceof QName) {
+ QName qname = (QName)uriValue;
+ uri = qname.uri();
+ if (uri != null) {
+ // TODO Is there a way to push this back into QName so that we can make prefix() private?
+ prefix = qname.prefix();
+ } else {
+ uri = qname.toString();
+ prefix = null;
+ }
+ } else {
+ uri = ScriptRuntime.toString(uriValue);
+ prefix = (uri.length() == 0) ? "" : null;
+ }
+
+ return newNamespace(prefix, uri);
+ }
+
+ Namespace castToNamespace(Object namespaceObj) {
+ if (namespaceObj instanceof Namespace) {
+ return (Namespace)namespaceObj;
+ }
+ return constructNamespace(namespaceObj);
+ }
+
+ private Namespace constructNamespace(Object prefixValue, Object uriValue) {
+ String prefix;
+ String uri;
+
+ if (uriValue instanceof QName) {
+ QName qname = (QName)uriValue;
+ uri = qname.uri();
+ if (uri == null) {
+ uri = qname.toString();
+ }
+ } else {
+ uri = ScriptRuntime.toString(uriValue);
+ }
+
+ if (uri.length() == 0) {
+ if (prefixValue == Undefined.instance) {
+ prefix = "";
+ } else {
+ prefix = ScriptRuntime.toString(prefixValue);
+ if (prefix.length() != 0) {
+ throw ScriptRuntime.typeError(
+ "Illegal prefix '"+prefix+"' for 'no namespace'.");
+ }
+ }
+ } else if (prefixValue == Undefined.instance) {
+ prefix = "";
+ } else if (!XMLName.accept(prefixValue)) {
+ prefix = "";
+ } else {
+ prefix = ScriptRuntime.toString(prefixValue);
+ }
+
+ return newNamespace(prefix, uri);
+ }
+
+ private Namespace constructNamespace() {
+ return newNamespace("", "");
+ }
+
+ private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
+ {
+ if (!inNewExpr && args.length == 1) {
+ return castToNamespace(args[0]);
+ }
+
+ if (args.length == 0) {
+ return constructNamespace();
+ } else if (args.length == 1) {
+ return constructNamespace(args[0]);
+ } else {
+ return constructNamespace(args[0], args[1]);
+ }
+ }
+
+ private String js_toSource()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ toSourceImpl(ns.getPrefix(), ns.getUri(), sb);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ static void toSourceImpl(String prefix, String uri, StringBuffer sb)
+ {
+ sb.append("new Namespace(");
+ if (uri.length() == 0) {
+ if (!"".equals(prefix)) throw new IllegalArgumentException(prefix);
+ } else {
+ sb.append('\'');
+ if (prefix != null) {
+ sb.append(ScriptRuntime.escapeString(prefix, '\''));
+ sb.append("', '");
+ }
+ sb.append(ScriptRuntime.escapeString(uri, '\''));
+ sb.append('\'');
+ }
+ sb.append(')');
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java
new file mode 100644
index 0000000..90a18cb
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/QName.java
@@ -0,0 +1,381 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+
+/**
+ * Class QName
+ *
+ */
+final class QName extends IdScriptableObject
+{
+ static final long serialVersionUID = 416745167693026750L;
+
+ private static final Object QNAME_TAG = new Object();
+
+ private XMLLibImpl lib;
+
+ private QName prototype;
+
+ private XmlNode.QName delegate;
+
+ private QName() {
+ }
+
+ static QName create(XMLLibImpl lib, Scriptable scope, QName prototype, XmlNode.QName delegate) {
+ QName rv = new QName();
+ rv.lib = lib;
+ rv.setParentScope(scope);
+ rv.prototype = prototype;
+ rv.setPrototype(prototype);
+ rv.delegate = delegate;
+ return rv;
+ }
+
+// /** @deprecated */
+// static QName create(XMLLibImpl lib, XmlNode.QName nodeQname) {
+// return create(lib, lib.globalScope(), lib.qnamePrototype(), nodeQname);
+// }
+
+ void exportAsJSClass(boolean sealed) {
+ exportAsJSClass(MAX_PROTOTYPE_ID, getParentScope(), sealed);
+ }
+
+ public String toString() {
+ // ECMA357 13.3.4.2
+ if (delegate.getNamespace() == null) {
+ return "*::" + localName();
+ } else if (delegate.getNamespace().isGlobal()) {
+ // leave as empty
+ return localName();
+ } else {
+ return uri() + "::" + localName();
+ }
+ }
+
+ public String localName() {
+ if (delegate.getLocalName() == null) return "*";
+ return delegate.getLocalName();
+ }
+
+ /**
+ @deprecated
+
+ This property is supposed to be invisible and I think we can make it private at some point, though Namespace
+ might need it
+ */
+ String prefix() {
+ if (delegate.getNamespace() == null) return null;
+ return delegate.getNamespace().getPrefix();
+ }
+
+ String uri() {
+ if (delegate.getNamespace() == null) return null;
+ return delegate.getNamespace().getUri();
+ }
+
+ /** @deprecated */
+ final XmlNode.QName toNodeQname() {
+ return delegate;
+ }
+
+ final XmlNode.QName getDelegate() {
+ return delegate;
+ }
+
+ public boolean equals(Object obj) {
+ if(!(obj instanceof QName)) return false;
+ return equals((QName)obj);
+ }
+
+ protected Object equivalentValues(Object value)
+ {
+ if(!(value instanceof QName)) return Scriptable.NOT_FOUND;
+ boolean result = equals((QName)value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ private boolean equals(QName q) {
+ return this.delegate.isEqualTo(q.delegate);
+ }
+
+ public String getClassName() {
+ return "QName";
+ }
+
+ public Object getDefaultValue(Class hint) {
+ return toString();
+ }
+
+// #string_id_map#
+ private static final int
+ Id_localName = 1,
+ Id_uri = 2,
+ MAX_INSTANCE_ID = 2;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s)
+ {
+ int id;
+// #generated# Last update: 2007-08-20 08:21:41 EDT
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==3) { X="uri";id=Id_uri; }
+ else if (s_length==9) { X="localName";id=Id_localName; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_localName:
+ case Id_uri:
+ attr = PERMANENT | READONLY;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_localName: return "localName";
+ case Id_uri: return "uri";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_localName: return localName();
+ case Id_uri: return uri();
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+// #string_id_map#
+ private static final int
+ Id_constructor = 1,
+ Id_toString = 2,
+ Id_toSource = 3,
+ MAX_PROTOTYPE_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-08-20 08:21:41 EDT
+ L0: { id = 0; String X = null; int c;
+ int s_length = s.length();
+ if (s_length==8) {
+ c=s.charAt(3);
+ if (c=='o') { X="toSource";id=Id_toSource; }
+ else if (c=='t') { X="toString";id=Id_toString; }
+ }
+ else if (s_length==11) { X="constructor";id=Id_constructor; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: arity=2; s="constructor"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toSource: arity=0; s="toSource"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(QNAME_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f,
+ Context cx,
+ Scriptable scope,
+ Scriptable thisObj,
+ Object[] args)
+ {
+ if (!f.hasTag(QNAME_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_constructor:
+ return jsConstructor(cx, (thisObj == null), args);
+ case Id_toString:
+ return realThis(thisObj, f).toString();
+ case Id_toSource:
+ return realThis(thisObj, f).js_toSource();
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private QName realThis(Scriptable thisObj, IdFunctionObject f)
+ {
+ if(!(thisObj instanceof QName))
+ throw incompatibleCallError(f);
+ return (QName)thisObj;
+ }
+
+ QName newQName(XMLLibImpl lib, String q_uri, String q_localName, String q_prefix) {
+ QName prototype = this.prototype;
+ if (prototype == null) {
+ prototype = this;
+ }
+ XmlNode.Namespace ns = null;
+ if (q_prefix != null) {
+ ns = XmlNode.Namespace.create(q_uri, q_prefix);
+ } else if (q_uri != null) {
+ ns = XmlNode.Namespace.create(q_uri);
+ } else {
+ ns = null;
+ }
+ if (q_localName != null && q_localName.equals("*")) q_localName = null;
+ return create(lib, this.getParentScope(), prototype, XmlNode.QName.create(ns, q_localName));
+ }
+
+ // See ECMA357 13.3.2
+ QName constructQName(XMLLibImpl lib, Context cx, Object namespace, Object name) {
+ String nameString = null;
+ if (name instanceof QName) {
+ if (namespace == Undefined.instance) {
+ return (QName)name;
+ } else {
+ nameString = ((QName)name).localName();
+ }
+ }
+ if (name == Undefined.instance) {
+ nameString = "";
+ } else {
+ nameString = ScriptRuntime.toString(name);
+ }
+
+ if (namespace == Undefined.instance) {
+ if ("*".equals(nameString)) {
+ namespace = null;
+ } else {
+ namespace = lib.getDefaultNamespace(cx);
+ }
+ }
+ Namespace namespaceNamespace = null;
+ if (namespace == null) {
+ // leave as null
+ } else if (namespace instanceof Namespace) {
+ namespaceNamespace = (Namespace)namespace;
+ } else {
+ namespaceNamespace = lib.newNamespace(ScriptRuntime.toString(namespace));
+ }
+ String q_localName = nameString;
+ String q_uri;
+ String q_prefix;
+ if (namespace == null) {
+ q_uri = null;
+ q_prefix = null; // corresponds to undefined; see QName class
+ } else {
+ q_uri = namespaceNamespace.uri();
+ q_prefix = namespaceNamespace.prefix();
+ }
+ return newQName(lib, q_uri, q_localName, q_prefix);
+ }
+
+ QName constructQName(XMLLibImpl lib, Context cx, Object nameValue) {
+ return constructQName(lib, cx, Undefined.instance, nameValue);
+ }
+
+ QName castToQName(XMLLibImpl lib, Context cx, Object qnameValue) {
+ if (qnameValue instanceof QName) {
+ return (QName)qnameValue;
+ }
+ return constructQName(lib, cx, qnameValue);
+ }
+
+ private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args) {
+ // See ECMA357 13.3.2
+ if (!inNewExpr && args.length == 1) {
+ return castToQName(lib, cx, args[0]);
+ }
+ if (args.length == 0) {
+ return constructQName(lib, cx, Undefined.instance);
+ } else if (args.length == 1) {
+ return constructQName(lib, cx, args[0]);
+ } else {
+ return constructQName(lib, cx, args[0], args[1]);
+ }
+ }
+
+ private String js_toSource() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ toSourceImpl(uri(), localName(), prefix(), sb);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ private static void toSourceImpl(String uri, String localName, String prefix, StringBuffer sb) {
+ sb.append("new QName(");
+ if (uri == null && prefix == null) {
+ if (!"*".equals(localName)) {
+ sb.append("null, ");
+ }
+ } else {
+ Namespace.toSourceImpl(prefix, uri, sb);
+ sb.append(", ");
+ }
+ sb.append('\'');
+ sb.append(ScriptRuntime.escapeString(localName, '\''));
+ sb.append("')");
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java
new file mode 100644
index 0000000..090ae1a
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XML.java
@@ -0,0 +1,734 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.XMLObject;
+
+class XML extends XMLObjectImpl {
+ static final long serialVersionUID = -630969919086449092L;
+
+ private XmlNode node;
+
+ XML(XMLLibImpl lib, Scriptable scope, XMLObject prototype, XmlNode node) {
+ super(lib, scope, prototype);
+ initialize(node);
+ }
+
+ void initialize(XmlNode node) {
+ this.node = node;
+ this.node.setXml(this);
+ }
+
+ final XML getXML() {
+ return this;
+ }
+
+ void replaceWith(XML value) {
+ // We use the underlying document structure if the node is not
+ // "standalone," but we need to just replace the XmlNode instance
+ // otherwise
+ if (this.node.parent() != null || false) {
+ this.node.replaceWith(value.node);
+ } else {
+ this.initialize(value.node);
+ }
+ }
+
+ /** @deprecated I would love to encapsulate this somehow. */
+ XML makeXmlFromString(XMLName name, String value) {
+ try {
+ return newTextElementXML(this.node, name.toQname(), value.toString());
+ } catch(Exception e) {
+ throw ScriptRuntime.typeError(e.getMessage());
+ }
+ }
+
+ /** @deprecated Rename this, at the very least. But it's not clear it's even necessary */
+ XmlNode getAnnotation() {
+ return node;
+ }
+
+ //
+ // Methods from ScriptableObject
+ //
+
+ // TODO Either cross-reference this next comment with the specification or delete it and change the behavior
+ // The comment: XML[0] should return this, all other indexes are Undefined
+ public Object get(int index, Scriptable start) {
+ if (index == 0) {
+ return this;
+ } else {
+ return Scriptable.NOT_FOUND;
+ }
+ }
+
+ public boolean has(int index, Scriptable start) {
+ return (index == 0);
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ // TODO Clarify the following comment and add a reference to the spec
+ // The comment: Spec says assignment to indexed XML object should return type error
+ throw ScriptRuntime.typeError("Assignment to indexed XML is not allowed");
+ }
+
+ public Object[] getIds() {
+ if (isPrototype()) {
+ return new Object[0];
+ } else {
+ return new Object[] { new Integer(0) };
+ }
+ }
+
+ // TODO This is how I found it but I am not sure it makes sense
+ public void delete(int index) {
+ if (index == 0) {
+ this.remove();
+ }
+ }
+
+ //
+ // Methods from XMLObjectImpl
+ //
+
+ boolean hasXMLProperty(XMLName xmlName) {
+ if (isPrototype()) {
+ return getMethod(xmlName.localName()) != NOT_FOUND;
+ } else {
+ return (getPropertyList(xmlName).length() > 0) || (getMethod(xmlName.localName()) != NOT_FOUND);
+ }
+ }
+
+ Object getXMLProperty(XMLName xmlName) {
+ if (isPrototype()) {
+ return getMethod(xmlName.localName());
+ } else {
+ return getPropertyList(xmlName);
+ }
+ }
+
+ //
+ //
+ // Methods that merit further review
+ //
+ //
+
+ XmlNode.QName getNodeQname() {
+ return this.node.getQname();
+ }
+
+ XML[] getChildren() {
+ if (!isElement()) return null;
+ XmlNode[] children = this.node.getMatchingChildren(XmlNode.Filter.TRUE);
+ XML[] rv = new XML[children.length];
+ for (int i=0; i<rv.length; i++) {
+ rv[i] = toXML(children[i]);
+ }
+ return rv;
+ }
+
+ XML[] getAttributes() {
+ XmlNode[] attributes = this.node.getAttributes();
+ XML[] rv = new XML[attributes.length];
+ for (int i=0; i<rv.length; i++) {
+ rv[i] = toXML(attributes[i]);
+ }
+ return rv;
+ }
+
+ // Used only by XML, XMLList
+ XMLList getPropertyList(XMLName name) {
+ return name.getMyValueOn(this);
+ }
+
+ void deleteXMLProperty(XMLName name) {
+ XMLList list = getPropertyList(name);
+ for (int i=0; i<list.length(); i++) {
+ list.item(i).node.deleteMe();
+ }
+ }
+
+ void putXMLProperty(XMLName xmlName, Object value) {
+ if (isPrototype()) {
+ // TODO Is this really a no-op? Check the spec to be sure
+ } else {
+ xmlName.setMyValueOn(this, value);
+ }
+ }
+
+ boolean hasOwnProperty(XMLName xmlName) {
+ boolean hasProperty = false;
+
+ if (isPrototype()) {
+ String property = xmlName.localName();
+ hasProperty = (0 != findPrototypeId(property));
+ } else {
+ hasProperty = (getPropertyList(xmlName).length() > 0);
+ }
+
+ return hasProperty;
+ }
+
+ protected Object jsConstructor(Context cx, boolean inNewExpr, Object[] args) {
+ if (args.length == 0 || args[0] == null || args[0] == Undefined.instance) {
+ args = new Object[] { "" };
+ }
+ // ECMA 13.4.2 does not appear to specify what to do if multiple arguments are sent.
+ XML toXml = ecmaToXml(args[0]);
+ if (inNewExpr) {
+ return toXml.copy();
+ } else {
+ return toXml;
+ }
+ }
+
+ // See ECMA 357, 11_2_2_1, Semantics, 3_f.
+ public Scriptable getExtraMethodSource(Context cx) {
+ if (hasSimpleContent()) {
+ String src = toString();
+ return ScriptRuntime.toObjectOrNull(cx, src);
+ }
+ return null;
+ }
+
+ //
+ // TODO Miscellaneous methods not yet grouped
+ //
+
+ void removeChild(int index) {
+ this.node.removeChild(index);
+ }
+
+ void normalize() {
+ this.node.normalize();
+ }
+
+ private XML toXML(XmlNode node) {
+ if (node.getXml() == null) {
+ node.setXml(newXML(node));
+ }
+ return node.getXml();
+ }
+
+ void setAttribute(XMLName xmlName, Object value) {
+ if (!isElement()) throw new IllegalStateException("Can only set attributes on elements.");
+ // TODO Is this legal, but just not "supported"? If so, support it.
+ if (xmlName.uri() == null && xmlName.localName().equals("*")) {
+ throw ScriptRuntime.typeError("@* assignment not supported.");
+ }
+ this.node.setAttribute(xmlName.toQname(), ScriptRuntime.toString(value));
+ }
+
+ void remove() {
+ this.node.deleteMe();
+ }
+
+ void addMatches(XMLList rv, XMLName name) {
+ name.addMatches(rv, this);
+ }
+
+ XMLList elements(XMLName name) {
+ XMLList rv = newXMLList();
+ rv.setTargets(this, name.toQname());
+ // TODO Should have an XMLNode.Filter implementation based on XMLName
+ XmlNode[] elements = this.node.getMatchingChildren(XmlNode.Filter.ELEMENT);
+ for (int i=0; i<elements.length; i++) {
+ if (name.matches( toXML(elements[i]) )) {
+ rv.addToList( toXML(elements[i]) );
+ }
+ }
+ return rv;
+ }
+
+ XMLList child(XMLName xmlName) {
+ // TODO Right now I think this method would allow child( "@xxx" ) to return the xxx attribute, which is wrong
+
+ XMLList rv = newXMLList();
+
+ // TODO Should this also match processing instructions? If so, we have to change the filter and also the XMLName
+ // class to add an acceptsProcessingInstruction() method
+
+ XmlNode[] elements = this.node.getMatchingChildren(XmlNode.Filter.ELEMENT);
+ for (int i=0; i<elements.length; i++) {
+ if (xmlName.matchesElement(elements[i].getQname())) {
+ rv.addToList( toXML(elements[i]) );
+ }
+ }
+ rv.setTargets(this, xmlName.toQname());
+ return rv;
+ }
+
+ XML replace(XMLName xmlName, Object xml) {
+ putXMLProperty(xmlName, xml);
+ return this;
+ }
+
+ XMLList children() {
+ XMLList rv = newXMLList();
+ XMLName all = XMLName.formStar();
+ rv.setTargets(this, all.toQname());
+ XmlNode[] children = this.node.getMatchingChildren(XmlNode.Filter.TRUE);
+ for (int i=0; i<children.length; i++) {
+ rv.addToList( toXML(children[i]) );
+ }
+ return rv;
+ }
+
+ XMLList child(int index) {
+ // ECMA357 13.4.4.6 (numeric case)
+ XMLList result = newXMLList();
+ result.setTargets(this, null);
+ if (index >= 0 && index < this.node.getChildCount()) {
+ result.addToList(getXmlChild(index));
+ }
+ return result;
+ }
+
+ XML getXmlChild(int index) {
+ XmlNode child = this.node.getChild(index);
+ if (child.getXml() == null) {
+ child.setXml(newXML(child));
+ }
+ return child.getXml();
+ }
+
+ int childIndex() {
+ return this.node.getChildIndex();
+ }
+
+ boolean contains(Object xml) {
+ if (xml instanceof XML) {
+ return equivalentXml(xml);
+ } else {
+ return false;
+ }
+ }
+
+ // Method overriding XMLObjectImpl
+ boolean equivalentXml(Object target) {
+ boolean result = false;
+
+ if (target instanceof XML) {
+ // TODO This is a horrifyingly inefficient way to do this so we should make it better. It may also not work.
+ return this.node.toXmlString(getProcessor()).equals( ((XML)target).node.toXmlString(getProcessor()) );
+ } else if (target instanceof XMLList) {
+ // TODO Is this right? Check the spec ...
+ XMLList otherList = (XMLList) target;
+
+ if (otherList.length() == 1) {
+ result = equivalentXml(otherList.getXML());
+ }
+ } else if (hasSimpleContent()) {
+ String otherStr = ScriptRuntime.toString(target);
+
+ result = toString().equals(otherStr);
+ }
+
+ return result;
+ }
+
+ XMLObjectImpl copy() {
+ return newXML( this.node.copy() );
+ }
+
+ boolean hasSimpleContent() {
+ if (isComment() || isProcessingInstruction()) return false;
+ if (isText() || this.node.isAttributeType()) return true;
+ return !this.node.hasChildElement();
+ }
+
+ boolean hasComplexContent() {
+ return !hasSimpleContent();
+ }
+
+ // TODO Cross-reference comment below with spec
+ // Comment is: Length of an XML object is always 1, it's a list of XML objects of size 1.
+ int length() {
+ return 1;
+ }
+
+ // TODO it is not clear what this method was for ...
+ boolean is(XML other) {
+ return this.node.isSameNode(other.node);
+ }
+
+ Object nodeKind() {
+ return ecmaClass();
+ }
+
+ Object parent() {
+ XmlNode parent = this.node.parent();
+ if (parent == null) return null;
+ return newXML(this.node.parent());
+ }
+
+ boolean propertyIsEnumerable(Object name)
+ {
+ boolean result;
+ if (name instanceof Integer) {
+ result = (((Integer)name).intValue() == 0);
+ } else if (name instanceof Number) {
+ double x = ((Number)name).doubleValue();
+ // Check that number is positive 0
+ result = (x == 0.0 && 1.0 / x > 0);
+ } else {
+ result = ScriptRuntime.toString(name).equals("0");
+ }
+ return result;
+ }
+
+ Object valueOf() {
+ return this;
+ }
+
+ //
+ // Selection of children
+ //
+
+ XMLList comments() {
+ XMLList rv = newXMLList();
+ this.node.addMatchingChildren(rv, XmlNode.Filter.COMMENT);
+ return rv;
+ }
+
+ XMLList text() {
+ XMLList rv = newXMLList();
+ this.node.addMatchingChildren(rv, XmlNode.Filter.TEXT);
+ return rv;
+ }
+
+ XMLList processingInstructions(XMLName xmlName) {
+ XMLList rv = newXMLList();
+ this.node.addMatchingChildren(rv, XmlNode.Filter.PROCESSING_INSTRUCTION(xmlName));
+ return rv;
+ }
+
+ //
+ // Methods relating to modification of child nodes
+ //
+
+ // We create all the nodes we are inserting before doing the insert to
+ // avoid nasty cycles caused by mutability of these objects. For example,
+ // what if the toString() method of value modifies the XML object we were
+ // going to insert into? insertAfter might get confused about where to
+ // insert. This actually came up with SpiderMonkey, leading to a (very)
+ // long discussion. See bug #354145.
+ private XmlNode[] getNodesForInsert(Object value) {
+ if (value instanceof XML) {
+ return new XmlNode[] { ((XML)value).node };
+ } else if (value instanceof XMLList) {
+ XMLList list = (XMLList)value;
+ XmlNode[] rv = new XmlNode[list.length()];
+ for (int i=0; i<list.length(); i++) {
+ rv[i] = list.item(i).node;
+ }
+ return rv;
+ } else {
+ return new XmlNode[] {
+ XmlNode.createText(getProcessor(), ScriptRuntime.toString(value))
+ };
+ }
+ }
+
+ XML replace(int index, Object xml) {
+ XMLList xlChildToReplace = child(index);
+ if (xlChildToReplace.length() > 0) {
+ // One exists an that index
+ XML childToReplace = xlChildToReplace.item(0);
+ insertChildAfter(childToReplace, xml);
+ removeChild(index);
+ }
+ return this;
+ }
+
+ XML prependChild(Object xml) {
+ if (this.node.isParentType()) {
+ this.node.insertChildrenAt(0, getNodesForInsert(xml));
+ }
+ return this;
+ }
+
+ XML appendChild(Object xml) {
+ if (this.node.isParentType()) {
+ XmlNode[] nodes = getNodesForInsert(xml);
+ this.node.insertChildrenAt(this.node.getChildCount(), nodes);
+ }
+ return this;
+ }
+
+ private int getChildIndexOf(XML child) {
+ for (int i=0; i<this.node.getChildCount(); i++) {
+ if (this.node.getChild(i).isSameNode(child.node)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ XML insertChildBefore(XML child, Object xml) {
+ if (child == null) {
+ // Spec says inserting before nothing is the same as appending
+ appendChild(xml);
+ } else {
+ XmlNode[] toInsert = getNodesForInsert(xml);
+ int index = getChildIndexOf(child);
+ if (index != -1) {
+ this.node.insertChildrenAt(index, toInsert);
+ }
+ }
+
+ return this;
+ }
+
+ XML insertChildAfter(XML child, Object xml) {
+ if (child == null) {
+ // Spec says inserting after nothing is the same as prepending
+ prependChild(xml);
+ } else {
+ XmlNode[] toInsert = getNodesForInsert(xml);
+ int index = getChildIndexOf(child);
+ if (index != -1) {
+ this.node.insertChildrenAt(index+1, toInsert);
+ }
+ }
+
+ return this;
+ }
+
+ XML setChildren(Object xml) {
+ // TODO Have not carefully considered the spec but it seems to call for this
+ if (!isElement()) return this;
+
+ while(this.node.getChildCount() > 0) {
+ this.node.removeChild(0);
+ }
+ XmlNode[] toInsert = getNodesForInsert(xml);
+ // append new children
+ this.node.insertChildrenAt(0, toInsert);
+
+ return this;
+ }
+
+ //
+ // Name and namespace-related methods
+ //
+
+ private void addInScopeNamespace(Namespace ns) {
+ if (!isElement()) {
+ return;
+ }
+ // See ECMA357 9.1.1.13
+ // in this implementation null prefix means ECMA undefined
+ if (ns.prefix() != null) {
+ if (ns.prefix().length() == 0 && ns.uri().length() == 0) {
+ return;
+ }
+ if (node.getQname().getNamespace().getPrefix().equals(ns.prefix())) {
+ node.invalidateNamespacePrefix();
+ }
+ node.declareNamespace(ns.prefix(), ns.uri());
+ } else {
+ return;
+ }
+ }
+
+ Namespace[] inScopeNamespaces() {
+ XmlNode.Namespace[] inScope = this.node.getInScopeNamespaces();
+ return createNamespaces(inScope);
+ }
+
+ private XmlNode.Namespace adapt(Namespace ns) {
+ if (ns.prefix() == null) {
+ return XmlNode.Namespace.create(ns.uri());
+ } else {
+ return XmlNode.Namespace.create(ns.prefix(), ns.uri());
+ }
+ }
+
+ XML removeNamespace(Namespace ns) {
+ if (!isElement()) return this;
+ this.node.removeNamespace(adapt(ns));
+ return this;
+ }
+
+ XML addNamespace(Namespace ns) {
+ addInScopeNamespace(ns);
+ return this;
+ }
+
+ QName name() {
+ if (isText() || isComment()) return null;
+ if (isProcessingInstruction()) return newQName("", this.node.getQname().getLocalName(), null);
+ return newQName(node.getQname());
+ }
+
+ Namespace[] namespaceDeclarations() {
+ XmlNode.Namespace[] declarations = node.getNamespaceDeclarations();
+ return createNamespaces(declarations);
+ }
+
+ Namespace namespace(String prefix) {
+ if (prefix == null) {
+ return createNamespace( this.node.getNamespaceDeclaration() );
+ } else {
+ return createNamespace( this.node.getNamespaceDeclaration(prefix) );
+ }
+ }
+
+ String localName() {
+ if (name() == null) return null;
+ return name().localName();
+ }
+
+ void setLocalName(String localName) {
+ // ECMA357 13.4.4.34
+ if (isText() || isComment()) return;
+ this.node.setLocalName(localName);
+ }
+
+ void setName(QName name) {
+ // See ECMA357 13.4.4.35
+ if (isText() || isComment()) return;
+ if (isProcessingInstruction()) {
+ // Spec says set the name URI to empty string and then set the [[Name]] property, but I understand this to do the same
+ // thing, unless we allow colons in processing instruction targets, which I think we do not.
+ this.node.setLocalName(name.localName());
+ return;
+ }
+ node.renameNode(name.getDelegate());
+ }
+
+ void setNamespace(Namespace ns) {
+ // See ECMA357 13.4.4.36
+ if (isText() || isComment() || isProcessingInstruction()) return;
+ setName(newQName(ns.uri(), localName(), ns.prefix()));
+ }
+
+ final String ecmaClass() {
+ // See ECMA357 9.1
+
+ // TODO See ECMA357 9.1.1 last paragraph for what defaults should be
+
+ if (node.isTextType()) {
+ return "text";
+ } else if (node.isAttributeType()) {
+ return "attribute";
+ } else if (node.isCommentType()) {
+ return "comment";
+ } else if (node.isProcessingInstructionType()) {
+ return "processing-instruction";
+ } else if (node.isElementType()) {
+ return "element";
+ } else {
+ throw new RuntimeException("Unrecognized type: " + node);
+ }
+ }
+
+ public String getClassName() {
+ // TODO: This appears to confuse the interpreter if we use the "real" class property from ECMA. Otherwise this code
+ // would be:
+ // return ecmaClass();
+ return "XML";
+ }
+
+ private String ecmaValue() {
+ return node.ecmaValue();
+ }
+
+ private String ecmaToString() {
+ // See ECMA357 10.1.1
+ if (isAttribute() || isText()) {
+ return ecmaValue();
+ }
+ if (this.hasSimpleContent()) {
+ StringBuffer rv = new StringBuffer();
+ for (int i=0; i < this.node.getChildCount(); i++) {
+ XmlNode child = this.node.getChild(i);
+ if (!child.isProcessingInstructionType() &&
+ !child.isCommentType())
+ {
+ // TODO: Probably inefficient; taking clean non-optimized
+ // solution for now
+ XML x = new XML(getLib(), getParentScope(),
+ (XMLObject)getPrototype(), child);
+ rv.append(x.toString());
+ }
+ }
+ return rv.toString();
+ }
+ return toXMLString();
+ }
+
+ public String toString() {
+ return ecmaToString();
+ }
+
+ String toXMLString() {
+ return this.node.ecmaToXMLString(getProcessor());
+ }
+
+ final boolean isAttribute() {
+ return node.isAttributeType();
+ }
+
+ final boolean isComment() {
+ return node.isCommentType();
+ }
+
+ final boolean isText() {
+ return node.isTextType();
+ }
+
+ final boolean isElement() {
+ return node.isElementType();
+ }
+
+ final boolean isProcessingInstruction() {
+ return node.isProcessingInstructionType();
+ }
+
+ // Support experimental Java interface
+ org.w3c.dom.Node toDomNode() {
+ return node.toDomNode();
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLCtor.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLCtor.java
new file mode 100644
index 0000000..fac8773
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLCtor.java
@@ -0,0 +1,280 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+
+class XMLCtor extends IdFunctionObject
+{
+ static final long serialVersionUID = -8708195078359817341L;
+
+ private static final Object XMLCTOR_TAG = new Object();
+
+ private XmlProcessor options;
+// private XMLLibImpl lib;
+
+ XMLCtor(XML xml, Object tag, int id, int arity)
+ {
+ super(xml, tag, id, arity);
+// this.lib = xml.lib;
+ this.options = xml.getProcessor();
+ activatePrototypeMap(MAX_FUNCTION_ID);
+ }
+
+ private void writeSetting(Scriptable target)
+ {
+ for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
+ int id = super.getMaxInstanceId() + i;
+ String name = getInstanceIdName(id);
+ Object value = getInstanceIdValue(id);
+ ScriptableObject.putProperty(target, name, value);
+ }
+ }
+
+ private void readSettings(Scriptable source)
+ {
+ for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
+ int id = super.getMaxInstanceId() + i;
+ String name = getInstanceIdName(id);
+ Object value = ScriptableObject.getProperty(source, name);
+ if (value == Scriptable.NOT_FOUND) {
+ continue;
+ }
+ switch (i) {
+ case Id_ignoreComments:
+ case Id_ignoreProcessingInstructions:
+ case Id_ignoreWhitespace:
+ case Id_prettyPrinting:
+ if (!(value instanceof Boolean)) {
+ continue;
+ }
+ break;
+ case Id_prettyIndent:
+ if (!(value instanceof Number)) {
+ continue;
+ }
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ setInstanceIdValue(id, value);
+ }
+ }
+
+// #string_id_map#
+
+ private static final int
+ Id_ignoreComments = 1,
+ Id_ignoreProcessingInstructions = 2,
+ Id_ignoreWhitespace = 3,
+ Id_prettyIndent = 4,
+ Id_prettyPrinting = 5,
+
+ MAX_INSTANCE_ID = 5;
+
+ protected int getMaxInstanceId()
+ {
+ return super.getMaxInstanceId() + MAX_INSTANCE_ID;
+ }
+
+ protected int findInstanceIdInfo(String s) {
+ int id;
+// #generated# Last update: 2007-08-20 09:01:10 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 12: X="prettyIndent";id=Id_prettyIndent; break L;
+ case 14: c=s.charAt(0);
+ if (c=='i') { X="ignoreComments";id=Id_ignoreComments; }
+ else if (c=='p') { X="prettyPrinting";id=Id_prettyPrinting; }
+ break L;
+ case 16: X="ignoreWhitespace";id=Id_ignoreWhitespace; break L;
+ case 28: X="ignoreProcessingInstructions";id=Id_ignoreProcessingInstructions; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+
+ if (id == 0) return super.findInstanceIdInfo(s);
+
+ int attr;
+ switch (id) {
+ case Id_ignoreComments:
+ case Id_ignoreProcessingInstructions:
+ case Id_ignoreWhitespace:
+ case Id_prettyIndent:
+ case Id_prettyPrinting:
+ attr = PERMANENT | DONTENUM;
+ break;
+ default: throw new IllegalStateException();
+ }
+ return instanceIdInfo(attr, super.getMaxInstanceId() + id);
+ }
+
+// #/string_id_map#
+
+ protected String getInstanceIdName(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments: return "ignoreComments";
+ case Id_ignoreProcessingInstructions: return "ignoreProcessingInstructions";
+ case Id_ignoreWhitespace: return "ignoreWhitespace";
+ case Id_prettyIndent: return "prettyIndent";
+ case Id_prettyPrinting: return "prettyPrinting";
+ }
+ return super.getInstanceIdName(id);
+ }
+
+ protected Object getInstanceIdValue(int id)
+ {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments:
+ return ScriptRuntime.wrapBoolean(options.isIgnoreComments());
+ case Id_ignoreProcessingInstructions:
+ return ScriptRuntime.wrapBoolean(options.isIgnoreProcessingInstructions());
+ case Id_ignoreWhitespace:
+ return ScriptRuntime.wrapBoolean(options.isIgnoreWhitespace());
+ case Id_prettyIndent:
+ return ScriptRuntime.wrapInt(options.getPrettyIndent());
+ case Id_prettyPrinting:
+ return ScriptRuntime.wrapBoolean(options.isPrettyPrinting());
+ }
+ return super.getInstanceIdValue(id);
+ }
+
+ protected void setInstanceIdValue(int id, Object value) {
+ switch (id - super.getMaxInstanceId()) {
+ case Id_ignoreComments:
+ options.setIgnoreComments(ScriptRuntime.toBoolean(value));
+ return;
+ case Id_ignoreProcessingInstructions:
+ options.setIgnoreProcessingInstructions(ScriptRuntime.toBoolean(value));
+ return;
+ case Id_ignoreWhitespace:
+ options.setIgnoreWhitespace(ScriptRuntime.toBoolean(value));
+ return;
+ case Id_prettyIndent:
+ options.setPrettyIndent(ScriptRuntime.toInt32(value));
+ return;
+ case Id_prettyPrinting:
+ options.setPrettyPrinting(ScriptRuntime.toBoolean(value));
+ return;
+ }
+ super.setInstanceIdValue(id, value);
+ }
+
+// #string_id_map#
+ private static final int
+ Id_defaultSettings = 1,
+ Id_settings = 2,
+ Id_setSettings = 3,
+ MAX_FUNCTION_ID = 3;
+
+ protected int findPrototypeId(String s)
+ {
+ int id;
+// #generated# Last update: 2007-08-20 09:01:10 EDT
+ L0: { id = 0; String X = null;
+ int s_length = s.length();
+ if (s_length==8) { X="settings";id=Id_settings; }
+ else if (s_length==11) { X="setSettings";id=Id_setSettings; }
+ else if (s_length==15) { X="defaultSettings";id=Id_defaultSettings; }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id)
+ {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_defaultSettings: arity=0; s="defaultSettings"; break;
+ case Id_settings: arity=0; s="settings"; break;
+ case Id_setSettings: arity=1; s="setSettings"; break;
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(XMLCTOR_TAG, id, s, arity);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args)
+ {
+ if (!f.hasTag(XMLCTOR_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ switch (id) {
+ case Id_defaultSettings: {
+ options.setDefault();
+ Scriptable obj = cx.newObject(scope);
+ writeSetting(obj);
+ return obj;
+ }
+ case Id_settings: {
+ Scriptable obj = cx.newObject(scope);
+ writeSetting(obj);
+ return obj;
+ }
+ case Id_setSettings: {
+ if (args.length == 0
+ || args[0] == null
+ || args[0] == Undefined.instance)
+ {
+ options.setDefault();
+ } else if (args[0] instanceof Scriptable) {
+ readSettings((Scriptable)args[0]);
+ }
+ return Undefined.instance;
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ /**
+ hasInstance for XML objects works differently than other objects; see ECMA357 13.4.3.10.
+ */
+ public boolean hasInstance(Scriptable instance) {
+ return (instance instanceof XML || instance instanceof XMLList);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java
new file mode 100644
index 0000000..6d45240
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLLibImpl.java
@@ -0,0 +1,606 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import java.io.Serializable;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+public final class XMLLibImpl extends XMLLib implements Serializable {
+ // TODO Document that this only works with JDK 1.5 or backport its
+ // features to earlier versions
+ private static final long serialVersionUID = 1L;
+
+ //
+ // EXPERIMENTAL Java interface
+ //
+
+ /**
+ This experimental interface is undocumented.
+ */
+ public static org.w3c.dom.Node toDomNode(Object xmlObject) {
+ // Could return DocumentFragment for XMLList
+ // Probably a single node for XMLList with one element
+ if (xmlObject instanceof XML) {
+ return ((XML)xmlObject).toDomNode();
+ } else {
+ throw new IllegalArgumentException("xmlObject is not an XML object in JavaScript.");
+ }
+ }
+
+ public static void init(Context cx, Scriptable scope, boolean sealed) {
+ XMLLibImpl lib = new XMLLibImpl(scope);
+ XMLLib bound = lib.bindToScope(scope);
+ if (bound == lib) {
+ lib.exportToScope(sealed);
+ }
+ }
+
+ private Scriptable globalScope;
+
+ private XML xmlPrototype;
+ private XMLList xmlListPrototype;
+ private Namespace namespacePrototype;
+ private QName qnamePrototype;
+
+ private XmlProcessor options = new XmlProcessor();
+
+ private XMLLibImpl(Scriptable globalScope) {
+ this.globalScope = globalScope;
+ }
+
+ /** @deprecated */
+ QName qnamePrototype() {
+ return qnamePrototype;
+ }
+
+ /** @deprecated */
+ Scriptable globalScope() {
+ return globalScope;
+ }
+
+ XmlProcessor getProcessor() {
+ return options;
+ }
+
+ private void exportToScope(boolean sealed) {
+ xmlPrototype = newXML(XmlNode.createText(options, ""));
+ xmlListPrototype = newXMLList();
+ namespacePrototype = Namespace.create(this.globalScope, null, XmlNode.Namespace.GLOBAL);
+ qnamePrototype = QName.create(this, this.globalScope, null, XmlNode.QName.create(XmlNode.Namespace.create(""), ""));
+
+ xmlPrototype.exportAsJSClass(sealed);
+ xmlListPrototype.exportAsJSClass(sealed);
+ namespacePrototype.exportAsJSClass(sealed);
+ qnamePrototype.exportAsJSClass(sealed);
+ }
+
+ /** @deprecated */
+ XMLName toAttributeName(Context cx, Object nameValue) {
+ if (nameValue instanceof XMLName) {
+ // TODO Will this always be an XMLName of type attribute name?
+ return (XMLName)nameValue;
+ } else if (nameValue instanceof QName) {
+ return XMLName.create( ((QName)nameValue).getDelegate(), true, false );
+ } else if (nameValue instanceof Boolean
+ || nameValue instanceof Number
+ || nameValue == Undefined.instance
+ || nameValue == null) {
+ throw badXMLName(nameValue);
+ } else {
+ // TODO Not 100% sure that putting these in global namespace is the right thing to do
+ String localName = null;
+ if (nameValue instanceof String) {
+ localName = (String)nameValue;
+ } else {
+ localName = ScriptRuntime.toString(nameValue);
+ }
+ if (localName != null && localName.equals("*")) localName = null;
+ return XMLName.create(XmlNode.QName.create(XmlNode.Namespace.create(""), localName), true, false);
+ }
+ }
+
+ private static RuntimeException badXMLName(Object value)
+ {
+ String msg;
+ if (value instanceof Number) {
+ msg = "Can not construct XML name from number: ";
+ } else if (value instanceof Boolean) {
+ msg = "Can not construct XML name from boolean: ";
+ } else if (value == Undefined.instance || value == null) {
+ msg = "Can not construct XML name from ";
+ } else {
+ throw new IllegalArgumentException(value.toString());
+ }
+ return ScriptRuntime.typeError(msg+ScriptRuntime.toString(value));
+ }
+
+ XMLName toXMLNameFromString(Context cx, String name) {
+ return XMLName.create( getDefaultNamespaceURI(cx), name );
+ }
+
+ /** @deprecated */
+ XMLName toXMLName(Context cx, Object nameValue) {
+ XMLName result;
+
+ if (nameValue instanceof XMLName) {
+ result = (XMLName)nameValue;
+ } else if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ result = XMLName.formProperty(qname.uri(), qname.localName());
+ } else if (nameValue instanceof String) {
+ result = toXMLNameFromString(cx, (String)nameValue);
+ } else if (nameValue instanceof Boolean
+ || nameValue instanceof Number
+ || nameValue == Undefined.instance
+ || nameValue == null) {
+ throw badXMLName(nameValue);
+ } else {
+ String name = ScriptRuntime.toString(nameValue);
+ result = toXMLNameFromString(cx, name);
+ }
+
+ return result;
+ }
+
+ /**
+ * If value represents Uint32 index, make it available through
+ * ScriptRuntime.lastUint32Result(cx) and return null.
+ * Otherwise return the same value as toXMLName(cx, value).
+ */
+ XMLName toXMLNameOrIndex(Context cx, Object value)
+ {
+ XMLName result;
+
+ if (value instanceof XMLName) {
+ result = (XMLName)value;
+ } else if (value instanceof String) {
+ String str = (String)value;
+ long test = ScriptRuntime.testUint32String(str);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ result = null;
+ } else {
+ result = toXMLNameFromString(cx, str);
+ }
+ } else if (value instanceof Number) {
+ double d = ((Number)value).doubleValue();
+ long l = (long)d;
+ if (l == d && 0 <= l && l <= 0xFFFFFFFFL) {
+ ScriptRuntime.storeUint32Result(cx, l);
+ result = null;
+ } else {
+ throw badXMLName(value);
+ }
+ } else if (value instanceof QName) {
+ QName qname = (QName)value;
+ String uri = qname.uri();
+ boolean number = false;
+ result = null;
+ if (uri != null && uri.length() == 0) {
+ // Only in this case qname.toString() can resemble uint32
+ long test = ScriptRuntime.testUint32String(uri);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ number = true;
+ }
+ }
+ if (!number) {
+ result = XMLName.formProperty(uri, qname.localName());
+ }
+ } else if (value instanceof Boolean
+ || value == Undefined.instance
+ || value == null)
+ {
+ throw badXMLName(value);
+ } else {
+ String str = ScriptRuntime.toString(value);
+ long test = ScriptRuntime.testUint32String(str);
+ if (test >= 0) {
+ ScriptRuntime.storeUint32Result(cx, test);
+ result = null;
+ } else {
+ result = toXMLNameFromString(cx, str);
+ }
+ }
+
+ return result;
+ }
+
+ Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
+ {
+ XMLList listToAdd = newXMLList();
+
+ if (obj1 instanceof XMLList) {
+ XMLList list1 = (XMLList)obj1;
+ if (list1.length() == 1) {
+ listToAdd.addToList(list1.item(0));
+ } else {
+ // Might be xmlFragment + xmlFragment + xmlFragment + ...;
+ // then the result will be an XMLList which we want to be an
+ // rValue and allow it to be assigned to an lvalue.
+ listToAdd = newXMLListFrom(obj1);
+ }
+ } else {
+ listToAdd.addToList(obj1);
+ }
+
+ if (obj2 instanceof XMLList) {
+ XMLList list2 = (XMLList)obj2;
+ for (int i = 0; i < list2.length(); i++) {
+ listToAdd.addToList(list2.item(i));
+ }
+ } else if (obj2 instanceof XML) {
+ listToAdd.addToList(obj2);
+ }
+
+ return listToAdd;
+ }
+
+ private Ref xmlPrimaryReference(Context cx, XMLName xmlName, Scriptable scope) {
+ XMLObjectImpl xmlObj;
+ XMLObjectImpl firstXml = null;
+ for (;;) {
+ // XML object can only present on scope chain as a wrapper
+ // of XMLWithScope
+ if (scope instanceof XMLWithScope) {
+ xmlObj = (XMLObjectImpl)scope.getPrototype();
+ if (xmlObj.hasXMLProperty(xmlName)) {
+ break;
+ }
+ if (firstXml == null) {
+ firstXml = xmlObj;
+ }
+ }
+ scope = scope.getParentScope();
+ if (scope == null) {
+ xmlObj = firstXml;
+ break;
+ }
+ }
+
+ // xmlObj == null corresponds to undefined as the target of
+ // the reference
+ if (xmlObj != null) {
+ xmlName.initXMLObject(xmlObj);
+ }
+ return xmlName;
+ }
+
+ Namespace castToNamespace(Context cx, Object namespaceObj) {
+ return this.namespacePrototype.castToNamespace(namespaceObj);
+ }
+
+ private String getDefaultNamespaceURI(Context cx) {
+ return getDefaultNamespace(cx).uri();
+ }
+
+ Namespace newNamespace(String uri) {
+ return this.namespacePrototype.newNamespace(uri);
+ }
+
+ Namespace getDefaultNamespace(Context cx) {
+ if (cx == null) {
+ cx = Context.getCurrentContext();
+ if (cx == null) {
+ return namespacePrototype;
+ }
+ }
+
+ Object ns = ScriptRuntime.searchDefaultNamespace(cx);
+ if (ns == null) {
+ return namespacePrototype;
+ } else {
+ if (ns instanceof Namespace) {
+ return (Namespace)ns;
+ } else {
+ // TODO Clarify or remove the following comment
+ // Should not happen but for now it could
+ // due to bad searchDefaultNamespace implementation.
+ return namespacePrototype;
+ }
+ }
+ }
+
+ Namespace[] createNamespaces(XmlNode.Namespace[] declarations) {
+ Namespace[] rv = new Namespace[declarations.length];
+ for (int i=0; i<declarations.length; i++) {
+ rv[i] = this.namespacePrototype.newNamespace(declarations[i].getPrefix(), declarations[i].getUri());
+ }
+ return rv;
+ }
+
+ // See ECMA357 13.3.2
+ QName constructQName(Context cx, Object namespace, Object name) {
+ return this.qnamePrototype.constructQName(this, cx, namespace, name);
+ }
+
+ QName newQName(String uri, String localName, String prefix) {
+ return this.qnamePrototype.newQName(this, uri, localName, prefix);
+ }
+
+ QName constructQName(Context cx, Object nameValue) {
+// return constructQName(cx, Undefined.instance, nameValue);
+ return this.qnamePrototype.constructQName(this, cx, nameValue);
+ }
+
+ QName castToQName(Context cx, Object qnameValue) {
+ return this.qnamePrototype.castToQName(this, cx, qnameValue);
+ }
+
+ QName newQName(XmlNode.QName qname) {
+ return QName.create(this, this.globalScope, this.qnamePrototype, qname);
+ }
+
+ XML newXML(XmlNode node) {
+ return new XML(this, this.globalScope, this.xmlPrototype, node);
+ }
+
+ /**
+ @deprecated I believe this can be replaced by ecmaToXml below.
+ */
+ final XML newXMLFromJs(Object inputObject) {
+ String frag;
+
+ if (inputObject == null || inputObject == Undefined.instance) {
+ frag = "";
+ } else if (inputObject instanceof XMLObjectImpl) {
+ // todo: faster way for XMLObjects?
+ frag = ((XMLObjectImpl) inputObject).toXMLString();
+ } else {
+ frag = ScriptRuntime.toString(inputObject);
+ }
+
+ if (frag.trim().startsWith("<>")) {
+ throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <></>.");
+ }
+
+ if (frag.indexOf("<") == -1) {
+ // Solo text node
+ return newXML(XmlNode.createText(options, frag));
+ }
+ return parse(frag);
+ }
+
+ private XML parse(String frag) {
+ try {
+ return newXML(XmlNode.createElement(options, getDefaultNamespaceURI(Context.getCurrentContext()), frag));
+ } catch (org.xml.sax.SAXException e) {
+ throw ScriptRuntime.typeError("Cannot parse XML: " + e.getMessage());
+ }
+ }
+
+ final XML ecmaToXml(Object object) {
+ // See ECMA357 10.3
+ if (object == null || object == Undefined.instance) throw ScriptRuntime.typeError("Cannot convert " + object + " to XML");
+ if (object instanceof XML) return (XML)object;
+ if (object instanceof XMLList) {
+ XMLList list = (XMLList)object;
+ if (list.getXML() != null) {
+ return list.getXML();
+ } else {
+ throw ScriptRuntime.typeError("Cannot convert list of >1 element to XML");
+ }
+ }
+ // TODO Technically we should fail on anything except a String, Number or Boolean
+ // See ECMA357 10.3
+ // Extension: if object is a DOM node, use that to construct the XML
+ // object.
+ if (object instanceof Wrapper) {
+ object = ((Wrapper) object).unwrap();
+ }
+ if (object instanceof org.w3c.dom.Node) {
+ org.w3c.dom.Node node = (org.w3c.dom.Node) object;
+ return newXML(XmlNode.createElementFromNode(node));
+ }
+ // Instead we just blindly cast to a String and let them convert anything.
+ String s = ScriptRuntime.toString(object);
+ // TODO Could this get any uglier?
+ if (s.length() > 0 && s.charAt(0) == '<') {
+ return parse(s);
+ } else {
+ return newXML(XmlNode.createText(options, s));
+ }
+ }
+
+ final XML newTextElementXML(XmlNode reference, XmlNode.QName qname, String value) {
+ return newXML(XmlNode.newElementWithText(options, reference, qname, value));
+ }
+
+ XMLList newXMLList() {
+ return new XMLList(this, this.globalScope, this.xmlListPrototype);
+ }
+
+ final XMLList newXMLListFrom(Object inputObject) {
+ XMLList rv = newXMLList();
+
+ if (inputObject == null || inputObject instanceof Undefined) {
+ return rv;
+ } else if (inputObject instanceof XML) {
+ XML xml = (XML) inputObject;
+ rv.getNodeList().add(xml);
+ return rv;
+ } else if (inputObject instanceof XMLList) {
+ XMLList xmll = (XMLList) inputObject;
+ rv.getNodeList().add(xmll.getNodeList());
+ return rv;
+ } else {
+ String frag = ScriptRuntime.toString(inputObject).trim();
+
+ if (!frag.startsWith("<>")) {
+ frag = "<>" + frag + "</>";
+ }
+
+ frag = "<fragment>" + frag.substring(2);
+ if (!frag.endsWith("</>")) {
+ throw ScriptRuntime.typeError("XML with anonymous tag missing end anonymous tag");
+ }
+
+ frag = frag.substring(0, frag.length() - 3) + "</fragment>";
+
+ XML orgXML = newXMLFromJs(frag);
+
+ // Now orphan the children and add them to our XMLList.
+ XMLList children = orgXML.children();
+
+ for (int i = 0; i < children.getNodeList().length(); i++) {
+ // Copy here is so that they'll be orphaned (parent() will be undefined)
+ rv.getNodeList().add(((XML) children.item(i).copy()));
+ }
+ return rv;
+ }
+ }
+
+ XmlNode.QName toNodeQName(Context cx, Object namespaceValue, Object nameValue) {
+ // This is duplication of constructQName(cx, namespaceValue, nameValue)
+ // but for XMLName
+
+ String localName;
+
+ if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ localName = qname.localName();
+ } else {
+ localName = ScriptRuntime.toString(nameValue);
+ }
+
+ XmlNode.Namespace ns;
+ if (namespaceValue == Undefined.instance) {
+ if ("*".equals(localName)) {
+ ns = null;
+ } else {
+ ns = getDefaultNamespace(cx).getDelegate();
+ }
+ } else if (namespaceValue == null) {
+ ns = null;
+ } else if (namespaceValue instanceof Namespace) {
+ ns = ((Namespace)namespaceValue).getDelegate();
+ } else {
+ ns = this.namespacePrototype.constructNamespace(namespaceValue).getDelegate();
+ }
+
+ if (localName != null && localName.equals("*")) localName = null;
+ return XmlNode.QName.create(ns, localName);
+ }
+
+ XmlNode.QName toNodeQName(Context cx, String name, boolean attribute) {
+ XmlNode.Namespace defaultNamespace = getDefaultNamespace(cx).getDelegate();
+ if (name != null && name.equals("*")) {
+ return XmlNode.QName.create(null, null);
+ } else {
+ if (attribute) {
+ return XmlNode.QName.create(XmlNode.Namespace.GLOBAL, name);
+ } else {
+ return XmlNode.QName.create(defaultNamespace, name);
+ }
+ }
+ }
+
+ /**
+ @deprecated Too general; this should be split into overloaded methods.
+ Is that possible?
+ */
+ XmlNode.QName toNodeQName(Context cx, Object nameValue, boolean attribute) {
+ if (nameValue instanceof XMLName) {
+ return ((XMLName)nameValue).toQname();
+ } else if (nameValue instanceof QName) {
+ QName qname = (QName)nameValue;
+ return qname.getDelegate();
+ } else if (
+ nameValue instanceof Boolean
+ || nameValue instanceof Number
+ || nameValue == Undefined.instance
+ || nameValue == null
+ ) {
+ throw badXMLName(nameValue);
+ } else {
+ String local = null;
+ if (nameValue instanceof String) {
+ local = (String)nameValue;
+ } else {
+ local = ScriptRuntime.toString(nameValue);
+ }
+ return toNodeQName(cx, local, attribute);
+ }
+ }
+
+ //
+ // Override methods from XMLLib
+ //
+
+ public boolean isXMLName(Context _cx, Object nameObj) {
+ return XMLName.accept(nameObj);
+ }
+
+ public Object toDefaultXmlNamespace(Context cx, Object uriValue) {
+ return this.namespacePrototype.constructNamespace(uriValue);
+ }
+
+ public String escapeTextValue(Object o) {
+ return options.escapeTextValue(o);
+ }
+
+ public String escapeAttributeValue(Object o) {
+ return options.escapeAttributeValue(o);
+ }
+
+ public Ref nameRef(Context cx, Object name, Scriptable scope, int memberTypeFlags) {
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) {
+ // should only be called foir cases like @name or @[expr]
+ throw Kit.codeBug();
+ }
+ XMLName xmlName = toAttributeName(cx, name);
+ return xmlPrimaryReference(cx, xmlName, scope);
+ }
+
+ public Ref nameRef(Context cx, Object namespace, Object name, Scriptable scope, int memberTypeFlags) {
+ XMLName xmlName = XMLName.create(toNodeQName(cx, namespace, name), false, false);
+
+ // No idea what is coming in from the parser in this case; is it detecting the "@"?
+ if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
+ if (!xmlName.isAttributeName()) {
+ xmlName.setAttributeName();
+ }
+ }
+
+ return xmlPrimaryReference(cx, xmlName, scope);
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java
new file mode 100644
index 0000000..59dcca3
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLList.java
@@ -0,0 +1,765 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+class XMLList extends XMLObjectImpl implements Function {
+ static final long serialVersionUID = -4543618751670781135L;
+
+ private XmlNode.List _annos;
+ private XMLObjectImpl targetObject = null;
+ private XmlNode.QName targetProperty = null;
+
+ XMLList(XMLLibImpl lib, Scriptable scope, XMLObject prototype) {
+ super(lib, scope, prototype);
+ _annos = new XmlNode.List();
+ }
+
+ /** @deprecated Will probably end up unnecessary as we move things around */
+ XmlNode.List getNodeList() {
+ return _annos;
+ }
+
+ // TODO Should be XMLObjectImpl, XMLName?
+ void setTargets(XMLObjectImpl object, XmlNode.QName property) {
+ targetObject = object;
+ targetProperty = property;
+ }
+
+ /** @deprecated */
+ private XML getXmlFromAnnotation(int index) {
+ return getXML(_annos, index);
+ }
+
+ XML getXML() {
+ if (length() == 1) return getXmlFromAnnotation(0);
+ return null;
+ }
+
+ private void internalRemoveFromList(int index) {
+ _annos.remove(index);
+ }
+
+ void replace(int index, XML xml) {
+ if (index < length()) {
+ XmlNode.List newAnnoList = new XmlNode.List();
+ newAnnoList.add(_annos, 0, index);
+ newAnnoList.add(xml);
+ newAnnoList.add(_annos, index+1, length());
+ _annos = newAnnoList;
+ }
+ }
+
+ private void insert(int index, XML xml) {
+ if (index < length()) {
+ XmlNode.List newAnnoList = new XmlNode.List();
+ newAnnoList.add(_annos, 0, index);
+ newAnnoList.add(xml);
+ newAnnoList.add(_annos, index, length());
+ _annos = newAnnoList;
+ }
+ }
+
+ //
+ //
+ // methods overriding ScriptableObject
+ //
+ //
+
+ public String getClassName() {
+ return "XMLList";
+ }
+
+ //
+ //
+ // methods overriding IdScriptableObject
+ //
+ //
+
+ public Object get(int index, Scriptable start) {
+ //Log("get index: " + index);
+
+ if (index >= 0 && index < length()) {
+ return getXmlFromAnnotation(index);
+ } else {
+ return Scriptable.NOT_FOUND;
+ }
+ }
+
+ boolean hasXMLProperty(XMLName xmlName) {
+ boolean result = false;
+
+ // Has now should return true if the property would have results > 0 or
+ // if it's a method name
+ String name = xmlName.localName();
+ if ((getPropertyList(xmlName).length() > 0) ||
+ (getMethod(name) != NOT_FOUND)) {
+ result = true;
+ }
+
+ return result;
+ }
+
+ public boolean has(int index, Scriptable start) {
+ return 0 <= index && index < length();
+ }
+
+ void putXMLProperty(XMLName xmlName, Object value) {
+ //Log("put property: " + name);
+
+ // Special-case checks for undefined and null
+ if (value == null) {
+ value = "null";
+ } else if (value instanceof Undefined) {
+ value = "undefined";
+ }
+
+ if (length() > 1) {
+ throw ScriptRuntime.typeError("Assignment to lists with more than one item is not supported");
+ } else if (length() == 0) {
+ // Secret sauce for super-expandos.
+ // We set an element here, and then add ourselves to our target.
+ if (targetObject != null && targetProperty != null && targetProperty.getLocalName() != null) {
+ // Add an empty element with our targetProperty name and then set it.
+ XML xmlValue = newTextElementXML(null, targetProperty, null);
+ addToList(xmlValue);
+
+ if(xmlName.isAttributeName()) {
+ setAttribute(xmlName, value);
+ } else {
+ XML xml = item(0);
+ xml.putXMLProperty(xmlName, value);
+
+ // Update the list with the new item at location 0.
+ replace(0, item(0));
+ }
+
+ // Now add us to our parent
+ XMLName name2 = XMLName.formProperty(targetProperty.getUri(), targetProperty.getLocalName());
+ targetObject.putXMLProperty(name2, this);
+ } else {
+ throw ScriptRuntime.typeError("Assignment to empty XMLList without targets not supported");
+ }
+ } else if(xmlName.isAttributeName()) {
+ setAttribute(xmlName, value);
+ } else {
+ XML xml = item(0);
+ xml.putXMLProperty(xmlName, value);
+
+ // Update the list with the new item at location 0.
+ replace(0, item(0));
+ }
+ }
+
+ Object getXMLProperty(XMLName name) {
+ return getPropertyList(name);
+ }
+
+ private void replaceNode(XML xml, XML with) {
+ xml.replaceWith(with);
+ }
+
+ public void put(int index, Scriptable start, Object value) {
+ Object parent = Undefined.instance;
+ // Convert text into XML if needed.
+ XMLObject xmlValue;
+
+ // Special-case checks for undefined and null
+ if (value == null) {
+ value = "null";
+ } else if (value instanceof Undefined) {
+ value = "undefined";
+ }
+
+ if (value instanceof XMLObject) {
+ xmlValue = (XMLObject) value;
+ } else {
+ if (targetProperty == null) {
+ xmlValue = newXMLFromJs(value.toString());
+ } else {
+ // Note that later in the code, we will use this as an argument to replace(int,value)
+ // So we will be "replacing" this element with itself
+ // There may well be a better way to do this
+ // TODO Find a way to refactor this whole method and simplify it
+ xmlValue = item(index);
+ ((XML)xmlValue).setChildren(value);
+ }
+ }
+
+ // Find the parent
+ if (index < length()) {
+ parent = item(index).parent();
+ } else {
+ // Appending
+ parent = parent();
+ }
+
+ if (parent instanceof XML) {
+ // found parent, alter doc
+ XML xmlParent = (XML) parent;
+
+ if (index < length()) {
+ // We're replacing the the node.
+ XML xmlNode = getXmlFromAnnotation(index);
+
+ if (xmlValue instanceof XML) {
+ replaceNode(xmlNode, (XML) xmlValue);
+ replace(index, xmlNode);
+ } else if (xmlValue instanceof XMLList) {
+ // Replace the first one, and add the rest on the list.
+ XMLList list = (XMLList) xmlValue;
+
+ if (list.length() > 0) {
+ int lastIndexAdded = xmlNode.childIndex();
+ replaceNode(xmlNode, list.item(0));
+ replace(index, list.item(0));
+
+ for (int i = 1; i < list.length(); i++) {
+ xmlParent.insertChildAfter(xmlParent.getXmlChild(lastIndexAdded), list.item(i));
+ lastIndexAdded++;
+ insert(index + i, list.item(i));
+ }
+ }
+ }
+ } else {
+ // Appending
+ xmlParent.appendChild(xmlValue);
+ addToList(xmlParent.getXmlChild(index));
+ }
+ } else {
+ // Don't all have same parent, no underlying doc to alter
+ if (index < length()) {
+ XML xmlNode = getXML(_annos, index);
+
+ if (xmlValue instanceof XML) {
+ replaceNode(xmlNode, (XML) xmlValue);
+ replace(index, xmlNode);
+ } else if (xmlValue instanceof XMLList) {
+ // Replace the first one, and add the rest on the list.
+ XMLList list = (XMLList) xmlValue;
+
+ if (list.length() > 0) {
+ replaceNode(xmlNode, list.item(0));
+ replace(index, list.item(0));
+
+ for (int i = 1; i < list.length(); i++) {
+ insert(index + i, list.item(i));
+ }
+ }
+ }
+ } else {
+ addToList(xmlValue);
+ }
+ }
+ }
+
+ private XML getXML(XmlNode.List _annos, int index) {
+ if (index >= 0 && index < length()) {
+ return xmlFromNode(_annos.item(index));
+ } else {
+ return null;
+ }
+ }
+
+ void deleteXMLProperty(XMLName name) {
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+
+ if (xml.isElement()) {
+ xml.deleteXMLProperty(name);
+ }
+ }
+ }
+
+ public void delete(int index) {
+ if (index >= 0 && index < length()) {
+ XML xml = getXmlFromAnnotation(index);
+
+ xml.remove();
+
+ internalRemoveFromList(index);
+ }
+ }
+
+ public Object[] getIds() {
+ Object enumObjs[];
+
+ if (isPrototype()) {
+ enumObjs = new Object[0];
+ } else {
+ enumObjs = new Object[length()];
+
+ for (int i = 0; i < enumObjs.length; i++) {
+ enumObjs[i] = new Integer(i);
+ }
+ }
+
+ return enumObjs;
+ }
+
+ public Object[] getIdsForDebug() {
+ return getIds();
+ }
+
+
+ // XMLList will remove will delete all items in the list (a set delete) this differs from the XMLList delete operator.
+ void remove() {
+ int nLen = length();
+ for (int i = nLen - 1; i >= 0; i--) {
+ XML xml = getXmlFromAnnotation(i);
+ if (xml != null) {
+ xml.remove();
+ internalRemoveFromList(i);
+ }
+ }
+ }
+
+ XML item(int index) {
+ return _annos != null
+ ? getXmlFromAnnotation(index) : createEmptyXML();
+ }
+
+ private void setAttribute(XMLName xmlName, Object value) {
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+ xml.setAttribute(xmlName, value);
+ }
+ }
+
+ void addToList(Object toAdd) {
+ _annos.addToList(toAdd);
+ }
+
+ //
+ //
+ // Methods from section 12.4.4 in the spec
+ //
+ //
+
+ XMLList child(int index) {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ result.addToList(getXmlFromAnnotation(i).child(index));
+ }
+
+ return result;
+ }
+
+ XMLList child(XMLName xmlName) {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ result.addToList(getXmlFromAnnotation(i).child(xmlName));
+ }
+
+ return result;
+ }
+
+ void addMatches(XMLList rv, XMLName name) {
+ for (int i=0; i<length(); i++) {
+ getXmlFromAnnotation(i).addMatches(rv, name);
+ }
+ }
+
+ XMLList children() {
+ java.util.Vector v = new java.util.Vector();
+
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+
+ if (xml != null) {
+ Object o = xml.children();
+ if (o instanceof XMLList) {
+ XMLList childList = (XMLList)o;
+
+ int cChildren = childList.length();
+ for (int j = 0; j < cChildren; j++) {
+ v.addElement(childList.item(j));
+ }
+ }
+ }
+ }
+
+ XMLList allChildren = newXMLList();
+ int sz = v.size();
+
+ for (int i = 0; i < sz; i++) {
+ allChildren.addToList(v.get(i));
+ }
+
+ return allChildren;
+ }
+
+ XMLList comments() {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.comments());
+ }
+
+ return result;
+ }
+
+ XMLList elements(XMLName name) {
+ XMLList rv = newXMLList();
+ for (int i=0; i<length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+ rv.addToList(xml.elements(name));
+ }
+ return rv;
+ }
+
+ boolean contains(Object xml) {
+ boolean result = false;
+
+ for (int i = 0; i < length(); i++) {
+ XML member = getXmlFromAnnotation(i);
+
+ if (member.equivalentXml(xml)) {
+ result = true;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ XMLObjectImpl copy() {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+ result.addToList(xml.copy());
+ }
+
+ return result;
+ }
+
+ boolean hasOwnProperty(XMLName xmlName) {
+ if (isPrototype()) {
+ String property = xmlName.localName();
+ return (findPrototypeId(property) != 0);
+ } else {
+ return (getPropertyList(xmlName).length() > 0);
+ }
+ }
+
+ boolean hasComplexContent() {
+ boolean complexContent;
+ int length = length();
+
+ if (length == 0) {
+ complexContent = false;
+ } else if (length == 1) {
+ complexContent = getXmlFromAnnotation(0).hasComplexContent();
+ } else {
+ complexContent = false;
+
+ for (int i = 0; i < length; i++) {
+ XML nextElement = getXmlFromAnnotation(i);
+ if (nextElement.isElement()) {
+ complexContent = true;
+ break;
+ }
+ }
+ }
+
+ return complexContent;
+ }
+
+ boolean hasSimpleContent() {
+ if (length() == 0) {
+ return true;
+ } else if (length() == 1) {
+ return getXmlFromAnnotation(0).hasSimpleContent();
+ } else {
+ for (int i=0; i<length(); i++) {
+ XML nextElement = getXmlFromAnnotation(i);
+ if (nextElement.isElement()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ int length() {
+ int result = 0;
+
+ if (_annos != null) {
+ result = _annos.length();
+ }
+
+ return result;
+ }
+
+ void normalize() {
+ for (int i = 0; i < length(); i++) {
+ getXmlFromAnnotation(i).normalize();
+ }
+ }
+
+ /**
+ * If list is empty, return undefined, if elements have different parents return undefined,
+ * If they all have the same parent, return that parent
+ */
+ Object parent() {
+ if (length() == 0) return Undefined.instance;
+
+ XML candidateParent = null;
+
+ for (int i = 0; i < length(); i++) {
+ Object currParent = getXmlFromAnnotation(i).parent();
+ if (!(currParent instanceof XML)) return Undefined.instance;
+ XML xml = (XML)currParent;
+ if (i == 0) {
+ // Set the first for the rest to compare to.
+ candidateParent = xml;
+ } else {
+ if (candidateParent.is(xml)) {
+ // keep looking
+ } else {
+ return Undefined.instance;
+ }
+ }
+ }
+ return candidateParent;
+ }
+
+ XMLList processingInstructions(XMLName xmlName) {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ XML xml = getXmlFromAnnotation(i);
+
+ result.addToList(xml.processingInstructions(xmlName));
+ }
+
+ return result;
+ }
+
+ boolean propertyIsEnumerable(Object name) {
+ long index;
+ if (name instanceof Integer) {
+ index = ((Integer)name).intValue();
+ } else if (name instanceof Number) {
+ double x = ((Number)name).doubleValue();
+ index = (long)x;
+ if (index != x) {
+ return false;
+ }
+ if (index == 0 && 1.0 / x < 0) {
+ // Negative 0
+ return false;
+ }
+ } else {
+ String s = ScriptRuntime.toString(name);
+ index = ScriptRuntime.testUint32String(s);
+ }
+ return (0 <= index && index < length());
+ }
+
+ XMLList text() {
+ XMLList result = newXMLList();
+
+ for (int i = 0; i < length(); i++) {
+ result.addToList(getXmlFromAnnotation(i).text());
+ }
+
+ return result;
+ }
+
+ public String toString() {
+ // ECMA357 10.1.2
+ if (hasSimpleContent()) {
+ StringBuffer sb = new StringBuffer();
+
+ for(int i = 0; i < length(); i++) {
+ XML next = getXmlFromAnnotation(i);
+ if (next.isComment() || next.isProcessingInstruction()) {
+ // do nothing
+ } else {
+ sb.append(next.toString());
+ }
+ }
+
+ return sb.toString();
+ } else {
+ return toXMLString();
+ }
+ }
+
+ String toXMLString() {
+ // See ECMA 10.2.1
+ StringBuffer sb = new StringBuffer();
+
+ for (int i=0; i<length(); i++) {
+ if (getProcessor().isPrettyPrinting() && i != 0) {
+ sb.append('\n');
+ }
+ sb.append(getXmlFromAnnotation(i).toXMLString());
+ }
+ return sb.toString();
+ }
+
+ Object valueOf() {
+ return this;
+ }
+
+ //
+ // Other public Functions from XMLObject
+ //
+
+ boolean equivalentXml(Object target) {
+ boolean result = false;
+
+ // Zero length list should equate to undefined
+ if (target instanceof Undefined && length() == 0) {
+ result = true;
+ } else if (length() == 1) {
+ result = getXmlFromAnnotation(0).equivalentXml(target);
+ } else if (target instanceof XMLList) {
+ XMLList otherList = (XMLList) target;
+
+ if (otherList.length() == length()) {
+ result = true;
+
+ for (int i = 0; i < length(); i++) {
+ if (!getXmlFromAnnotation(i).equivalentXml(otherList.getXmlFromAnnotation(i))) {
+ result = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private XMLList getPropertyList(XMLName name) {
+ XMLList propertyList = newXMLList();
+ XmlNode.QName qname = null;
+
+ if (!name.isDescendants() && !name.isAttributeName()) {
+ // Only set the targetProperty if this is a regular child get
+ // and not a descendant or attribute get
+ qname = name.toQname();
+ }
+
+ propertyList.setTargets(this, qname);
+
+ for (int i = 0; i < length(); i++) {
+ propertyList.addToList(
+ getXmlFromAnnotation(i).getPropertyList(name));
+ }
+
+ return propertyList;
+ }
+
+ private Object applyOrCall(boolean isApply,
+ Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args) {
+ String methodName = isApply ? "apply" : "call";
+ if(!(thisObj instanceof XMLList) ||
+ ((XMLList)thisObj).targetProperty == null)
+ throw ScriptRuntime.typeError1("msg.isnt.function",
+ methodName);
+
+ return ScriptRuntime.applyOrCall(isApply, cx, scope, thisObj, args);
+ }
+
+ protected Object jsConstructor(Context cx, boolean inNewExpr,
+ Object[] args) {
+ if (args.length == 0) {
+ return newXMLList();
+ } else {
+ Object arg0 = args[0];
+ if (!inNewExpr && arg0 instanceof XMLList) {
+ // XMLList(XMLList) returns the same object.
+ return arg0;
+ }
+ return newXMLListFrom(arg0);
+ }
+ }
+
+ /**
+ * See ECMA 357, 11_2_2_1, Semantics, 3_e.
+ */
+ public Scriptable getExtraMethodSource(Context cx) {
+ if (length() == 1) {
+ return getXmlFromAnnotation(0);
+ }
+ return null;
+ }
+
+ public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+ Object[] args) {
+ // This XMLList is being called as a Function.
+ // Let's find the real Function object.
+ if(targetProperty == null)
+ throw ScriptRuntime.notFunctionError(this);
+
+ String methodName = targetProperty.getLocalName();
+
+ boolean isApply = methodName.equals("apply");
+ if(isApply || methodName.equals("call"))
+ return applyOrCall(isApply, cx, scope, thisObj, args);
+
+ Callable method = ScriptRuntime.getElemFunctionAndThis(
+ this, methodName, cx);
+ // Call lastStoredScriptable to clear stored thisObj
+ // but ignore the result as the method should use the supplied
+ // thisObj, not one from redirected call
+ ScriptRuntime.lastStoredScriptable(cx);
+ return method.call(cx, scope, thisObj, args);
+ }
+
+ public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
+ throw ScriptRuntime.typeError1("msg.not.ctor", "XMLList");
+ }
+}
+
+
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java
new file mode 100644
index 0000000..edd7525
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLName.java
@@ -0,0 +1,469 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Milen Nankov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+
+class XMLName extends Ref {
+ static final long serialVersionUID = 3832176310755686977L;
+
+ private static boolean isNCNameStartChar(int c) {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return (0xC0 <= c && c <= 0xD6)
+ || (0xD8 <= c && c <= 0xF6)
+ || (0xF8 <= c && c <= 0x2FF)
+ || (0x370 <= c && c <= 0x37D)
+ || 0x37F <= c;
+ }
+ return (0x200C <= c && c <= 0x200D)
+ || (0x2070 <= c && c <= 0x218F)
+ || (0x2C00 <= c && c <= 0x2FEF)
+ || (0x3001 <= c && c <= 0xD7FF)
+ || (0xF900 <= c && c <= 0xFDCF)
+ || (0xFDF0 <= c && c <= 0xFFFD)
+ || (0x10000 <= c && c <= 0xEFFFF);
+ }
+
+ private static boolean isNCNameChar(int c) {
+ if ((c & ~0x7F) == 0) {
+ // Optimize for ASCII and use - < . < 0..9 < A..Z < _ < a..z
+ if (c >= 'a') {
+ return c <= 'z';
+ } else if (c >= 'A') {
+ if (c <= 'Z') {
+ return true;
+ }
+ return c == '_';
+ } else if (c >= '0') {
+ return c <= '9';
+ } else {
+ return c == '-' || c == '.';
+ }
+ } else if ((c & ~0x1FFF) == 0) {
+ return isNCNameStartChar(c) || c == 0xB7
+ || (0x300 <= c && c <= 0x36F);
+ }
+ return isNCNameStartChar(c) || (0x203F <= c && c <= 0x2040);
+ }
+
+ // This means "accept" in the parsing sense
+ // See ECMA357 13.1.2.1
+ static boolean accept(Object nameObj) {
+ String name;
+ try {
+ name = ScriptRuntime.toString(nameObj);
+ } catch (EcmaError ee) {
+ if ("TypeError".equals(ee.getName())) {
+ return false;
+ }
+ throw ee;
+ }
+
+ // See http://w3.org/TR/xml-names11/#NT-NCName
+ int length = name.length();
+ if (length != 0) {
+ if (isNCNameStartChar(name.charAt(0))) {
+ for (int i = 1; i != length; ++i) {
+ if (!isNCNameChar(name.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private XmlNode.QName qname;
+ private boolean isAttributeName;
+ private boolean isDescendants;
+ private XMLObjectImpl xmlObject;
+
+ private XMLName() {
+ }
+
+ static XMLName formStar() {
+ XMLName rv = new XMLName();
+ rv.qname = XmlNode.QName.create(null, null);
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName formProperty(XmlNode.Namespace namespace, String localName) {
+ if (localName != null && localName.equals("*")) localName = null;
+ XMLName rv = new XMLName();
+ rv.qname = XmlNode.QName.create(namespace, localName);
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName formProperty(String uri, String localName) {
+ return formProperty(XmlNode.Namespace.create(uri), localName);
+ }
+
+ /** @deprecated */
+ static XMLName create(String defaultNamespaceUri, String name) {
+ if (name == null)
+ throw new IllegalArgumentException();
+
+ int l = name.length();
+ if (l != 0) {
+ char firstChar = name.charAt(0);
+ if (firstChar == '*') {
+ if (l == 1) {
+ return XMLName.formStar();
+ }
+ } else if (firstChar == '@') {
+ XMLName xmlName = XMLName.formProperty("", name.substring(1));
+ xmlName.setAttributeName();
+ return xmlName;
+ }
+ }
+
+ return XMLName.formProperty(defaultNamespaceUri, name);
+ }
+
+ static XMLName create(XmlNode.QName qname, boolean attribute, boolean descendants) {
+ XMLName rv = new XMLName();
+ rv.qname = qname;
+ rv.isAttributeName = attribute;
+ rv.isDescendants = descendants;
+ return rv;
+ }
+
+ /** @deprecated */
+ static XMLName create(XmlNode.QName qname) {
+ return create(qname, false, false);
+ }
+
+ void initXMLObject(XMLObjectImpl xmlObject) {
+ if (xmlObject == null) throw new IllegalArgumentException();
+ if (this.xmlObject != null) throw new IllegalStateException();
+ this.xmlObject = xmlObject;
+ }
+
+ String uri() {
+ if (qname.getNamespace() == null) return null;
+ return qname.getNamespace().getUri();
+ }
+
+ String localName() {
+ if (qname.getLocalName() == null) return "*";
+ return qname.getLocalName();
+ }
+
+ private void addDescendantChildren(XMLList list, XML target) {
+ XMLName xmlName = this;
+ if (target.isElement()) {
+ XML[] children = target.getChildren();
+ for (int i=0; i<children.length; i++) {
+ if (xmlName.matches( children[i] )) {
+ list.addToList( children[i] );
+ }
+ addDescendantChildren(list, children[i]);
+ }
+ }
+ }
+
+ void addMatchingAttributes(XMLList list, XML target) {
+ XMLName name = this;
+ if (target.isElement()) {
+ XML[] attributes = target.getAttributes();
+ for (int i=0; i<attributes.length; i++) {
+ if (name.matches( attributes[i]) ) {
+ list.addToList( attributes[i] );
+ }
+ }
+ }
+ }
+
+ private void addDescendantAttributes(XMLList list, XML target) {
+ if (target.isElement()) {
+ addMatchingAttributes(list, target);
+ XML[] children = target.getChildren();
+ for (int i=0; i<children.length; i++) {
+ addDescendantAttributes(list, children[i]);
+ }
+ }
+ }
+
+ XMLList matchDescendantAttributes(XMLList rv, XML target) {
+ rv.setTargets(target, null);
+ addDescendantAttributes(rv, target);
+ return rv;
+ }
+
+ XMLList matchDescendantChildren(XMLList rv, XML target) {
+ rv.setTargets(target, null);
+ addDescendantChildren(rv, target);
+ return rv;
+ }
+
+ void addDescendants(XMLList rv, XML target) {
+ XMLName xmlName = this;
+ if (xmlName.isAttributeName()) {
+ matchDescendantAttributes(rv, target);
+ } else {
+ matchDescendantChildren(rv, target);
+ }
+ }
+
+ private void addAttributes(XMLList rv, XML target) {
+ addMatchingAttributes(rv, target);
+ }
+
+ void addMatches(XMLList rv, XML target) {
+ if (isDescendants()) {
+ addDescendants(rv, target);
+ } else if (isAttributeName()) {
+ addAttributes(rv, target);
+ } else {
+ XML[] children = target.getChildren();
+ if (children != null) {
+ for (int i=0; i<children.length; i++) {
+ if (this.matches(children[i])) {
+ rv.addToList( children[i] );
+ }
+ }
+ }
+ rv.setTargets(target, this.toQname());
+ }
+ }
+
+ XMLList getMyValueOn(XML target) {
+ XMLList rv = target.newXMLList();
+ addMatches(rv, target);
+ return rv;
+ }
+
+ void setMyValueOn(XML target, Object value) {
+ // Special-case checks for undefined and null
+ if (value == null) {
+ value = "null";
+ } else if (value instanceof Undefined) {
+ value = "undefined";
+ }
+
+ XMLName xmlName = this;
+ // Get the named property
+ if (xmlName.isAttributeName()) {
+ target.setAttribute(xmlName, value);
+ } else if (xmlName.uri() == null && xmlName.localName().equals("*")) {
+ target.setChildren(value);
+ } else {
+ // Convert text into XML if needed.
+ XMLObjectImpl xmlValue = null;
+
+ if (value instanceof XMLObjectImpl) {
+ xmlValue = (XMLObjectImpl)value;
+
+ // Check for attribute type and convert to textNode
+ if (xmlValue instanceof XML) {
+ if (((XML)xmlValue).isAttribute()) {
+ xmlValue = target.makeXmlFromString(xmlName, xmlValue.toString());
+ }
+ }
+
+ if (xmlValue instanceof XMLList) {
+ for (int i = 0; i < xmlValue.length(); i++) {
+ XML xml = ((XMLList) xmlValue).item(i);
+
+ if (xml.isAttribute()) {
+ ((XMLList)xmlValue).replace(i, target.makeXmlFromString(xmlName, xml.toString()));
+ }
+ }
+ }
+ } else {
+ xmlValue = target.makeXmlFromString(xmlName, ScriptRuntime.toString(value));
+ }
+
+ XMLList matches = target.getPropertyList(xmlName);
+
+ if (matches.length() == 0) {
+ target.appendChild(xmlValue);
+ } else {
+ // Remove all other matches
+ for (int i = 1; i < matches.length(); i++) {
+ target.removeChild(matches.item(i).childIndex());
+ }
+
+ // Replace first match with new value.
+ XML firstMatch = matches.item(0);
+ target.replace(firstMatch.childIndex(), xmlValue);
+ }
+ }
+ }
+
+ public boolean has(Context cx) {
+ if (xmlObject == null) {
+ return false;
+ }
+ return xmlObject.hasXMLProperty(this);
+ }
+
+ public Object get(Context cx) {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefReadError(Undefined.instance,
+ toString());
+ }
+ return xmlObject.getXMLProperty(this);
+ }
+
+ public Object set(Context cx, Object value) {
+ if (xmlObject == null) {
+ throw ScriptRuntime.undefWriteError(Undefined.instance,
+ toString(),
+ value);
+ }
+ // Assignment to descendants causes parse error on bad reference
+ // and this should not be called
+ if (isDescendants) throw Kit.codeBug();
+ xmlObject.putXMLProperty(this, value);
+ return value;
+ }
+
+ public boolean delete(Context cx) {
+ if (xmlObject == null) {
+ return true;
+ }
+ xmlObject.deleteXMLProperty(this);
+ return !xmlObject.hasXMLProperty(this);
+ }
+
+ public String toString() {
+ //return qname.localName();
+ StringBuffer buff = new StringBuffer();
+ if (isDescendants) buff.append("..");
+ if (isAttributeName) buff.append('@');
+ if (uri() == null) {
+ buff.append('*');
+ if(localName().equals("*")) {
+ return buff.toString();
+ }
+ } else {
+ buff.append('"').append(uri()).append('"');
+ }
+ buff.append(':').append(localName());
+ return buff.toString();
+ }
+
+ final XmlNode.QName toQname() {
+ return this.qname;
+ }
+
+ final boolean matchesLocalName(String localName) {
+ return localName().equals("*") || localName().equals(localName);
+ }
+
+ final boolean matchesElement(XmlNode.QName qname) {
+ if (this.uri() == null || this.uri().equals(qname.getNamespace().getUri())) {
+ if (this.localName().equals("*") || this.localName().equals(qname.getLocalName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ final boolean matches(XML node) {
+ XmlNode.QName qname = node.getNodeQname();
+ String nodeUri = null;
+ if (qname.getNamespace() != null) {
+ nodeUri = qname.getNamespace().getUri();
+ }
+ if (isAttributeName) {
+ if (node.isAttribute()) {
+ if (this.uri() == null || this.uri().equals(nodeUri)) {
+ if (this.localName().equals("*") || this.localName().equals(qname.getLocalName())) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ // TODO Could throw exception maybe, should not call this method on attribute name with arbitrary node type
+ // unless we traverse all attributes and children habitually
+ return false;
+ }
+ } else {
+ if ( this.uri() == null || ((node.isElement()) && this.uri().equals(nodeUri)) ) {
+ if (localName().equals("*")) return true;
+ if (node.isElement()) {
+ if (localName().equals(qname.getLocalName())) return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /** @deprecated */
+ boolean isAttributeName() {
+ return isAttributeName;
+ }
+
+ // TODO Fix whether this is an attribute XMLName at construction?
+ /** @deprecated */
+ void setAttributeName() {
+// if (isAttributeName) throw new IllegalStateException();
+ isAttributeName = true;
+ }
+
+ /** @deprecated */
+ boolean isDescendants() {
+ return isDescendants;
+ }
+
+ // TODO Fix whether this is an descendant XMLName at construction?
+ /** @deprecated */
+ void setIsDescendants() {
+// if (isDescendants) throw new IllegalStateException();
+ isDescendants = true;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java
new file mode 100644
index 0000000..db918f8
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLObjectImpl.java
@@ -0,0 +1,812 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+/**
+ * This abstract class describes what all XML objects (XML, XMLList) should
+ * have in common.
+ *
+ * @see XML
+ */
+abstract class XMLObjectImpl extends XMLObject {
+ private static final Object XMLOBJECT_TAG = new Object();
+ private XMLLibImpl lib;
+ private boolean prototypeFlag;
+
+ protected XMLObjectImpl(XMLLibImpl lib, Scriptable scope,
+ XMLObject prototype)
+ {
+ initialize(lib, scope, prototype);
+ }
+
+ final void initialize(XMLLibImpl lib, Scriptable scope,
+ XMLObject prototype)
+ {
+ setParentScope(scope);
+ setPrototype(prototype);
+ prototypeFlag = (prototype == null);
+ this.lib = lib;
+ }
+
+ final boolean isPrototype() {
+ return prototypeFlag;
+ }
+
+ XMLLibImpl getLib() {
+ return lib;
+ }
+
+ final XML newXML(XmlNode node) {
+ return lib.newXML(node);
+ }
+
+ XML xmlFromNode(XmlNode node) {
+ if (node.getXml() == null) {
+ node.setXml( newXML(node) );
+ }
+ return node.getXml();
+ }
+
+ final XMLList newXMLList() {
+ return lib.newXMLList();
+ }
+
+ final XMLList newXMLListFrom(Object o) {
+ return lib.newXMLListFrom(o);
+ }
+
+ final XmlProcessor getProcessor() {
+ return lib.getProcessor();
+ }
+
+ final QName newQName(String uri, String localName, String prefix) {
+ return lib.newQName(uri, localName, prefix);
+ }
+
+ final QName newQName(XmlNode.QName name) {
+ return lib.newQName(name);
+ }
+
+ final Namespace createNamespace(XmlNode.Namespace declaration) {
+ if (declaration == null) return null;
+ return lib.createNamespaces( new XmlNode.Namespace[] { declaration } )[0];
+ }
+
+ final Namespace[] createNamespaces(XmlNode.Namespace[] declarations) {
+ return lib.createNamespaces(declarations);
+ }
+
+ //
+ // Scriptable
+ //
+
+ public final Object get(String name, Scriptable start) {
+ return super.get(name, start);
+ }
+
+ public final boolean has(String name, Scriptable start) {
+ return super.has(name, start);
+ }
+
+ public final void put(String name, Scriptable start, Object value) {
+ super.put(name, start, value);
+ }
+
+ public final void delete(String name) {
+ // TODO I am not sure about this, but this is how I found it. DPC
+ throw new IllegalArgumentException("String: [" + name + "]");
+ }
+
+ public final Scriptable getPrototype() {
+ return super.getPrototype();
+ }
+
+ public final void setPrototype(Scriptable prototype) {
+ super.setPrototype(prototype);
+ }
+
+ public final Scriptable getParentScope() {
+ return super.getParentScope();
+ }
+
+ public final void setParentScope(Scriptable parent) {
+ super.setParentScope(parent);
+ }
+
+ public final Object getDefaultValue(Class hint) {
+ return this.toString();
+ }
+
+ public final boolean hasInstance(Scriptable scriptable) {
+ return super.hasInstance(scriptable);
+ }
+
+ /**
+ * ecmaHas(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract boolean hasXMLProperty(XMLName name);
+
+ /**
+ * ecmaGet(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract Object getXMLProperty(XMLName name);
+
+ /**
+ * ecmaPut(cx, id, value) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract void putXMLProperty(XMLName name, Object value);
+
+ /**
+ * ecmaDelete(cx, id) calls this after resolving when id to XMLName
+ * and checking it is not Uint32 index.
+ */
+ abstract void deleteXMLProperty(XMLName name);
+
+ /**
+ * Test XML equality with target the target.
+ */
+ abstract boolean equivalentXml(Object target);
+
+ abstract void addMatches(XMLList rv, XMLName name);
+
+ private XMLList getMatches(XMLName name) {
+ XMLList rv = newXMLList();
+ addMatches(rv, name);
+ return rv;
+ }
+
+ abstract XML getXML();
+
+ // Methods from section 12.4.4 in the spec
+ abstract XMLList child(int index);
+ abstract XMLList child(XMLName xmlName);
+ abstract XMLList children();
+ abstract XMLList comments();
+ abstract boolean contains(Object xml);
+ abstract XMLObjectImpl copy();
+ abstract XMLList elements(XMLName xmlName);
+ abstract boolean hasOwnProperty(XMLName xmlName);
+ abstract boolean hasComplexContent();
+ abstract boolean hasSimpleContent();
+ abstract int length();
+ abstract void normalize();
+ abstract Object parent();
+ abstract XMLList processingInstructions(XMLName xmlName);
+ abstract boolean propertyIsEnumerable(Object member);
+ abstract XMLList text();
+ public abstract String toString();
+ abstract String toXMLString();
+ abstract Object valueOf();
+
+ protected abstract Object jsConstructor(Context cx, boolean inNewExpr, Object[] args);
+
+ final Object getMethod(String id) {
+ return super.get(id, this);
+ }
+
+ //
+ //
+ // Methods overriding ScriptableObject
+ //
+ //
+
+ /**
+ * XMLObject always compare with any value and equivalentValues
+ * never returns {@link Scriptable#NOT_FOUND} for them but rather
+ * calls equivalentXml(value) and wrap the result as Boolean.
+ */
+ protected final Object equivalentValues(Object value) {
+ boolean result = equivalentXml(value);
+ return result ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ //
+ //
+ // Methods overriding XMLObject
+ //
+ //
+
+ /**
+ * Implementation of ECMAScript [[Has]]
+ */
+ public final boolean ecmaHas(Context cx, Object id) {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ return has((int)index, this);
+ }
+ return hasXMLProperty(xmlName);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Get]]
+ */
+ public final Object ecmaGet(Context cx, Object id) {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ Object result = get((int)index, this);
+ if (result == Scriptable.NOT_FOUND) {
+ result = Undefined.instance;
+ }
+ return result;
+ }
+ return getXMLProperty(xmlName);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Put]]
+ */
+ public final void ecmaPut(Context cx, Object id, Object value) {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this cast
+ put((int)index, this, value);
+ return;
+ }
+ putXMLProperty(xmlName, value);
+ }
+
+ /**
+ * Implementation of ECMAScript [[Delete]].
+ */
+ public final boolean ecmaDelete(Context cx, Object id) {
+ if (cx == null) cx = Context.getCurrentContext();
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
+ if (xmlName == null) {
+ long index = ScriptRuntime.lastUint32Result(cx);
+ // XXX Fix this
+ delete((int)index);
+ return true;
+ }
+ deleteXMLProperty(xmlName);
+ return true;
+ }
+
+ // TODO Can this be made more strongly typed?
+ public Ref memberRef(Context cx, Object elem, int memberTypeFlags) {
+ boolean attribute = (memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0;
+ boolean descendants = (memberTypeFlags & Node.DESCENDANTS_FLAG) != 0;
+ if (!attribute && !descendants) {
+ // Code generation would use ecma(Get|Has|Delete|Set) for
+ // normal name identifiers so one ATTRIBUTE_FLAG
+ // or DESCENDANTS_FLAG has to be set
+ throw Kit.codeBug();
+ }
+ XmlNode.QName qname = lib.toNodeQName(cx, elem, attribute);
+ XMLName rv = XMLName.create(qname, attribute, descendants);
+ rv.initXMLObject(this);
+ return rv;
+ }
+
+ /**
+ * Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
+ */
+ public Ref memberRef(Context cx, Object namespace, Object elem, int memberTypeFlags) {
+ boolean attribute = (memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0;
+ boolean descendants = (memberTypeFlags & Node.DESCENDANTS_FLAG) != 0;
+ XMLName rv = XMLName.create(lib.toNodeQName(cx, namespace, elem), attribute, descendants);
+ rv.initXMLObject(this);
+ return rv;
+ }
+
+ public NativeWith enterWith(Scriptable scope) {
+ return new XMLWithScope(lib, scope, this);
+ }
+
+ public NativeWith enterDotQuery(Scriptable scope) {
+ XMLWithScope xws = new XMLWithScope(lib, scope, this);
+ xws.initAsDotQuery();
+ return xws;
+ }
+
+ public final Object addValues(Context cx, boolean thisIsLeft,
+ Object value) {
+ if (value instanceof XMLObject) {
+ XMLObject v1, v2;
+ if (thisIsLeft) {
+ v1 = this;
+ v2 = (XMLObject)value;
+ } else {
+ v1 = (XMLObject)value;
+ v2 = this;
+ }
+ return lib.addXMLObjects(cx, v1, v2);
+ }
+ if (value == Undefined.instance) {
+ // both "xml + undefined" and "undefined + xml" gives String(xml)
+ return ScriptRuntime.toString(this);
+ }
+
+ return super.addValues(cx, thisIsLeft, value);
+ }
+
+ //
+ //
+ // IdScriptableObject machinery
+ //
+ //
+
+ final void exportAsJSClass(boolean sealed) {
+ prototypeFlag = true;
+ exportAsJSClass(MAX_PROTOTYPE_ID, getParentScope(), sealed);
+ }
+
+// #string_id_map#
+ private final static int
+ Id_constructor = 1,
+
+ Id_addNamespace = 2,
+ Id_appendChild = 3,
+ Id_attribute = 4,
+ Id_attributes = 5,
+ Id_child = 6,
+ Id_childIndex = 7,
+ Id_children = 8,
+ Id_comments = 9,
+ Id_contains = 10,
+ Id_copy = 11,
+ Id_descendants = 12,
+ Id_elements = 13,
+ Id_inScopeNamespaces = 14,
+ Id_insertChildAfter = 15,
+ Id_insertChildBefore = 16,
+ Id_hasOwnProperty = 17,
+ Id_hasComplexContent = 18,
+ Id_hasSimpleContent = 19,
+ Id_length = 20,
+ Id_localName = 21,
+ Id_name = 22,
+ Id_namespace = 23,
+ Id_namespaceDeclarations = 24,
+ Id_nodeKind = 25,
+ Id_normalize = 26,
+ Id_parent = 27,
+ Id_prependChild = 28,
+ Id_processingInstructions = 29,
+ Id_propertyIsEnumerable = 30,
+ Id_removeNamespace = 31,
+ Id_replace = 32,
+ Id_setChildren = 33,
+ Id_setLocalName = 34,
+ Id_setName = 35,
+ Id_setNamespace = 36,
+ Id_text = 37,
+ Id_toString = 38,
+ Id_toXMLString = 39,
+ Id_valueOf = 40,
+
+ MAX_PROTOTYPE_ID = 40;
+
+ protected int findPrototypeId(String s) {
+ int id;
+// #generated# Last update: 2007-08-20 09:04:06 EDT
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 4: c=s.charAt(0);
+ if (c=='c') { X="copy";id=Id_copy; }
+ else if (c=='n') { X="name";id=Id_name; }
+ else if (c=='t') { X="text";id=Id_text; }
+ break L;
+ case 5: X="child";id=Id_child; break L;
+ case 6: c=s.charAt(0);
+ if (c=='l') { X="length";id=Id_length; }
+ else if (c=='p') { X="parent";id=Id_parent; }
+ break L;
+ case 7: c=s.charAt(0);
+ if (c=='r') { X="replace";id=Id_replace; }
+ else if (c=='s') { X="setName";id=Id_setName; }
+ else if (c=='v') { X="valueOf";id=Id_valueOf; }
+ break L;
+ case 8: switch (s.charAt(2)) {
+ case 'S': X="toString";id=Id_toString; break L;
+ case 'd': X="nodeKind";id=Id_nodeKind; break L;
+ case 'e': X="elements";id=Id_elements; break L;
+ case 'i': X="children";id=Id_children; break L;
+ case 'm': X="comments";id=Id_comments; break L;
+ case 'n': X="contains";id=Id_contains; break L;
+ } break L;
+ case 9: switch (s.charAt(2)) {
+ case 'c': X="localName";id=Id_localName; break L;
+ case 'm': X="namespace";id=Id_namespace; break L;
+ case 'r': X="normalize";id=Id_normalize; break L;
+ case 't': X="attribute";id=Id_attribute; break L;
+ } break L;
+ case 10: c=s.charAt(0);
+ if (c=='a') { X="attributes";id=Id_attributes; }
+ else if (c=='c') { X="childIndex";id=Id_childIndex; }
+ break L;
+ case 11: switch (s.charAt(0)) {
+ case 'a': X="appendChild";id=Id_appendChild; break L;
+ case 'c': X="constructor";id=Id_constructor; break L;
+ case 'd': X="descendants";id=Id_descendants; break L;
+ case 's': X="setChildren";id=Id_setChildren; break L;
+ case 't': X="toXMLString";id=Id_toXMLString; break L;
+ } break L;
+ case 12: c=s.charAt(0);
+ if (c=='a') { X="addNamespace";id=Id_addNamespace; }
+ else if (c=='p') { X="prependChild";id=Id_prependChild; }
+ else if (c=='s') {
+ c=s.charAt(3);
+ if (c=='L') { X="setLocalName";id=Id_setLocalName; }
+ else if (c=='N') { X="setNamespace";id=Id_setNamespace; }
+ }
+ break L;
+ case 14: X="hasOwnProperty";id=Id_hasOwnProperty; break L;
+ case 15: X="removeNamespace";id=Id_removeNamespace; break L;
+ case 16: c=s.charAt(0);
+ if (c=='h') { X="hasSimpleContent";id=Id_hasSimpleContent; }
+ else if (c=='i') { X="insertChildAfter";id=Id_insertChildAfter; }
+ break L;
+ case 17: c=s.charAt(3);
+ if (c=='C') { X="hasComplexContent";id=Id_hasComplexContent; }
+ else if (c=='c') { X="inScopeNamespaces";id=Id_inScopeNamespaces; }
+ else if (c=='e') { X="insertChildBefore";id=Id_insertChildBefore; }
+ break L;
+ case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
+ case 21: X="namespaceDeclarations";id=Id_namespaceDeclarations; break L;
+ case 22: X="processingInstructions";id=Id_processingInstructions; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ break L0;
+ }
+// #/generated#
+ return id;
+ }
+// #/string_id_map#
+
+ protected void initPrototypeId(int id) {
+ String s;
+ int arity;
+ switch (id) {
+ case Id_constructor: {
+ IdFunctionObject ctor;
+ if (this instanceof XML) {
+ ctor = new XMLCtor((XML)this, XMLOBJECT_TAG, id, 1);
+ } else {
+ ctor = new IdFunctionObject(this, XMLOBJECT_TAG, id, 1);
+ }
+ initPrototypeConstructor(ctor);
+ return;
+ }
+
+ case Id_addNamespace: arity=1; s="addNamespace"; break;
+ case Id_appendChild: arity=1; s="appendChild"; break;
+ case Id_attribute: arity=1; s="attribute"; break;
+ case Id_attributes: arity=0; s="attributes"; break;
+ case Id_child: arity=1; s="child"; break;
+ case Id_childIndex: arity=0; s="childIndex"; break;
+ case Id_children: arity=0; s="children"; break;
+ case Id_comments: arity=0; s="comments"; break;
+ case Id_contains: arity=1; s="contains"; break;
+ case Id_copy: arity=0; s="copy"; break;
+ case Id_descendants: arity=1; s="descendants"; break;
+ case Id_elements: arity=1; s="elements"; break;
+ case Id_hasComplexContent: arity=0; s="hasComplexContent"; break;
+ case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
+ case Id_hasSimpleContent: arity=0; s="hasSimpleContent"; break;
+ case Id_inScopeNamespaces: arity=0; s="inScopeNamespaces"; break;
+ case Id_insertChildAfter: arity=2; s="insertChildAfter"; break;
+ case Id_insertChildBefore: arity=2; s="insertChildBefore"; break;
+ case Id_length: arity=0; s="length"; break;
+ case Id_localName: arity=0; s="localName"; break;
+ case Id_name: arity=0; s="name"; break;
+ case Id_namespace: arity=1; s="namespace"; break;
+ case Id_namespaceDeclarations:
+ arity=0; s="namespaceDeclarations"; break;
+ case Id_nodeKind: arity=0; s="nodeKind"; break;
+ case Id_normalize: arity=0; s="normalize"; break;
+ case Id_parent: arity=0; s="parent"; break;
+ case Id_prependChild: arity=1; s="prependChild"; break;
+ case Id_processingInstructions:
+ arity=1; s="processingInstructions"; break;
+ case Id_propertyIsEnumerable:
+ arity=1; s="propertyIsEnumerable"; break;
+ case Id_removeNamespace: arity=1; s="removeNamespace"; break;
+ case Id_replace: arity=2; s="replace"; break;
+ case Id_setChildren: arity=1; s="setChildren"; break;
+ case Id_setLocalName: arity=1; s="setLocalName"; break;
+ case Id_setName: arity=1; s="setName"; break;
+ case Id_setNamespace: arity=1; s="setNamespace"; break;
+ case Id_text: arity=0; s="text"; break;
+ case Id_toString: arity=0; s="toString"; break;
+ case Id_toXMLString: arity=1; s="toXMLString"; break;
+ case Id_valueOf: arity=0; s="valueOf"; break;
+
+ default: throw new IllegalArgumentException(String.valueOf(id));
+ }
+ initPrototypeMethod(XMLOBJECT_TAG, id, s, arity);
+ }
+
+ private Object[] toObjectArray(Object[] typed) {
+ Object[] rv = new Object[typed.length];
+ for (int i=0; i<rv.length; i++) {
+ rv[i] = typed[i];
+ }
+ return rv;
+ }
+
+ private void xmlMethodNotFound(Object object, String name) {
+ throw ScriptRuntime.notFunctionError(object, name);
+ }
+
+ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
+ if (!f.hasTag(XMLOBJECT_TAG)) {
+ return super.execIdCall(f, cx, scope, thisObj, args);
+ }
+ int id = f.methodId();
+ if (id == Id_constructor) {
+ return jsConstructor(cx, thisObj == null, args);
+ }
+
+ // All (XML|XMLList).prototype methods require thisObj to be XML
+ if (!(thisObj instanceof XMLObjectImpl))
+ throw incompatibleCallError(f);
+ XMLObjectImpl realThis = (XMLObjectImpl)thisObj;
+
+ XML xml = realThis.getXML();
+ switch (id) {
+ case Id_appendChild: {
+ if (xml == null) xmlMethodNotFound(realThis, "appendChild");
+ return xml.appendChild(arg(args, 0));
+ }
+ case Id_addNamespace: {
+ if (xml == null) xmlMethodNotFound(realThis, "addNamespace");
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ return xml.addNamespace(ns);
+ }
+ case Id_childIndex: {
+ if (xml == null) xmlMethodNotFound(realThis, "childIndex");
+ return ScriptRuntime.wrapInt(xml.childIndex());
+ }
+ case Id_inScopeNamespaces: {
+ if (xml == null) xmlMethodNotFound(realThis, "inScopeNamespaces");
+ return cx.newArray(scope, toObjectArray(xml.inScopeNamespaces()));
+ }
+ case Id_insertChildAfter: {
+ if (xml == null) xmlMethodNotFound(realThis, "insertChildAfter");
+ Object arg0 = arg(args, 0);
+ if (arg0 == null || arg0 instanceof XML) {
+ return xml.insertChildAfter((XML)arg0, arg(args, 1));
+ }
+ return Undefined.instance;
+ }
+ case Id_insertChildBefore: {
+ if (xml == null) xmlMethodNotFound(realThis, "insertChildBefore");
+ Object arg0 = arg(args, 0);
+ if (arg0 == null || arg0 instanceof XML) {
+ return xml.insertChildBefore((XML)arg0, arg(args, 1));
+ }
+ return Undefined.instance;
+ }
+ case Id_localName: {
+ if (xml == null) xmlMethodNotFound(realThis, "localName");
+ return xml.localName();
+ }
+ case Id_name: {
+ if (xml == null) xmlMethodNotFound(realThis, "name");
+ return xml.name();
+ }
+ case Id_namespace: {
+ if (xml == null) xmlMethodNotFound(realThis, "namespace");
+ String prefix = (args.length > 0) ? ScriptRuntime.toString(args[0]) : null;
+ Namespace rv = xml.namespace(prefix);
+ if (rv == null) {
+ return Undefined.instance;
+ } else {
+ return rv;
+ }
+ }
+ case Id_namespaceDeclarations: {
+ if (xml == null) xmlMethodNotFound(realThis, "namespaceDeclarations");
+ Namespace[] array = xml.namespaceDeclarations();
+ return cx.newArray(scope, toObjectArray(array));
+ }
+ case Id_nodeKind: {
+ if (xml == null) xmlMethodNotFound(realThis, "nodeKind");
+ return xml.nodeKind();
+ }
+ case Id_prependChild: {
+ if (xml == null) xmlMethodNotFound(realThis, "prependChild");
+ return xml.prependChild(arg(args, 0));
+ }
+ case Id_removeNamespace: {
+ if (xml == null) xmlMethodNotFound(realThis, "removeNamespace");
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ return xml.removeNamespace(ns);
+ }
+ case Id_replace: {
+ if (xml == null) xmlMethodNotFound(realThis, "replace");
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
+ Object arg1 = arg(args, 1);
+ if (xmlName == null) {
+ // I refuse to believe that this number will exceed 2^31
+ int index = (int)ScriptRuntime.lastUint32Result(cx);
+ return xml.replace(index, arg1);
+ } else {
+ return xml.replace(xmlName, arg1);
+ }
+ }
+ case Id_setChildren: {
+ if (xml == null) xmlMethodNotFound(realThis, "setChildren");
+ return xml.setChildren(arg(args, 0));
+ }
+ case Id_setLocalName: {
+ if (xml == null) xmlMethodNotFound(realThis, "setLocalName");
+ String localName;
+ Object arg = arg(args, 0);
+ if (arg instanceof QName) {
+ localName = ((QName)arg).localName();
+ } else {
+ localName = ScriptRuntime.toString(arg);
+ }
+ xml.setLocalName(localName);
+ return Undefined.instance;
+ }
+ case Id_setName: {
+ if (xml == null) xmlMethodNotFound(realThis, "setName");
+ Object arg = (args.length != 0) ? args[0] : Undefined.instance;
+ QName qname = lib.constructQName(cx, arg);
+ xml.setName(qname);
+ return Undefined.instance;
+ }
+ case Id_setNamespace: {
+ if (xml == null) xmlMethodNotFound(realThis, "setNamespace");
+ Namespace ns = lib.castToNamespace(cx, arg(args, 0));
+ xml.setNamespace(ns);
+ return Undefined.instance;
+ }
+
+ case Id_attribute: {
+ XMLName xmlName = XMLName.create( lib.toNodeQName(cx, arg(args, 0), true), true, false );
+ return realThis.getMatches(xmlName);
+ }
+ case Id_attributes:
+ return realThis.getMatches(XMLName.create(XmlNode.QName.create(null, null), true, false));
+ case Id_child: {
+ XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
+ if (xmlName == null) {
+ // Two billion or so is a fine upper limit, so we cast to int
+ int index = (int)ScriptRuntime.lastUint32Result(cx);
+ return realThis.child(index);
+ } else {
+ return realThis.child(xmlName);
+ }
+ }
+ case Id_children:
+ return realThis.children();
+ case Id_comments:
+ return realThis.comments();
+ case Id_contains:
+ return ScriptRuntime.wrapBoolean(
+ realThis.contains(arg(args, 0)));
+ case Id_copy:
+ return realThis.copy();
+ case Id_descendants: {
+ XmlNode.QName qname = (args.length == 0) ? XmlNode.QName.create(null, null) : lib.toNodeQName(cx, args[0], false);
+ return realThis.getMatches( XMLName.create(qname, false, true) );
+ }
+ case Id_elements: {
+ XMLName xmlName = (args.length == 0)
+ ? XMLName.formStar()
+ : lib.toXMLName(cx, args[0]);
+ return realThis.elements(xmlName);
+ }
+ case Id_hasOwnProperty: {
+ XMLName xmlName = lib.toXMLName(cx, arg(args, 0));
+ return ScriptRuntime.wrapBoolean(
+ realThis.hasOwnProperty(xmlName));
+ }
+ case Id_hasComplexContent:
+ return ScriptRuntime.wrapBoolean(realThis.hasComplexContent());
+ case Id_hasSimpleContent:
+ return ScriptRuntime.wrapBoolean(realThis.hasSimpleContent());
+ case Id_length:
+ return ScriptRuntime.wrapInt(realThis.length());
+ case Id_normalize:
+ realThis.normalize();
+ return Undefined.instance;
+ case Id_parent:
+ return realThis.parent();
+ case Id_processingInstructions: {
+ XMLName xmlName = (args.length > 0)
+ ? lib.toXMLName(cx, args[0])
+ : XMLName.formStar();
+ return realThis.processingInstructions(xmlName);
+ }
+ case Id_propertyIsEnumerable: {
+ return ScriptRuntime.wrapBoolean(
+ realThis.propertyIsEnumerable(arg(args, 0)));
+ }
+ case Id_text:
+ return realThis.text();
+ case Id_toString:
+ return realThis.toString();
+ case Id_toXMLString: {
+ return realThis.toXMLString();
+ }
+ case Id_valueOf:
+ return realThis.valueOf();
+ }
+ throw new IllegalArgumentException(String.valueOf(id));
+ }
+
+ private static Object arg(Object[] args, int i) {
+ return (i < args.length) ? args[i] : Undefined.instance;
+ }
+
+ final XML newTextElementXML(XmlNode reference, XmlNode.QName qname, String value) {
+ return lib.newTextElementXML(reference, qname, value);
+ }
+
+ /** @deprecated Hopefully this can be replaced with ecmaToXml below. */
+ final XML newXMLFromJs(Object inputObject) {
+ return lib.newXMLFromJs(inputObject);
+ }
+
+ final XML ecmaToXml(Object object) {
+ return lib.ecmaToXml(object);
+ }
+
+ final String ecmaEscapeAttributeValue(String s) {
+ // TODO Check this
+ String quoted = lib.escapeAttributeValue(s);
+ return quoted.substring(1, quoted.length() - 1);
+ }
+
+ final XML createEmptyXML() {
+ return newXML(XmlNode.createEmpty(getProcessor()));
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java
new file mode 100644
index 0000000..fbeb45e
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XMLWithScope.java
@@ -0,0 +1,125 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Ethan Hugg
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.xml.*;
+
+final class XMLWithScope extends NativeWith
+{
+ private static final long serialVersionUID = -696429282095170887L;
+
+ private XMLLibImpl lib;
+ private int _currIndex;
+ private XMLList _xmlList;
+ private XMLObject _dqPrototype;
+
+ XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype)
+ {
+ super(parent, prototype);
+ this.lib = lib;
+ }
+
+ void initAsDotQuery()
+ {
+ XMLObject prototype = (XMLObject)getPrototype();
+ // XMLWithScope also handles the .(xxx) DotQuery for XML
+ // basically DotQuery is a for/in/with statement and in
+ // the following 3 statements we setup to signal it's
+ // DotQuery,
+ // the index and the object being looped over. The
+ // xws.setPrototype is the scope of the object which is
+ // is a element of the lhs (XMLList).
+ _currIndex = 0;
+ _dqPrototype = prototype;
+ if (prototype instanceof XMLList) {
+ XMLList xl = (XMLList)prototype;
+ if (xl.length() > 0) {
+ setPrototype((Scriptable)(xl.get(0, null)));
+ }
+ }
+ // Always return the outer-most type of XML lValue of
+ // XML to left of dotQuery.
+ _xmlList = lib.newXMLList();
+ }
+
+ protected Object updateDotQuery(boolean value)
+ {
+ // Return null to continue looping
+
+ XMLObject seed = _dqPrototype;
+ XMLList xmlL = _xmlList;
+
+ if (seed instanceof XMLList) {
+ // We're a list so keep testing each element of the list if the
+ // result on the top of stack is true then that element is added
+ // to our result list. If false, we try the next element.
+ XMLList orgXmlL = (XMLList)seed;
+
+ int idx = _currIndex;
+
+ if (value) {
+ xmlL.addToList(orgXmlL.get(idx, null));
+ }
+
+ // More elements to test?
+ if (++idx < orgXmlL.length()) {
+ // Yes, set our new index, get the next element and
+ // reset the expression to run with this object as
+ // the WITH selector.
+ _currIndex = idx;
+ setPrototype((Scriptable)(orgXmlL.get(idx, null)));
+
+ // continue looping
+ return null;
+ }
+ } else {
+ // If we're not a XMLList then there's no looping
+ // just return DQPrototype if the result is true.
+ if (value) {
+ xmlL.addToList(seed);
+ }
+ }
+
+ return xmlL;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlNode.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlNode.java
new file mode 100644
index 0000000..06955d0
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlNode.java
@@ -0,0 +1,869 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino DOM-only E4X implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * David P. Caldwell.
+ * Portions created by David P. Caldwell are Copyright (C)
+ * 2007 David P. Caldwell. All Rights Reserved.
+ *
+ *
+ * Contributor(s):
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import java.util.*;
+
+import org.w3c.dom.*;
+
+import org.mozilla.javascript.*;
+
+// Disambiguate with org.mozilla.javascript
+import org.w3c.dom.Node;
+
+class XmlNode {
+ private static final String XML_NAMESPACES_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
+
+ private static final String USER_DATA_XMLNODE_KEY = XmlNode.class.getName();
+
+ private static final boolean DOM_LEVEL_3 = true;
+
+ private static XmlNode getUserData(Node node) {
+ if (DOM_LEVEL_3) {
+ return (XmlNode)node.getUserData(USER_DATA_XMLNODE_KEY);
+ }
+ return null;
+ }
+
+ private static void setUserData(Node node, XmlNode wrap) {
+ if (DOM_LEVEL_3) {
+ node.setUserData(USER_DATA_XMLNODE_KEY, wrap, wrap.events);
+ }
+ }
+
+ private static XmlNode createImpl(Node node) {
+ if (node instanceof Document) throw new IllegalArgumentException();
+ XmlNode rv = null;
+ if (getUserData(node) == null) {
+ rv = new XmlNode();
+ rv.dom = node;
+ setUserData(node, rv);
+ } else {
+ rv = getUserData(node);
+ }
+ return rv;
+ }
+
+ static XmlNode newElementWithText(XmlProcessor processor, XmlNode reference, XmlNode.QName qname, String value) {
+ if (reference instanceof org.w3c.dom.Document) throw new IllegalArgumentException("Cannot use Document node as reference");
+ Document document = null;
+ if (reference != null) {
+ document = reference.dom.getOwnerDocument();
+ } else {
+ document = processor.newDocument();
+ }
+ Node referenceDom = (reference != null) ? reference.dom : null;
+ Element e = document.createElementNS(qname.getUri(), qname.qualify(referenceDom));
+ if (value != null) {
+ e.appendChild(document.createTextNode(value));
+ }
+ return XmlNode.createImpl(e);
+ }
+
+ static XmlNode createText(XmlProcessor processor, String value) {
+ return createImpl( processor.newDocument().createTextNode(value) );
+ }
+
+ static XmlNode createElementFromNode(Node node) {
+ if (node instanceof Document)
+ node = ((Document) node).getDocumentElement();
+ return createImpl(node);
+ }
+
+ static XmlNode createElement(XmlProcessor processor, String namespaceUri, String xml) throws org.xml.sax.SAXException {
+ return createImpl( processor.toXml(namespaceUri, xml) );
+ }
+
+ static XmlNode createEmpty(XmlProcessor processor) {
+ return createText(processor, "");
+ }
+
+ private static XmlNode copy(XmlNode other) {
+ return createImpl( other.dom.cloneNode(true) );
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ private UserDataHandler events = new UserDataHandler() {
+ public void handle(short operation, String key, Object data, Node src, Node dest) {
+ }
+ };
+
+ private Node dom;
+
+ private XML xml;
+
+ private XmlNode() {
+ }
+
+ String debug() {
+ XmlProcessor raw = new XmlProcessor();
+ raw.setIgnoreComments(false);
+ raw.setIgnoreProcessingInstructions(false);
+ raw.setIgnoreWhitespace(false);
+ raw.setPrettyPrinting(false);
+ return raw.ecmaToXmlString(this.dom);
+ }
+
+ public String toString() {
+ return "XmlNode: type=" + dom.getNodeType() + " dom=" + dom.toString();
+ }
+
+ XML getXml() {
+ return xml;
+ }
+
+ void setXml(XML xml) {
+ this.xml = xml;
+ }
+
+ int getChildCount() {
+ return this.dom.getChildNodes().getLength();
+ }
+
+ XmlNode parent() {
+ Node domParent = dom.getParentNode();
+ if (domParent instanceof Document) return null;
+ if (domParent == null) return null;
+ return createImpl(domParent);
+ }
+
+ int getChildIndex() {
+ if (this.isAttributeType()) return -1;
+ if (parent() == null) return -1;
+ org.w3c.dom.NodeList siblings = this.dom.getParentNode().getChildNodes();
+ for (int i=0; i<siblings.getLength(); i++) {
+ if (siblings.item(i) == dom) {
+ return i;
+ }
+ }
+ // Either the parent is -1 or one of the this node's parent's children is this node.
+ throw new RuntimeException("Unreachable.");
+ }
+
+ void removeChild(int index) {
+ this.dom.removeChild( this.dom.getChildNodes().item(index) );
+ }
+
+ String toXmlString(XmlProcessor processor) {
+ return processor.ecmaToXmlString(this.dom);
+ }
+
+ String ecmaValue() {
+ // TODO See ECMA 357 Section 9.1
+ if (isTextType()) {
+ return ((org.w3c.dom.Text)dom).getData();
+ } else if (isAttributeType()) {
+ return ((org.w3c.dom.Attr)dom).getValue();
+ } else if (isProcessingInstructionType()) {
+ return ((org.w3c.dom.ProcessingInstruction)dom).getData();
+ } else if (isCommentType()) {
+ return ((org.w3c.dom.Comment)dom).getNodeValue();
+ } else if (isElementType()) {
+ throw new RuntimeException("Unimplemented ecmaValue() for elements.");
+ } else {
+ throw new RuntimeException("Unimplemented for node " + dom);
+ }
+ }
+
+ void deleteMe() {
+ if (dom instanceof Attr) {
+ Attr attr = (Attr)this.dom;
+ attr.getOwnerElement().getAttributes().removeNamedItemNS(attr.getNamespaceURI(), attr.getLocalName());
+ } else {
+ if (this.dom.getParentNode() != null) {
+ this.dom.getParentNode().removeChild(this.dom);
+ } else {
+ // This case can be exercised at least when executing the regression
+ // tests under https://bugzilla.mozilla.org/show_bug.cgi?id=354145
+ }
+ }
+ }
+
+ void normalize() {
+ this.dom.normalize();
+ }
+
+ void insertChildAt(int index, XmlNode node) {
+ Node parent = this.dom;
+ Node child = parent.getOwnerDocument().importNode( node.dom, true );
+ if (parent.getChildNodes().getLength() < index) {
+ // TODO Check ECMA for what happens here
+ throw new IllegalArgumentException("index=" + index + " length=" + parent.getChildNodes().getLength());
+ }
+ if (parent.getChildNodes().getLength() == index) {
+ parent.appendChild(child);
+ } else {
+ parent.insertBefore(child, parent.getChildNodes().item(index));
+ }
+ }
+
+ void insertChildrenAt(int index, XmlNode[] nodes) {
+ for (int i=0; i<nodes.length; i++) {
+ insertChildAt(index+i, nodes[i]);
+ }
+ }
+
+ XmlNode getChild(int index) {
+ Node child = dom.getChildNodes().item(index);
+ return createImpl(child);
+ }
+
+ // Helper method for XML.hasSimpleContent()
+ boolean hasChildElement() {
+ org.w3c.dom.NodeList nodes = this.dom.getChildNodes();
+ for (int i=0; i<nodes.getLength(); i++) {
+ if (nodes.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) return true;
+ }
+ return false;
+ }
+
+ boolean isSameNode(XmlNode other) {
+ // TODO May need to be changed if we allow XmlNode to refer to several Node objects
+ return this.dom == other.dom;
+ }
+
+ private String toUri(String ns) {
+ return (ns == null) ? "" : ns;
+ }
+
+ private void addNamespaces(Namespaces rv, Element element) {
+ if (element == null) throw new RuntimeException("element must not be null");
+ String myDefaultNamespace = toUri(element.lookupNamespaceURI(null));
+ String parentDefaultNamespace = "";
+ if (element.getParentNode() != null) {
+ parentDefaultNamespace = toUri(element.getParentNode().lookupNamespaceURI(null));
+ }
+ if (!myDefaultNamespace.equals(parentDefaultNamespace) || !(element.getParentNode() instanceof Element) ) {
+ rv.declare(Namespace.create("", myDefaultNamespace));
+ }
+ NamedNodeMap attributes = element.getAttributes();
+ for (int i=0; i<attributes.getLength(); i++) {
+ Attr attr = (Attr)attributes.item(i);
+ if (attr.getPrefix() != null && attr.getPrefix().equals("xmlns")) {
+ rv.declare(Namespace.create(attr.getLocalName(), attr.getValue()));
+ }
+ }
+ }
+
+ private Namespaces getAllNamespaces() {
+ Namespaces rv = new Namespaces();
+
+ Node target = this.dom;
+ if (target instanceof Attr) {
+ target = ((Attr)target).getOwnerElement();
+ }
+ while(target != null) {
+ if (target instanceof Element) {
+ addNamespaces(rv, (Element)target);
+ }
+ target = target.getParentNode();
+ }
+ // Fallback in case no namespace was declared
+ rv.declare(Namespace.create("", ""));
+ return rv;
+ }
+
+ Namespace[] getInScopeNamespaces() {
+ Namespaces rv = getAllNamespaces();
+ return rv.getNamespaces();
+ }
+
+ Namespace[] getNamespaceDeclarations() {
+ // ECMA357 13.4.4.24
+ if (this.dom instanceof Element) {
+ Namespaces rv = new Namespaces();
+ addNamespaces( rv, (Element)this.dom );
+ return rv.getNamespaces();
+ } else {
+ return new Namespace[0];
+ }
+ }
+
+ Namespace getNamespaceDeclaration(String prefix) {
+ if (prefix.equals("") && dom instanceof Attr) {
+ // Default namespaces do not apply to attributes; see XML Namespaces section 5.2
+ return Namespace.create("", "");
+ }
+ Namespaces rv = getAllNamespaces();
+ return rv.getNamespace(prefix);
+ }
+
+ Namespace getNamespaceDeclaration() {
+ if (dom.getPrefix() == null) return getNamespaceDeclaration("");
+ return getNamespaceDeclaration(dom.getPrefix());
+ }
+
+ private static class Namespaces {
+ private HashMap map = new HashMap();
+ private HashMap uriToPrefix = new HashMap();
+
+ Namespaces() {
+ }
+
+ void declare(Namespace n) {
+ if (map.get(n.prefix) == null) {
+ map.put(n.prefix, n.uri);
+ }
+ // TODO I think this is analogous to the other way, but have not really thought it through ... should local scope
+ // matter more than outer scope?
+ if (uriToPrefix.get(n.uri) == null) {
+ uriToPrefix.put(n.uri, n.prefix);
+ }
+ }
+
+ Namespace getNamespaceByUri(String uri) {
+ if (uriToPrefix.get(uri) == null) return null;
+ return Namespace.create(uri, (String)uriToPrefix.get(uri));
+ }
+
+ Namespace getNamespace(String prefix) {
+ if (map.get(prefix) == null) return null;
+ return Namespace.create(prefix, (String)map.get(prefix));
+ }
+
+ Namespace[] getNamespaces() {
+ Iterator i = map.keySet().iterator();
+ ArrayList rv = new ArrayList();
+ while(i.hasNext()) {
+ String prefix = (String)i.next();
+ String uri = (String)map.get(prefix);
+ Namespace n = Namespace.create(prefix, uri);
+ if (!n.isEmpty()) {
+ rv.add( n );
+ }
+ }
+ return (Namespace[])rv.toArray(new Namespace[0]);
+ }
+ }
+
+ final XmlNode copy() {
+ return copy( this );
+ }
+
+ // Returns whether this node is capable of being a parent
+ final boolean isParentType() {
+ return isElementType();
+ }
+
+ final boolean isTextType() {
+ return dom.getNodeType() == Node.TEXT_NODE || dom.getNodeType() == Node.CDATA_SECTION_NODE;
+ }
+
+ final boolean isAttributeType() {
+ return dom.getNodeType() == Node.ATTRIBUTE_NODE;
+ }
+
+ final boolean isProcessingInstructionType() {
+ return dom.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE;
+ }
+
+ final boolean isCommentType() {
+ return dom.getNodeType() == Node.COMMENT_NODE;
+ }
+
+ final boolean isElementType() {
+ return dom.getNodeType() == Node.ELEMENT_NODE;
+ }
+
+ final void renameNode(QName qname) {
+ this.dom = dom.getOwnerDocument().renameNode(dom, qname.getUri(), qname.qualify(dom));
+ }
+
+ void invalidateNamespacePrefix() {
+ if (!(dom instanceof Element)) throw new IllegalStateException();
+ String prefix = this.dom.getPrefix();
+ QName after = QName.create(this.dom.getNamespaceURI(), this.dom.getLocalName(), null);
+ renameNode(after);
+ NamedNodeMap attrs = this.dom.getAttributes();
+ for (int i=0; i<attrs.getLength(); i++) {
+ if (attrs.item(i).getPrefix().equals(prefix)) {
+ createImpl( attrs.item(i) ).renameNode( QName.create(attrs.item(i).getNamespaceURI(), attrs.item(i).getLocalName(), null) );
+ }
+ }
+ }
+
+ private void declareNamespace(Element e, String prefix, String uri) {
+ if (prefix.length() > 0) {
+ e.setAttributeNS(XML_NAMESPACES_NAMESPACE_URI, "xmlns:" + prefix, uri);
+ } else {
+ e.setAttribute("xmlns", uri);
+ }
+ }
+
+ void declareNamespace(String prefix, String uri) {
+ if (!(dom instanceof Element)) throw new IllegalStateException();
+ if (dom.lookupNamespaceURI(uri) != null && dom.lookupNamespaceURI(uri).equals(prefix)) {
+ // do nothing
+ } else {
+ Element e = (Element)dom;
+ declareNamespace(e, prefix, uri);
+ }
+ }
+
+ private Namespace getDefaultNamespace() {
+ String prefix = "";
+ String uri = (dom.lookupNamespaceURI(null) == null) ? "" : dom.lookupNamespaceURI(null);
+ return Namespace.create(prefix, uri);
+ }
+
+ private String getExistingPrefixFor(Namespace namespace) {
+ if (getDefaultNamespace().getUri().equals(namespace.getUri())) {
+ return "";
+ }
+ return dom.lookupPrefix(namespace.getUri());
+ }
+
+ private Namespace getNodeNamespace() {
+ String uri = dom.getNamespaceURI();
+ String prefix = dom.getPrefix();
+ if (uri == null) uri = "";
+ if (prefix == null) prefix = "";
+ return Namespace.create(prefix, uri);
+ }
+
+ Namespace getNamespace() {
+ return getNodeNamespace();
+ }
+
+ void removeNamespace(Namespace namespace) {
+ Namespace current = getNodeNamespace();
+
+ // Do not remove in-use namespace
+ if (namespace.is(current)) return;
+ NamedNodeMap attrs = this.dom.getAttributes();
+ for (int i=0; i<attrs.getLength(); i++) {
+ XmlNode attr = XmlNode.createImpl(attrs.item(i));
+ if (namespace.is(attr.getNodeNamespace())) return;
+ }
+
+ // TODO I must confess I am not sure I understand the spec fully. See ECMA357 13.4.4.31
+ String existingPrefix = getExistingPrefixFor(namespace);
+ if (existingPrefix != null) {
+ if (namespace.isUnspecifiedPrefix()) {
+ // we should remove any namespace with this URI from scope; we do this by declaring a namespace with the same
+ // prefix as the existing prefix and setting its URI to the default namespace
+ declareNamespace(existingPrefix, getDefaultNamespace().getUri());
+ } else {
+ if (existingPrefix.equals(namespace.getPrefix())) {
+ declareNamespace(existingPrefix, getDefaultNamespace().getUri());
+ }
+ }
+ } else {
+ // the argument namespace is not declared in this scope, so do nothing.
+ }
+ }
+
+ private void setProcessingInstructionName(String localName) {
+ org.w3c.dom.ProcessingInstruction pi = (ProcessingInstruction)this.dom;
+ // We cannot set the node name; Document.renameNode() only supports elements and attributes. So we replace it
+ pi.getParentNode().replaceChild(
+ pi,
+ pi.getOwnerDocument().createProcessingInstruction(localName, pi.getData())
+ );
+ }
+
+ final void setLocalName(String localName) {
+ if (dom instanceof ProcessingInstruction) {
+ setProcessingInstructionName(localName);
+ } else {
+ String prefix = dom.getPrefix();
+ if (prefix == null) prefix = "";
+ this.dom = dom.getOwnerDocument().renameNode(dom, dom.getNamespaceURI(), QName.qualify(prefix, localName));
+ }
+ }
+
+ final QName getQname() {
+ String uri = (dom.getNamespaceURI()) == null ? "" : dom.getNamespaceURI();
+ String prefix = (dom.getPrefix() == null) ? "" : dom.getPrefix();
+ return QName.create( uri, dom.getLocalName(), prefix );
+ }
+
+ void addMatchingChildren(XMLList result, XmlNode.Filter filter) {
+ Node node = this.dom;
+ NodeList children = node.getChildNodes();
+ for(int i=0; i<children.getLength(); i++) {
+ Node childnode = children.item(i);
+ XmlNode child = XmlNode.createImpl(childnode);
+ if (filter.accept(childnode)) {
+ result.addToList(child);
+ }
+ }
+ }
+
+ XmlNode[] getMatchingChildren(Filter filter) {
+ ArrayList rv = new ArrayList();
+ NodeList nodes = this.dom.getChildNodes();
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ if (filter.accept(node)) {
+ rv.add( createImpl(node) );
+ }
+ }
+ return (XmlNode[])rv.toArray(new XmlNode[0]);
+ }
+
+ XmlNode[] getAttributes() {
+ NamedNodeMap attrs = this.dom.getAttributes();
+ // TODO Or could make callers handle null?
+ if (attrs == null) throw new IllegalStateException("Must be element.");
+ XmlNode[] rv = new XmlNode[attrs.getLength()];
+ for (int i=0; i<attrs.getLength(); i++) {
+ rv[i] = createImpl( attrs.item(i) );
+ }
+ return rv;
+ }
+
+ String getAttributeValue() {
+ return ((Attr)dom).getValue();
+ }
+
+ void setAttribute(QName name, String value) {
+ if (!(dom instanceof Element)) throw new IllegalStateException("Can only set attribute on elements.");
+ name.setAttribute( (Element)dom, value );
+ }
+
+ void replaceWith(XmlNode other) {
+ Node replacement = other.dom;
+ if (replacement.getOwnerDocument() != this.dom.getOwnerDocument()) {
+ replacement = this.dom.getOwnerDocument().importNode(replacement, true);
+ }
+ this.dom.getParentNode().replaceChild(replacement, this.dom);
+ }
+
+ String ecmaToXMLString(XmlProcessor processor) {
+ if (this.isElementType()) {
+ Element copy = (Element)this.dom.cloneNode(true);
+ Namespace[] inScope = this.getInScopeNamespaces();
+ for (int i=0; i<inScope.length; i++) {
+ declareNamespace(copy, inScope[i].getPrefix(), inScope[i].getUri());
+ }
+ return processor.ecmaToXmlString(copy);
+ } else {
+ return processor.ecmaToXmlString(dom);
+ }
+ }
+
+ static class Namespace {
+ static Namespace create(String prefix, String uri) {
+ if (prefix == null) throw new IllegalArgumentException("Empty string represents default namespace prefix");
+ if (uri == null) throw new IllegalArgumentException("Namespace may not lack a URI");
+ Namespace rv = new Namespace();
+ rv.prefix = prefix;
+ rv.uri = uri;
+ return rv;
+ }
+
+ static Namespace create(String uri) {
+ Namespace rv = new Namespace();
+ rv.uri = uri;
+ return rv;
+ }
+
+ static final Namespace GLOBAL = create("", "");
+
+ private String prefix;
+ private String uri;
+
+ private Namespace() {
+ }
+
+ public String toString() {
+ if (prefix == null) return "XmlNode.Namespace [" + uri + "]";
+ return "XmlNode.Namespace [" + prefix + "{" + uri + "}]";
+ }
+
+ boolean isUnspecifiedPrefix() {
+ return prefix == null;
+ }
+
+ boolean is(Namespace other) {
+ return this.prefix != null && other.prefix != null && this.prefix.equals(other.prefix) && this.uri.equals(other.uri);
+ }
+
+ boolean isEmpty() {
+ return prefix != null && prefix.equals("") && uri.equals("");
+ }
+
+ boolean isDefault() {
+ return prefix != null && prefix.equals("");
+ }
+
+ boolean isGlobal() {
+ return uri != null && uri.equals("");
+ }
+
+ // Called by QName
+ // TODO Move functionality from QName lookupPrefix to here
+ private void setPrefix(String prefix) {
+ if (prefix == null) throw new IllegalArgumentException();
+ this.prefix = prefix;
+ }
+
+ String getPrefix() {
+ return prefix;
+ }
+
+ String getUri() {
+ return uri;
+ }
+ }
+
+ // TODO Where is this class used? No longer using it in QName implementation
+ static class QName {
+ static QName create(Namespace namespace, String localName) {
+ // A null namespace indicates a wild-card match for any namespace
+ // A null localName indicates "*" from the point of view of ECMA357
+ if (localName != null && localName.equals("*")) throw new RuntimeException("* is not valid localName");
+ QName rv = new QName();
+ rv.namespace = namespace;
+ rv.localName = localName;
+ return rv;
+ }
+
+ /** @deprecated */
+ static QName create(String uri, String localName, String prefix) {
+ return create(Namespace.create(prefix, uri), localName);
+ }
+
+ static String qualify(String prefix, String localName) {
+ if (prefix == null) throw new IllegalArgumentException("prefix must not be null");
+ if (prefix.length() > 0) return prefix + ":" + localName;
+ return localName;
+ }
+
+ private Namespace namespace;
+ private String localName;
+
+ private QName() {
+ }
+
+ public String toString() {
+ return "XmlNode.QName [" + localName + "," + namespace + "]";
+ }
+
+ private boolean equals(String one, String two) {
+ if (one == null && two == null) return true;
+ if (one == null || two == null) return false;
+ return one.equals(two);
+ }
+
+ private boolean namespacesEqual(Namespace one, Namespace two) {
+ if (one == null && two == null) return true;
+ if (one == null || two == null) return false;
+ return equals(one.getUri(), two.getUri());
+ }
+
+ final boolean isEqualTo(QName other) {
+ if (!namespacesEqual(this.namespace, other.namespace)) return false;
+ if (!equals(this.localName, other.localName)) return false;
+ return true;
+ }
+
+ void lookupPrefix(org.w3c.dom.Node node) {
+ if (node == null) throw new IllegalArgumentException("node must not be null");
+ String prefix = node.lookupPrefix(namespace.getUri());
+ if (prefix == null) {
+ // check to see if we match the default namespace
+ String defaultNamespace = node.lookupNamespaceURI(null);
+ if (defaultNamespace == null) defaultNamespace = "";
+ String nodeNamespace = namespace.getUri();
+ if (nodeNamespace.equals(defaultNamespace)) {
+ prefix = "";
+ }
+ }
+ int i = 0;
+ while(prefix == null) {
+ String generatedPrefix = "e4x_" + i++;
+ String generatedUri = node.lookupNamespaceURI(generatedPrefix);
+ if (generatedUri == null) {
+ prefix = generatedPrefix;
+ org.w3c.dom.Node top = node;
+ while(top.getParentNode() != null && top.getParentNode() instanceof org.w3c.dom.Element) {
+ top = top.getParentNode();
+ }
+ ((org.w3c.dom.Element)top).setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + prefix, namespace.getUri());
+ }
+ }
+ namespace.setPrefix(prefix);
+ }
+
+ String qualify(org.w3c.dom.Node node) {
+ if (namespace.getPrefix() == null) {
+ if (node != null) {
+ lookupPrefix(node);
+ } else {
+ if (namespace.getUri().equals("")) {
+ namespace.setPrefix("");
+ } else {
+ // TODO I am not sure this is right, but if we are creating a standalone node, I think we can set the
+ // default namespace on the node itself and not worry about setting a prefix for that namespace.
+ namespace.setPrefix("");
+ }
+ }
+ }
+ return qualify(namespace.getPrefix(), localName);
+ }
+
+ void setAttribute(org.w3c.dom.Element element, String value) {
+ if (namespace.getPrefix() == null) lookupPrefix(element);
+ element.setAttributeNS(namespace.getUri(), qualify(namespace.getPrefix(), localName), value);
+ }
+
+ /** @deprecated Use getNamespace() */
+ String getUri() {
+ return namespace.getUri();
+ }
+
+ /** @deprecated Use getNamespace() */
+ String getPrefix() {
+ return namespace.getPrefix();
+ }
+
+ Namespace getNamespace() {
+ return namespace;
+ }
+
+ String getLocalName() {
+ return localName;
+ }
+ }
+
+ static class List {
+ private java.util.Vector v;
+
+ List() {
+ v = new java.util.Vector();
+ }
+
+ private void _add(XmlNode n) {
+ v.add(n);
+ }
+
+ XmlNode item(int index) {
+ return (XmlNode)(v.get(index));
+ }
+
+ void remove(int index) {
+ v.remove(index);
+ }
+
+ void add(List other) {
+ for (int i=0; i<other.length(); i++) {
+ _add(other.item(i));
+ }
+ }
+
+ void add(List from, int startInclusive, int endExclusive) {
+ for (int i=startInclusive; i<endExclusive; i++) {
+ _add(from.item(i));
+ }
+ }
+
+ void add(XmlNode node) {
+ _add(node);
+ }
+
+ /** @deprecated */
+ void add(XML xml) {
+ _add(xml.getAnnotation());
+ }
+
+ /** @deprecated */
+ void addToList(Object toAdd) {
+ if (toAdd instanceof Undefined) {
+ // Missing argument do nothing...
+ return;
+ }
+
+ if (toAdd instanceof XMLList) {
+ XMLList xmlSrc = (XMLList)toAdd;
+ for (int i = 0; i < xmlSrc.length(); i++) {
+ this._add((xmlSrc.item(i)).getAnnotation());
+ }
+ } else if (toAdd instanceof XML) {
+ this._add(((XML)(toAdd)).getAnnotation());
+ } else if (toAdd instanceof XmlNode) {
+ this._add((XmlNode)toAdd);
+ }
+ }
+
+ int length() {
+ return v.size();
+ }
+ }
+
+ static abstract class Filter {
+ static final Filter COMMENT = new Filter() {
+ boolean accept(Node node) {
+ return node.getNodeType() == Node.COMMENT_NODE;
+ }
+ };
+ static final Filter TEXT = new Filter() {
+ boolean accept(Node node) {
+ return node.getNodeType() == Node.TEXT_NODE;
+ }
+ };
+ static Filter PROCESSING_INSTRUCTION(final XMLName name) {
+ return new Filter() {
+ boolean accept(Node node) {
+ if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
+ ProcessingInstruction pi = (ProcessingInstruction)node;
+ return name.matchesLocalName(pi.getTarget());
+ }
+ return false;
+ }
+ };
+ }
+ static Filter ELEMENT = new Filter() {
+ boolean accept(Node node) {
+ return node.getNodeType() == Node.ELEMENT_NODE;
+ }
+ };
+ static Filter TRUE = new Filter() {
+ boolean accept(Node node) {
+ return true;
+ }
+ };
+ abstract boolean accept(Node node);
+ }
+
+ // Support experimental Java interface
+ org.w3c.dom.Node toDomNode() {
+ return this.dom;
+ }
+}
diff --git a/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlProcessor.java b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlProcessor.java
new file mode 100644
index 0000000..d8ad495
--- /dev/null
+++ b/infrastructure/rhino1_7R1/xmlimplsrc/org/mozilla/javascript/xmlimpl/XmlProcessor.java
@@ -0,0 +1,445 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino DOM-only E4X implementation.
+ *
+ * The Initial Developer of the Original Code is
+ * David P. Caldwell.
+ * Portions created by David P. Caldwell are Copyright (C)
+ * 2007 David P. Caldwell. All Rights Reserved.
+ *
+ *
+ * Contributor(s):
+ * David P. Caldwell <inonit@inonit.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.xmlimpl;
+
+import org.w3c.dom.*;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.mozilla.javascript.*;
+
+// Disambiguate from org.mozilla.javascript.Node
+import org.w3c.dom.Node;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXParseException;
+
+class XmlProcessor {
+ private boolean ignoreComments;
+ private boolean ignoreProcessingInstructions;
+ private boolean ignoreWhitespace;
+ private boolean prettyPrint;
+ private int prettyIndent;
+
+ private javax.xml.parsers.DocumentBuilderFactory dom;
+ private javax.xml.transform.TransformerFactory xform;
+ private DocumentBuilder documentBuilder;
+ private RhinoSAXErrorHandler errorHandler = new RhinoSAXErrorHandler();
+
+
+ private static class RhinoSAXErrorHandler implements ErrorHandler {
+
+ private void throwError(SAXParseException e) {
+ throw ScriptRuntime.constructError("TypeError", e.getMessage(),
+ e.getLineNumber() - 1);
+ }
+
+ public void error(SAXParseException e) {
+ throwError(e);
+ }
+
+ public void fatalError(SAXParseException e) {
+ throwError(e);
+ }
+
+ public void warning(SAXParseException e) {
+ Context.reportWarning(e.getMessage());
+ }
+ }
+
+ XmlProcessor() {
+ setDefault();
+ this.dom = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ this.dom.setNamespaceAware(true);
+ this.dom.setIgnoringComments(false);
+ this.xform = javax.xml.transform.TransformerFactory.newInstance();
+ }
+
+ final void setDefault() {
+ this.setIgnoreComments(true);
+ this.setIgnoreProcessingInstructions(true);
+ this.setIgnoreWhitespace(true);
+ this.setPrettyPrinting(true);
+ this.setPrettyIndent(2);
+ }
+
+ final void setIgnoreComments(boolean b) {
+ this.ignoreComments = b;
+ }
+
+ final void setIgnoreWhitespace(boolean b) {
+ this.ignoreWhitespace = b;
+ }
+
+ final void setIgnoreProcessingInstructions(boolean b) {
+ this.ignoreProcessingInstructions = b;
+ }
+
+ final void setPrettyPrinting(boolean b) {
+ this.prettyPrint = b;
+ }
+
+ final void setPrettyIndent(int i) {
+ this.prettyIndent = i;
+ }
+
+ final boolean isIgnoreComments() {
+ return ignoreComments;
+ }
+
+ final boolean isIgnoreProcessingInstructions() {
+ return ignoreProcessingInstructions;
+ }
+
+ final boolean isIgnoreWhitespace() {
+ return ignoreWhitespace;
+ }
+
+ final boolean isPrettyPrinting() {
+ return prettyPrint;
+ }
+
+ final int getPrettyIndent() {
+ return prettyIndent;
+ }
+
+ private String toXmlNewlines(String rv) {
+ StringBuffer nl = new StringBuffer();
+ for (int i=0; i<rv.length(); i++) {
+ if (rv.charAt(i) == '\r') {
+ if (rv.charAt(i+1) == '\n') {
+ // DOS, do nothing and skip the \r
+ } else {
+ // Macintosh, substitute \n
+ nl.append('\n');
+ }
+ } else {
+ nl.append(rv.charAt(i));
+ }
+ }
+ return nl.toString();
+ }
+
+ private javax.xml.parsers.DocumentBuilderFactory getDomFactory() {
+ return dom;
+ }
+
+ private synchronized DocumentBuilder getDocumentBuilderFromPool()
+ throws javax.xml.parsers.ParserConfigurationException
+ {
+ DocumentBuilder result;
+ if (documentBuilder == null) {
+ javax.xml.parsers.DocumentBuilderFactory factory = getDomFactory();
+ result = factory.newDocumentBuilder();
+ } else {
+ result = documentBuilder;
+ documentBuilder = null;
+ }
+ result.setErrorHandler(errorHandler);
+ return result;
+ }
+
+ private synchronized void returnDocumentBuilderToPool(DocumentBuilder db) {
+ if (documentBuilder == null) {
+ documentBuilder = db;
+ documentBuilder.reset();
+ }
+ }
+
+ private void addProcessingInstructionsTo(java.util.Vector v, Node node) {
+ if (node instanceof ProcessingInstruction) {
+ v.add(node);
+ }
+ if (node.getChildNodes() != null) {
+ for (int i=0; i<node.getChildNodes().getLength(); i++) {
+ addProcessingInstructionsTo(v, node.getChildNodes().item(i));
+ }
+ }
+ }
+
+ private void addCommentsTo(java.util.Vector v, Node node) {
+ if (node instanceof Comment) {
+ v.add(node);
+ }
+ if (node.getChildNodes() != null) {
+ for (int i=0; i<node.getChildNodes().getLength(); i++) {
+ addProcessingInstructionsTo(v, node.getChildNodes().item(i));
+ }
+ }
+ }
+
+ private void addTextNodesToRemoveAndTrim(java.util.Vector toRemove, Node node) {
+ if (node instanceof Text) {
+ Text text = (Text)node;
+ boolean BUG_369394_IS_VALID = false;
+ if (!BUG_369394_IS_VALID) {
+ text.setData(text.getData().trim());
+ } else {
+ if (text.getData().trim().length() == 0) {
+ text.setData("");
+ }
+ }
+ if (text.getData().length() == 0) {
+ toRemove.add(node);
+ }
+ }
+ if (node.getChildNodes() != null) {
+ for (int i=0; i<node.getChildNodes().getLength(); i++) {
+ addTextNodesToRemoveAndTrim(toRemove, node.getChildNodes().item(i));
+ }
+ }
+ }
+
+ final Node toXml(String defaultNamespaceUri, String xml) throws org.xml.sax.SAXException {
+ // See ECMA357 10.3.1
+ DocumentBuilder builder = null;
+ try {
+ String syntheticXml = "<parent xmlns=\"" + defaultNamespaceUri +
+ "\">" + xml + "</parent>";
+ builder = getDocumentBuilderFromPool();
+ Document document = builder.parse( new org.xml.sax.InputSource(new java.io.StringReader(syntheticXml)) );
+ if (ignoreProcessingInstructions) {
+ java.util.Vector v = new java.util.Vector();
+ addProcessingInstructionsTo(v, document);
+ for (int i=0; i<v.size(); i++) {
+ Node node = (Node)v.elementAt(i);
+ node.getParentNode().removeChild(node);
+ }
+ }
+ if (ignoreComments) {
+ java.util.Vector v = new java.util.Vector();
+ addCommentsTo(v, document);
+ for (int i=0; i<v.size(); i++) {
+ Node node = (Node)v.elementAt(i);
+ node.getParentNode().removeChild(node);
+ }
+ }
+ if (ignoreWhitespace) {
+ // Apparently JAXP setIgnoringElementContentWhitespace() has a different meaning, it appears from the Javadoc
+ // Refers to element-only content models, which means we would need to have a validating parser and DTD or schema
+ // so that it would know which whitespace to ignore.
+
+ // Instead we will try to delete it ourselves.
+ java.util.Vector v = new java.util.Vector();
+ addTextNodesToRemoveAndTrim(v, document);
+ for (int i=0; i<v.size(); i++) {
+ Node node = (Node)v.elementAt(i);
+ node.getParentNode().removeChild(node);
+ }
+ }
+ NodeList rv = document.getDocumentElement().getChildNodes();
+ if (rv.getLength() > 1) {
+ throw ScriptRuntime.constructError("SyntaxError", "XML objects may contain at most one node.");
+ } else if (rv.getLength() == 0) {
+ Node node = document.createTextNode("");
+ return node;
+ } else {
+ Node node = rv.item(0);
+ document.getDocumentElement().removeChild(node);
+ return node;
+ }
+ } catch (java.io.IOException e) {
+ throw new RuntimeException("Unreachable.");
+ } catch (javax.xml.parsers.ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (builder != null)
+ returnDocumentBuilderToPool(builder);
+ }
+ }
+
+ Document newDocument() {
+ DocumentBuilder builder = null;
+ try {
+ // TODO Should this use XML settings?
+ builder = getDocumentBuilderFromPool();
+ return builder.newDocument();
+ } catch (javax.xml.parsers.ParserConfigurationException ex) {
+ // TODO How to handle these runtime errors?
+ throw new RuntimeException(ex);
+ } finally {
+ if (builder != null)
+ returnDocumentBuilderToPool(builder);
+ }
+ }
+
+ // TODO Cannot remember what this is for, so whether it should use settings or not
+ private String toString(Node node) {
+ javax.xml.transform.dom.DOMSource source = new javax.xml.transform.dom.DOMSource(node);
+ java.io.StringWriter writer = new java.io.StringWriter();
+ javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(writer);
+ try {
+ javax.xml.transform.Transformer transformer = xform.newTransformer();
+ transformer.setOutputProperty(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "no");
+ transformer.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml");
+ transformer.transform(source, result);
+ } catch (javax.xml.transform.TransformerConfigurationException ex) {
+ // TODO How to handle these runtime errors?
+ throw new RuntimeException(ex);
+ } catch (javax.xml.transform.TransformerException ex) {
+ // TODO How to handle these runtime errors?
+ throw new RuntimeException(ex);
+ }
+ return toXmlNewlines(writer.toString());
+ }
+
+ String escapeAttributeValue(Object value) {
+ String text = ScriptRuntime.toString(value);
+
+ if (text.length() == 0) return "";
+
+ Document dom = newDocument();
+ Element e = dom.createElement("a");
+ e.setAttribute("b", text);
+ String elementText = toString(e);
+ int begin = elementText.indexOf('"');
+ int end = elementText.lastIndexOf('"');
+ return elementText.substring(begin+1,end);
+ }
+
+ String escapeTextValue(Object value) {
+ if (value instanceof XMLObjectImpl) {
+ return ((XMLObjectImpl)value).toXMLString();
+ }
+
+ String text = ScriptRuntime.toString(value);
+
+ if (text.length() == 0) return text;
+
+ Document dom = newDocument();
+ Element e = dom.createElement("a");
+ e.setTextContent(text);
+ String elementText = toString(e);
+
+ int begin = elementText.indexOf('>') + 1;
+ int end = elementText.lastIndexOf('<');
+ return (begin < end) ? elementText.substring(begin, end) : "";
+ }
+
+ private String escapeElementValue(String s) {
+ // TODO Check this
+ return escapeTextValue(s);
+ }
+
+ private String elementToXmlString(Element element) {
+ // TODO My goodness ECMA is complicated (see 10.2.1). We'll try this first.
+ Element copy = (Element)element.cloneNode(true);
+ if (prettyPrint) {
+ beautifyElement(copy, 0);
+ }
+ return toString(copy);
+ }
+
+ final String ecmaToXmlString(Node node) {
+ // See ECMA 357 Section 10.2.1
+ StringBuffer s = new StringBuffer();
+ int indentLevel = 0;
+ if (prettyPrint) {
+ for (int i=0; i<indentLevel; i++) {
+ s.append(' ');
+ }
+ }
+ if (node instanceof Text) {
+ String data = ((Text)node).getData();
+ // TODO Does Java trim() work same as XMLWhitespace?
+ String v = (prettyPrint) ? data.trim() : data;
+ s.append(escapeElementValue(v));
+ return s.toString();
+ }
+ if (node instanceof Attr) {
+ String value = ((Attr)node).getValue();
+ s.append(escapeAttributeValue(value));
+ return s.toString();
+ }
+ if (node instanceof Comment) {
+ s.append("<!--" + ((Comment)node).getNodeValue() + "-->");
+ return s.toString();
+ }
+ if (node instanceof ProcessingInstruction) {
+ ProcessingInstruction pi = (ProcessingInstruction)node;
+ s.append("<?" + pi.getTarget() + " " + pi.getData() + "?>");
+ return s.toString();
+ }
+ s.append(elementToXmlString((Element)node));
+ return s.toString();
+ }
+
+ private void beautifyElement(Element e, int indent) {
+ StringBuffer s = new StringBuffer();
+ s.append('\n');
+ for (int i=0; i<indent; i++) {
+ s.append(' ');
+ }
+ String afterContent = s.toString();
+ for (int i=0; i<prettyIndent; i++) {
+ s.append(' ');
+ }
+ String beforeContent = s.toString();
+
+ // We "mark" all the nodes first; if we tried to do this loop otherwise, it would behave unexpectedly (the inserted nodes
+ // would contribute to the length and it might never terminate).
+ java.util.Vector toIndent = new java.util.Vector();
+ boolean indentChildren = false;
+ for (int i=0; i<e.getChildNodes().getLength(); i++) {
+ if (i == 1) indentChildren = true;
+ if (e.getChildNodes().item(i) instanceof Text) {
+ toIndent.add(e.getChildNodes().item(i));
+ } else {
+ indentChildren = true;
+ toIndent.add(e.getChildNodes().item(i));
+ }
+ }
+ if (indentChildren) {
+ for (int i=0; i<toIndent.size(); i++) {
+ e.insertBefore( e.getOwnerDocument().createTextNode(beforeContent), (Node)toIndent.elementAt(i) );
+ }
+ }
+ NodeList nodes = e.getChildNodes();
+ java.util.Vector v = new java.util.Vector();
+ for (int i=0; i<nodes.getLength(); i++) {
+ if (nodes.item(i) instanceof Element) {
+ v.add( nodes.item(i) );
+ }
+ }
+ for (int i=0; i<v.size(); i++) {
+ beautifyElement( (Element)v.elementAt(i), indent + prettyIndent );
+ }
+ if (indentChildren) {
+ e.appendChild( e.getOwnerDocument().createTextNode(afterContent) );
+ }
+ }
+}
diff --git a/infrastructure/yuicompressor/lib/jargs-1.0.jar b/infrastructure/yuicompressor/lib/jargs-1.0.jar
new file mode 100644
index 0000000..cdbc80b
--- /dev/null
+++ b/infrastructure/yuicompressor/lib/jargs-1.0.jar
Binary files differ
diff --git a/infrastructure/yuicompressor/lib/rhino-yuicompressor.jar b/infrastructure/yuicompressor/lib/rhino-yuicompressor.jar
new file mode 100644
index 0000000..b99560e
--- /dev/null
+++ b/infrastructure/yuicompressor/lib/rhino-yuicompressor.jar
Binary files differ
diff --git a/infrastructure/yuicompressor/make.sh b/infrastructure/yuicompressor/make.sh
new file mode 100755
index 0000000..947aafa
--- /dev/null
+++ b/infrastructure/yuicompressor/make.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+mkdir -p build
+(
+ cd build
+ find ../lib -name '*.jar' | xargs -n1 jar xf
+ rm -rf META-INF
+ cd ..
+ javac -d build -classpath lib/jargs-1.0.jar:lib/rhino-yuicompressor.jar `find src -name '*.java'`
+ cd build
+ jar cf ../../lib/yuicompressor-2.4-appjet.jar *
+)
+rm -rf build
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/Bootstrap.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/Bootstrap.java
new file mode 100644
index 0000000..1b95aca
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/Bootstrap.java
@@ -0,0 +1,22 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.lang.reflect.Method;
+
+public class Bootstrap {
+
+ public static void main(String args[]) throws Exception {
+ ClassLoader loader = new JarClassLoader();
+ Thread.currentThread().setContextClassLoader(loader);
+ Class c = loader.loadClass(YUICompressor.class.getName());
+ Method main = c.getMethod("main", new Class[]{String[].class});
+ main.invoke(null, new Object[]{args});
+ }
+} \ No newline at end of file
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java
new file mode 100644
index 0000000..68b4de9
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java
@@ -0,0 +1,188 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ *
+ * This code is a port of Isaac Schlueter's cssmin utility.
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class CssCompressor {
+
+ private StringBuffer srcsb = new StringBuffer();
+
+ public CssCompressor(Reader in) throws IOException {
+ // Read the stream...
+ int c;
+ while ((c = in.read()) != -1) {
+ srcsb.append((char) c);
+ }
+ }
+
+ public void compress(Writer out, int linebreakpos)
+ throws IOException {
+
+ Pattern p;
+ Matcher m;
+ String css;
+ StringBuffer sb;
+ int startIndex, endIndex;
+
+ // Remove all comment blocks...
+ startIndex = 0;
+ boolean iemac = false;
+ boolean preserve = false;
+ sb = new StringBuffer(srcsb.toString());
+ while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) {
+ preserve = sb.length() > startIndex + 2 && sb.charAt(startIndex + 2) == '!';
+ endIndex = sb.indexOf("*/", startIndex + 2);
+ if (endIndex < 0) {
+ if (!preserve) {
+ sb.delete(startIndex, sb.length());
+ }
+ } else if (endIndex >= startIndex + 2) {
+ if (sb.charAt(endIndex-1) == '\\') {
+ // Looks like a comment to hide rules from IE Mac.
+ // Leave this comment, and the following one, alone...
+ startIndex = endIndex + 2;
+ iemac = true;
+ } else if (iemac) {
+ startIndex = endIndex + 2;
+ iemac = false;
+ } else if (!preserve) {
+ sb.delete(startIndex, endIndex + 2);
+ } else {
+ startIndex = endIndex + 2;
+ }
+ }
+ }
+
+ css = sb.toString();
+
+ // Normalize all whitespace strings to single spaces. Easier to work with that way.
+ css = css.replaceAll("\\s+", " ");
+
+ // Make a pseudo class for the Box Model Hack
+ css = css.replaceAll("\"\\\\\"}\\\\\"\"", "___PSEUDOCLASSBMH___");
+
+ // Remove the spaces before the things that should not have spaces before them.
+ // But, be careful not to turn "p :link {...}" into "p:link{...}"
+ // Swap out any pseudo-class colons with the token, and then swap back.
+ sb = new StringBuffer();
+ p = Pattern.compile("(^|\\})(([^\\{:])+:)+([^\\{]*\\{)");
+ m = p.matcher(css);
+ while (m.find()) {
+ String s = m.group();
+ s = s.replaceAll(":", "___PSEUDOCLASSCOLON___");
+ m.appendReplacement(sb, s);
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+ css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "$1");
+ css = css.replaceAll("___PSEUDOCLASSCOLON___", ":");
+
+ // Remove the spaces after the things that should not have spaces after them.
+ css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "$1");
+
+ // Add the semicolon where it's missing.
+ css = css.replaceAll("([^;\\}])}", "$1;}");
+
+ // Replace 0(px,em,%) with 0.
+ css = css.replaceAll("([\\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2");
+
+ // Replace 0 0 0 0; with 0.
+ css = css.replaceAll(":0 0 0 0;", ":0;");
+ css = css.replaceAll(":0 0 0;", ":0;");
+ css = css.replaceAll(":0 0;", ":0;");
+ // Replace background-position:0; with background-position:0 0;
+ css = css.replaceAll("background-position:0;", "background-position:0 0;");
+
+ // Replace 0.6 to .6, but only when preceded by : or a white-space
+ css = css.replaceAll("(:|\\s)0+\\.(\\d+)", "$1.$2");
+
+ // Shorten colors from rgb(51,102,153) to #336699
+ // This makes it more likely that it'll get further compressed in the next step.
+ p = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ String[] rgbcolors = m.group(1).split(",");
+ StringBuffer hexcolor = new StringBuffer("#");
+ for (int i = 0; i < rgbcolors.length; i++) {
+ int val = Integer.parseInt(rgbcolors[i]);
+ if (val < 16) {
+ hexcolor.append("0");
+ }
+ hexcolor.append(Integer.toHexString(val));
+ }
+ m.appendReplacement(sb, hexcolor.toString());
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Shorten colors from #AABBCC to #ABC. Note that we want to make sure
+ // the color is not preceded by either ", " or =. Indeed, the property
+ // filter: chroma(color="#FFFFFF");
+ // would become
+ // filter: chroma(color="#FFF");
+ // which makes the filter break in IE.
+ p = Pattern.compile("([^\"'=\\s])(\\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ // Test for AABBCC pattern
+ if (m.group(3).equalsIgnoreCase(m.group(4)) &&
+ m.group(5).equalsIgnoreCase(m.group(6)) &&
+ m.group(7).equalsIgnoreCase(m.group(8))) {
+ m.appendReplacement(sb, m.group(1) + m.group(2) + "#" + m.group(3) + m.group(5) + m.group(7));
+ } else {
+ m.appendReplacement(sb, m.group());
+ }
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Remove empty rules.
+ css = css.replaceAll("[^\\}]+\\{;\\}", "");
+
+ if (linebreakpos >= 0) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ int i = 0;
+ int linestartpos = 0;
+ sb = new StringBuffer(css);
+ while (i < sb.length()) {
+ char c = sb.charAt(i++);
+ if (c == '}' && i - linestartpos > linebreakpos) {
+ sb.insert(i, '\n');
+ linestartpos = i;
+ }
+ }
+
+ css = sb.toString();
+ }
+
+ // Replace the pseudo class for the Box Model Hack
+ css = css.replaceAll("___PSEUDOCLASSBMH___", "\"\\\\\"}\\\\\"\"");
+
+ // Replace multiple semi-colons in a row by a single one
+ // See SF bug #1980989
+ css = css.replaceAll(";;+", ";");
+
+ // Trim the final string (for any leading or trailing white spaces)
+ css = css.trim();
+
+ // Write the output...
+ out.write(css);
+ }
+}
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JarClassLoader.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JarClassLoader.java
new file mode 100644
index 0000000..a6d3e13
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JarClassLoader.java
@@ -0,0 +1,158 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+public class JarClassLoader extends ClassLoader {
+
+ private static String jarPath;
+
+ public Class loadClass(String name) throws ClassNotFoundException {
+
+ // First check if the class is already loaded
+ Class c = findLoadedClass(name);
+ if (c == null) {
+ c = findClass(name);
+ }
+
+ if (c == null) {
+ c = ClassLoader.getSystemClassLoader().loadClass(name);
+ }
+
+ return c;
+ }
+
+ private static String getJarPath() {
+
+ if (jarPath != null) {
+ return jarPath;
+ }
+
+ String classname = JarClassLoader.class.getName().replace('.', '/') + ".class";
+ String classpath = System.getProperty("java.class.path");
+ String classpaths[] = classpath.split(System.getProperty("path.separator"));
+
+ for (int i = 0; i < classpaths.length; i++) {
+
+ String path = classpaths[i];
+ JarFile jarFile = null;
+ JarEntry jarEntry = null;
+
+ try {
+ jarFile = new JarFile(path);
+ jarEntry = findJarEntry(jarFile, classname);
+ } catch (IOException ioe) {
+ /* ignore */
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+ }
+ }
+
+ if (jarEntry != null) {
+ jarPath = path;
+ break;
+ }
+ }
+
+ return jarPath;
+ }
+
+ private static JarEntry findJarEntry(JarFile jarFile, String entryName) {
+
+ Enumeration entries = jarFile.entries();
+
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ if (entry.getName().equals(entryName)) {
+ return entry;
+ }
+ }
+
+ return null;
+ }
+
+ protected Class findClass(String name) {
+
+ Class c = null;
+ String jarPath = getJarPath();
+
+ if (jarPath != null) {
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(jarPath);
+ c = loadClassData(jarFile, name);
+ } catch (IOException ioe) {
+ /* ignore */
+ } finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ return c;
+ }
+
+ private Class loadClassData(JarFile jarFile, String className) {
+
+ String entryName = className.replace('.', '/') + ".class";
+ JarEntry jarEntry = findJarEntry(jarFile, entryName);
+ if (jarEntry == null) {
+ return null;
+ }
+
+ // Create the necessary package if needed...
+ int index = className.lastIndexOf('.');
+ if (index >= 0) {
+ String packageName = className.substring(0, index);
+ if (getPackage(packageName) == null) {
+ definePackage(packageName, "", "", "", "", "", "", null);
+ }
+ }
+
+ // Read the Jar File entry and define the class...
+ Class c = null;
+ try {
+ InputStream is = jarFile.getInputStream(jarEntry);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ copy(is, os);
+ byte[] bytes = os.toByteArray();
+ c = defineClass(className, bytes, 0, bytes.length);
+ } catch (IOException ioe) {
+ /* ignore */
+ }
+
+ return c;
+ }
+
+ private void copy(InputStream in, OutputStream out) throws IOException {
+ byte[] buf = new byte[1024];
+ while (true) {
+ int len = in.read(buf);
+ if (len < 0) break;
+ out.write(buf, 0, len);
+ }
+ }
+} \ No newline at end of file
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
new file mode 100644
index 0000000..e69ae1a
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
@@ -0,0 +1,1307 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import yuicompressor.org.mozilla.javascript.*;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class JavaScriptCompressor {
+
+ static final ArrayList ones;
+ static final ArrayList twos;
+ static final ArrayList threes;
+
+ static final Set builtin = new HashSet();
+ static final Map literals = new Hashtable();
+ static final Set reserved = new HashSet();
+
+ static {
+
+ // This list contains all the 3 characters or less built-in global
+ // symbols available in a browser. Please add to this list if you
+ // see anything missing.
+ builtin.add("NaN");
+ builtin.add("top");
+
+ ones = new ArrayList();
+ for (char c = 'A'; c <= 'Z'; c++)
+ ones.add(Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ ones.add(Character.toString(c));
+
+ twos = new ArrayList();
+ for (int i = 0; i < ones.size(); i++) {
+ String one = (String) ones.get(i);
+ for (char c = 'A'; c <= 'Z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ twos.add(one + Character.toString(c));
+ }
+
+ // Remove two-letter JavaScript reserved words and built-in globals...
+ twos.remove("as");
+ twos.remove("is");
+ twos.remove("do");
+ twos.remove("if");
+ twos.remove("in");
+ twos.removeAll(builtin);
+
+ threes = new ArrayList();
+ for (int i = 0; i < twos.size(); i++) {
+ String two = (String) twos.get(i);
+ for (char c = 'A'; c <= 'Z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ threes.add(two + Character.toString(c));
+ }
+
+ // Remove three-letter JavaScript reserved words and built-in globals...
+ threes.remove("for");
+ threes.remove("int");
+ threes.remove("new");
+ threes.remove("try");
+ threes.remove("use");
+ threes.remove("var");
+ threes.removeAll(builtin);
+
+ // That's up to ((26+26)*(1+(26+26+10)))*(1+(26+26+10))-8
+ // (206,380 symbols per scope)
+
+ // The following list comes from org/mozilla/javascript/Decompiler.java...
+ literals.put(new Integer(Token.GET), "get ");
+ literals.put(new Integer(Token.SET), "set ");
+ literals.put(new Integer(Token.TRUE), "true");
+ literals.put(new Integer(Token.FALSE), "false");
+ literals.put(new Integer(Token.NULL), "null");
+ literals.put(new Integer(Token.THIS), "this");
+ literals.put(new Integer(Token.FUNCTION), "function");
+ literals.put(new Integer(Token.COMMA), ",");
+ literals.put(new Integer(Token.LC), "{");
+ literals.put(new Integer(Token.RC), "}");
+ literals.put(new Integer(Token.LP), "(");
+ literals.put(new Integer(Token.RP), ")");
+ literals.put(new Integer(Token.LB), "[");
+ literals.put(new Integer(Token.RB), "]");
+ literals.put(new Integer(Token.DOT), ".");
+ literals.put(new Integer(Token.NEW), "new ");
+ literals.put(new Integer(Token.DELPROP), "delete ");
+ literals.put(new Integer(Token.IF), "if");
+ literals.put(new Integer(Token.ELSE), "else");
+ literals.put(new Integer(Token.FOR), "for");
+ literals.put(new Integer(Token.IN), " in ");
+ literals.put(new Integer(Token.WITH), "with");
+ literals.put(new Integer(Token.WHILE), "while");
+ literals.put(new Integer(Token.DO), "do");
+ literals.put(new Integer(Token.TRY), "try");
+ literals.put(new Integer(Token.CATCH), "catch");
+ literals.put(new Integer(Token.FINALLY), "finally");
+ literals.put(new Integer(Token.THROW), "throw");
+ literals.put(new Integer(Token.SWITCH), "switch");
+ literals.put(new Integer(Token.BREAK), "break");
+ literals.put(new Integer(Token.CONTINUE), "continue");
+ literals.put(new Integer(Token.CASE), "case");
+ literals.put(new Integer(Token.DEFAULT), "default");
+ literals.put(new Integer(Token.RETURN), "return");
+ literals.put(new Integer(Token.VAR), "var ");
+ literals.put(new Integer(Token.SEMI), ";");
+ literals.put(new Integer(Token.ASSIGN), "=");
+ literals.put(new Integer(Token.ASSIGN_ADD), "+=");
+ literals.put(new Integer(Token.ASSIGN_SUB), "-=");
+ literals.put(new Integer(Token.ASSIGN_MUL), "*=");
+ literals.put(new Integer(Token.ASSIGN_DIV), "/=");
+ literals.put(new Integer(Token.ASSIGN_MOD), "%=");
+ literals.put(new Integer(Token.ASSIGN_BITOR), "|=");
+ literals.put(new Integer(Token.ASSIGN_BITXOR), "^=");
+ literals.put(new Integer(Token.ASSIGN_BITAND), "&=");
+ literals.put(new Integer(Token.ASSIGN_LSH), "<<=");
+ literals.put(new Integer(Token.ASSIGN_RSH), ">>=");
+ literals.put(new Integer(Token.ASSIGN_URSH), ">>>=");
+ literals.put(new Integer(Token.HOOK), "?");
+ literals.put(new Integer(Token.OBJECTLIT), ":");
+ literals.put(new Integer(Token.COLON), ":");
+ literals.put(new Integer(Token.OR), "||");
+ literals.put(new Integer(Token.AND), "&&");
+ literals.put(new Integer(Token.BITOR), "|");
+ literals.put(new Integer(Token.BITXOR), "^");
+ literals.put(new Integer(Token.BITAND), "&");
+ literals.put(new Integer(Token.SHEQ), "===");
+ literals.put(new Integer(Token.SHNE), "!==");
+ literals.put(new Integer(Token.EQ), "==");
+ literals.put(new Integer(Token.NE), "!=");
+ literals.put(new Integer(Token.LE), "<=");
+ literals.put(new Integer(Token.LT), "<");
+ literals.put(new Integer(Token.GE), ">=");
+ literals.put(new Integer(Token.GT), ">");
+ literals.put(new Integer(Token.INSTANCEOF), " instanceof ");
+ literals.put(new Integer(Token.LSH), "<<");
+ literals.put(new Integer(Token.RSH), ">>");
+ literals.put(new Integer(Token.URSH), ">>>");
+ literals.put(new Integer(Token.TYPEOF), "typeof");
+ literals.put(new Integer(Token.VOID), "void ");
+ literals.put(new Integer(Token.CONST), "const ");
+ literals.put(new Integer(Token.NOT), "!");
+ literals.put(new Integer(Token.BITNOT), "~");
+ literals.put(new Integer(Token.POS), "+");
+ literals.put(new Integer(Token.NEG), "-");
+ literals.put(new Integer(Token.INC), "++");
+ literals.put(new Integer(Token.DEC), "--");
+ literals.put(new Integer(Token.ADD), "+");
+ literals.put(new Integer(Token.SUB), "-");
+ literals.put(new Integer(Token.MUL), "*");
+ literals.put(new Integer(Token.DIV), "/");
+ literals.put(new Integer(Token.MOD), "%");
+ literals.put(new Integer(Token.COLONCOLON), "::");
+ literals.put(new Integer(Token.DOTDOT), "..");
+ literals.put(new Integer(Token.DOTQUERY), ".(");
+ literals.put(new Integer(Token.XMLATTR), "@");
+
+ // See http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Reserved_Words
+
+ // JavaScript 1.5 reserved words
+ reserved.add("break");
+ reserved.add("case");
+ reserved.add("catch");
+ reserved.add("continue");
+ reserved.add("default");
+ reserved.add("delete");
+ reserved.add("do");
+ reserved.add("else");
+ reserved.add("finally");
+ reserved.add("for");
+ reserved.add("function");
+ reserved.add("if");
+ reserved.add("in");
+ reserved.add("instanceof");
+ reserved.add("new");
+ reserved.add("return");
+ reserved.add("switch");
+ reserved.add("this");
+ reserved.add("throw");
+ reserved.add("try");
+ reserved.add("typeof");
+ reserved.add("var");
+ reserved.add("void");
+ reserved.add("while");
+ reserved.add("with");
+ // Words reserved for future use
+ reserved.add("abstract");
+ reserved.add("boolean");
+ reserved.add("byte");
+ reserved.add("char");
+ reserved.add("class");
+ reserved.add("const");
+ reserved.add("debugger");
+ reserved.add("double");
+ reserved.add("enum");
+ reserved.add("export");
+ reserved.add("extends");
+ reserved.add("final");
+ reserved.add("float");
+ reserved.add("goto");
+ reserved.add("implements");
+ reserved.add("import");
+ reserved.add("int");
+ reserved.add("interface");
+ reserved.add("long");
+ reserved.add("native");
+ reserved.add("package");
+ reserved.add("private");
+ reserved.add("protected");
+ reserved.add("public");
+ reserved.add("short");
+ reserved.add("static");
+ reserved.add("super");
+ reserved.add("synchronized");
+ reserved.add("throws");
+ reserved.add("transient");
+ reserved.add("volatile");
+ // These are not reserved, but should be taken into account
+ // in isValidIdentifier (See jslint source code)
+ reserved.add("arguments");
+ reserved.add("eval");
+ reserved.add("true");
+ reserved.add("false");
+ reserved.add("Infinity");
+ reserved.add("NaN");
+ reserved.add("null");
+ reserved.add("undefined");
+ }
+
+ private static int countChar(String haystack, char needle) {
+ int idx = 0;
+ int count = 0;
+ int length = haystack.length();
+ while (idx < length) {
+ char c = haystack.charAt(idx++);
+ if (c == needle) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ private static int printSourceString(String source, int offset, StringBuffer sb) {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ sb.append(str);
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source,
+ int offset, StringBuffer sb) {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ number = source.charAt(offset);
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long) source.charAt(offset) << 48;
+ lbits |= (long) source.charAt(offset + 1) << 32;
+ lbits |= (long) source.charAt(offset + 2) << 16;
+ lbits |= (long) source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private static ArrayList parse(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ CompilerEnvirons env = new CompilerEnvirons();
+ Parser parser = new Parser(env, reporter);
+ parser.parse(in, null, 1);
+ String source = parser.getEncodedSource();
+
+ int offset = 0;
+ int length = source.length();
+ ArrayList tokens = new ArrayList();
+ StringBuffer sb = new StringBuffer();
+
+ while (offset < length) {
+ int tt = source.charAt(offset++);
+ switch (tt) {
+
+ case Token.SPECIALCOMMENT:
+ case Token.NAME:
+ case Token.REGEXP:
+ case Token.STRING:
+ sb.setLength(0);
+ offset = printSourceString(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ case Token.NUMBER:
+ sb.setLength(0);
+ offset = printSourceNumber(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(tt));
+ if (literal != null) {
+ tokens.add(new JavaScriptToken(tt, literal));
+ }
+ break;
+ }
+ }
+
+ return tokens;
+ }
+
+ private static void processStringLiterals(ArrayList tokens, boolean merge) {
+
+ String tv;
+ int i, length = tokens.size();
+ JavaScriptToken token, prevToken, nextToken;
+
+ if (merge) {
+
+ // Concatenate string literals that are being appended wherever
+ // it is safe to do so. Note that we take care of the case:
+ // "a" + "b".toUpperCase()
+
+ for (i = 0; i < length; i++) {
+ token = (JavaScriptToken) tokens.get(i);
+ switch (token.getType()) {
+
+ case Token.ADD:
+ if (i > 0 && i < length) {
+ prevToken = (JavaScriptToken) tokens.get(i - 1);
+ nextToken = (JavaScriptToken) tokens.get(i + 1);
+ if (prevToken.getType() == Token.STRING && nextToken.getType() == Token.STRING &&
+ (i == length - 1 || ((JavaScriptToken) tokens.get(i + 2)).getType() != Token.DOT)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.STRING,
+ prevToken.getValue() + nextToken.getValue()));
+ tokens.remove(i + 1);
+ tokens.remove(i);
+ i = i - 1;
+ length = length - 2;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ // Second pass...
+
+ for (i = 0; i < length; i++) {
+ // APPJET modifications in this loop
+ token = (JavaScriptToken) tokens.get(i);
+ if (token.getType() == Token.STRING || token.getType() == Token.REGEXP) {
+ tv = token.getValue();
+ if (token.getType() == Token.STRING) {
+
+ // Finally, add the quoting characters and escape the string. We use
+ // the quoting character that minimizes the amount of escaping to save
+ // a few additional bytes.
+
+ char quotechar;
+ int singleQuoteCount = countChar(tv, '\'');
+ int doubleQuoteCount = countChar(tv, '"');
+ if (doubleQuoteCount <= singleQuoteCount) {
+ quotechar = '"';
+ } else {
+ quotechar = '\'';
+ }
+
+ tv = quotechar + escapeString(tv, quotechar) + quotechar;
+ }
+
+ // String concatenation transforms the old script scheme:
+ // '<scr'+'ipt ...><'+'/script>'
+ // into the following:
+ // '<script ...></script>'
+ // which breaks if this code is embedded inside an HTML document.
+ // Since this is not the right way to do this, let's fix the code by
+ // transforming all "</script" into "<\/script"
+
+ // (Anti-malware software can be sensitive to open tags)
+ tv = tv.replace("<script", "\\x3cscript");
+ tv = tv.replace("</script", "\\x3c/script");
+
+ tokens.set(i, new JavaScriptToken(token.getType(), tv));
+ }
+ }
+ }
+
+ // Add necessary escaping that was removed in Rhino's tokenizer.
+ private static String escapeString(String s, char quotechar) {
+
+ assert quotechar == '"' || quotechar == '\'';
+
+ if (s == null) {
+ return null;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, L = s.length(); i < L; i++) {
+ int c = s.charAt(i);
+ if (c == quotechar) {
+ sb.append("\\");
+ }
+ sb.append((char) c);
+ }
+
+ return sb.toString();
+ }
+
+ /*
+ * Simple check to see whether a string is a valid identifier name.
+ * If a string matches this pattern, it means it IS a valid
+ * identifier name. If a string doesn't match it, it does not
+ * necessarily mean it is not a valid identifier name.
+ */
+ private static final Pattern SIMPLE_IDENTIFIER_NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
+
+ private static boolean isValidIdentifier(String s) {
+ Matcher m = SIMPLE_IDENTIFIER_NAME_PATTERN.matcher(s);
+ return (m.matches() && !reserved.contains(s));
+ }
+
+ /*
+ * Transforms obj["foo"] into obj.foo whenever possible, saving 3 bytes.
+ */
+ private static void optimizeObjectMemberAccess(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.LB &&
+ i > 0 && i < length - 2 &&
+ ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.NAME &&
+ ((JavaScriptToken) tokens.get(i + 1)).getType() == Token.STRING &&
+ ((JavaScriptToken) tokens.get(i + 2)).getType() == Token.RB) {
+ token = (JavaScriptToken) tokens.get(i + 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i, new JavaScriptToken(Token.DOT, "."));
+ tokens.set(i + 1, new JavaScriptToken(Token.NAME, tv));
+ tokens.remove(i + 2);
+ i = i + 2;
+ length = length - 1;
+ }
+ }
+ }
+ }
+
+ /*
+ * Transforms 'foo': ... into foo: ... whenever possible, saving 2 bytes.
+ */
+ private static void optimizeObjLitMemberDecl(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.OBJECTLIT &&
+ i > 0 && ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.STRING) {
+ token = (JavaScriptToken) tokens.get(i - 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.NAME, tv));
+ }
+ }
+ }
+ }
+
+ private ErrorReporter logger;
+
+ private boolean munge;
+ private boolean verbose;
+
+ private static final int BUILDING_SYMBOL_TREE = 1;
+ private static final int CHECKING_SYMBOL_TREE = 2;
+
+ private int mode;
+ private int offset;
+ private int braceNesting;
+ private ArrayList tokens;
+ private Stack scopes = new Stack();
+ private ScriptOrFnScope globalScope = new ScriptOrFnScope(-1, null);
+ private Hashtable indexedScopes = new Hashtable();
+
+ public JavaScriptCompressor(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ this.logger = reporter;
+ this.tokens = parse(in, reporter);
+ }
+
+ public void compress(Writer out, int linebreak, boolean munge, boolean verbose,
+ boolean preserveAllSemiColons, boolean disableOptimizations)
+ throws IOException {
+
+ this.munge = munge;
+ this.verbose = verbose;
+
+ processStringLiterals(this.tokens, !disableOptimizations);
+
+ if (!disableOptimizations) {
+ optimizeObjectMemberAccess(this.tokens);
+ optimizeObjLitMemberDecl(this.tokens);
+ }
+
+ buildSymbolTree();
+ // DO NOT TOUCH this.tokens BETWEEN THESE TWO PHASES (BECAUSE OF this.indexedScopes)
+ mungeSymboltree();
+ StringBuffer sb = printSymbolTree(linebreak, preserveAllSemiColons);
+
+ out.write(sb.toString());
+ }
+
+ private ScriptOrFnScope getCurrentScope() {
+ return (ScriptOrFnScope) scopes.peek();
+ }
+
+ private void enterScope(ScriptOrFnScope scope) {
+ scopes.push(scope);
+ }
+
+ private void leaveCurrentScope() {
+ scopes.pop();
+ }
+
+ private JavaScriptToken consumeToken() {
+ return (JavaScriptToken) tokens.get(offset++);
+ }
+
+ private JavaScriptToken getToken(int delta) {
+ return (JavaScriptToken) tokens.get(offset + delta);
+ }
+
+ /*
+ * Returns the identifier for the specified symbol defined in
+ * the specified scope or in any scope above it. Returns null
+ * if this symbol does not have a corresponding identifier.
+ */
+ private JavaScriptIdentifier getIdentifier(String symbol, ScriptOrFnScope scope) {
+ JavaScriptIdentifier identifier;
+ while (scope != null) {
+ identifier = scope.getIdentifier(symbol);
+ if (identifier != null) {
+ return identifier;
+ }
+ scope = scope.getParentScope();
+ }
+ return null;
+ }
+
+ /*
+ * If either 'eval' or 'with' is used in a local scope, we must make
+ * sure that all containing local scopes don't get munged. Otherwise,
+ * the obfuscation would potentially introduce bugs.
+ */
+ private void protectScopeFromObfuscation(ScriptOrFnScope scope) {
+ assert scope != null;
+
+ if (scope == globalScope) {
+ // The global scope does not get obfuscated,
+ // so we don't need to worry about it...
+ return;
+ }
+
+ // Find the highest local scope containing the specified scope.
+ while (scope.getParentScope() != globalScope) {
+ scope = scope.getParentScope();
+ }
+
+ assert scope.getParentScope() == globalScope;
+ scope.preventMunging();
+ }
+
+ private String getDebugString(int max) {
+ assert max > 0;
+ StringBuffer result = new StringBuffer();
+ int start = Math.max(offset - max, 0);
+ int end = Math.min(offset + max, tokens.size());
+ for (int i = start; i < end; i++) {
+ JavaScriptToken token = (JavaScriptToken) tokens.get(i);
+ if (i == offset - 1) {
+ result.append(" ---> ");
+ }
+ result.append(token.getValue());
+ if (i == offset - 1) {
+ result.append(" <--- ");
+ }
+ }
+ return result.toString();
+ }
+
+ private void warn(String message, boolean showDebugString) {
+ if (verbose) {
+ if (showDebugString) {
+ message = message + "\n" + getDebugString(10);
+ }
+ logger.warning(message, null, -1, null, -1);
+ }
+ }
+
+ private void parseFunctionDeclaration() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope, fnScope;
+ JavaScriptIdentifier identifier;
+
+ currentScope = getCurrentScope();
+
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Get the name of the function and declare it in the current scope.
+ symbol = token.getValue();
+ if (currentScope.getIdentifier(symbol) != null) {
+ warn("The function " + symbol + " has already been declared in the same scope...", true);
+ }
+ currentScope.declareIdentifier(symbol);
+ }
+ token = consumeToken();
+ }
+
+ assert token.getType() == Token.LP;
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope = new ScriptOrFnScope(braceNesting, currentScope);
+ indexedScopes.put(new Integer(offset), fnScope);
+ } else {
+ fnScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ }
+
+ // Parse function arguments.
+ int argpos = 0;
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME ||
+ token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME && mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ identifier = fnScope.declareIdentifier(symbol);
+ if (symbol.equals("$super") && argpos == 0) {
+ // Exception for Prototype 1.6...
+ identifier.preventMunging();
+ }
+ argpos++;
+ }
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ braceNesting++;
+
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Hints are empty statements that look like
+ // "localvar1:nomunge, localvar2:nomunge"; They allow developers
+ // to prevent specific symbols from getting obfuscated (some heretic
+ // implementations, such as Prototype 1.6, require specific variable
+ // names, such as $super for example, in order to work appropriately.
+ // Note: right now, only "nomunge" is supported in the right hand side
+ // of a hint. However, in the future, the right hand side may contain
+ // other values.
+ consumeToken();
+ String hints = token.getValue();
+ // Remove the leading and trailing quotes...
+ hints = hints.substring(1, hints.length() - 1).trim();
+ StringTokenizer st1 = new StringTokenizer(hints, ",");
+ while (st1.hasMoreTokens()) {
+ String hint = st1.nextToken();
+ int idx = hint.indexOf(':');
+ if (idx <= 0 || idx >= hint.length() - 1) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // No need to report the error twice, hence the test...
+ warn("Invalid hint syntax: " + hint, true);
+ }
+ break;
+ }
+ String variableName = hint.substring(0, idx).trim();
+ String variableType = hint.substring(idx + 1).trim();
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope.addHint(variableName, variableType);
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+ identifier = fnScope.getIdentifier(variableName);
+ if (identifier != null) {
+ if (variableType.equals("nomunge")) {
+ identifier.preventMunging();
+ } else {
+ warn("Unsupported hint value: " + hint, true);
+ }
+ } else {
+ warn("Hint refers to an unknown identifier: " + hint, true);
+ }
+ }
+ }
+ }
+
+ parseScope(fnScope);
+ }
+
+ private void parseCatch() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ token = getToken(-1);
+ assert token.getType() == Token.CATCH;
+ token = consumeToken();
+ assert token.getType() == Token.LP;
+ token = consumeToken();
+ assert token.getType() == Token.NAME;
+
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // We must declare the exception identifier in the containing function
+ // scope to avoid errors related to the obfuscation process. No need to
+ // display a warning if the symbol was already declared here...
+ currentScope.declareIdentifier(symbol);
+ } else {
+ identifier = getIdentifier(symbol, currentScope);
+ identifier.incrementRefcount();
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.RP;
+ }
+
+ private void parseExpression() {
+
+ // Parse the expression until we encounter a comma or a semi-colon
+ // in the same brace nesting, bracket nesting and paren nesting.
+ // Parse functions if any...
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int expressionBraceNesting = braceNesting;
+ int bracketNesting = 0;
+ int parensNesting = 0;
+
+ int length = tokens.size();
+
+ while (offset < length) {
+
+ token = consumeToken();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.SEMI:
+ case Token.COMMA:
+ if (braceNesting == expressionBraceNesting &&
+ bracketNesting == 0 &&
+ parensNesting == 0) {
+ return;
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= expressionBraceNesting;
+ break;
+
+ case Token.LB:
+ bracketNesting++;
+ break;
+
+ case Token.RB:
+ bracketNesting--;
+ break;
+
+ case Token.LP:
+ parensNesting++;
+ break;
+
+ case Token.RP:
+ parensNesting--;
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(currentScope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(currentScope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 ||
+ (getToken(-2).getType() != Token.DOT &&
+ getToken(-2).getType() != Token.GET &&
+ getToken(-2).getType() != Token.SET)) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, currentScope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void parseScope(ScriptOrFnScope scope) {
+
+ String symbol;
+ JavaScriptToken token;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+
+ enterScope(scope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+
+ switch (token.getType()) {
+
+ case Token.VAR:
+
+ if (mode == BUILDING_SYMBOL_TREE && scope.incrementVarCount() > 1) {
+ warn("Try to use a single 'var' statement per scope.", true);
+ }
+
+ /* FALLSTHROUGH */
+
+ case Token.CONST:
+
+ // The var keyword is followed by at least one symbol name.
+ // If several symbols follow, they are comma separated.
+ for (; ;) {
+ token = consumeToken();
+
+ assert token.getType() == Token.NAME;
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ if (scope.getIdentifier(symbol) == null) {
+ scope.declareIdentifier(symbol);
+ } else {
+ warn("The variable " + symbol + " has already been declared in the same scope...", true);
+ }
+ }
+
+ token = getToken(0);
+
+ assert token.getType() == Token.SEMI ||
+ token.getType() == Token.ASSIGN ||
+ token.getType() == Token.COMMA ||
+ token.getType() == Token.IN;
+
+ if (token.getType() == Token.IN) {
+ break;
+ } else {
+ parseExpression();
+ token = getToken(-1);
+ if (token.getType() == Token.SEMI) {
+ break;
+ }
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= scope.getBraceNesting();
+ if (braceNesting == scope.getBraceNesting()) {
+ leaveCurrentScope();
+ return;
+ }
+ break;
+
+ case Token.WITH:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Inside a 'with' block, it is impossible to figure out
+ // statically whether a symbol is a local variable or an
+ // object member. As a consequence, the only thing we can
+ // do is turn the obfuscation off for the highest scope
+ // containing the 'with' block.
+ protectScopeFromObfuscation(scope);
+ warn("Using 'with' is not recommended." + (munge ? " Moreover, using 'with' reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.CATCH:
+ parseCatch();
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(scope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression." : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(scope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 || getToken(-2).getType() != Token.DOT) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, scope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void buildSymbolTree() {
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ indexedScopes.clear();
+ indexedScopes.put(new Integer(0), globalScope);
+ mode = BUILDING_SYMBOL_TREE;
+ parseScope(globalScope);
+ }
+
+ private void mungeSymboltree() {
+
+ if (!munge) {
+ return;
+ }
+
+ // One problem with obfuscation resides in the use of undeclared
+ // and un-namespaced global symbols that are 3 characters or less
+ // in length. Here is an example:
+ //
+ // var declaredGlobalVar;
+ //
+ // function declaredGlobalFn() {
+ // var localvar;
+ // localvar = abc; // abc is an undeclared global symbol
+ // }
+ //
+ // In the example above, there is a slim chance that localvar may be
+ // munged to 'abc', conflicting with the undeclared global symbol
+ // abc, creating a potential bug. The following code detects such
+ // global symbols. This must be done AFTER the entire file has been
+ // parsed, and BEFORE munging the symbol tree. Note that declaring
+ // extra symbols in the global scope won't hurt.
+ //
+ // Note: Since we go through all the tokens to do this, we also use
+ // the opportunity to count how many times each identifier is used.
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ mode = CHECKING_SYMBOL_TREE;
+ parseScope(globalScope);
+ globalScope.munge();
+ }
+
+ private StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons)
+ throws IOException {
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+ StringBuffer result = new StringBuffer();
+
+ int linestartpos = 0;
+
+ enterScope(globalScope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.NAME:
+
+ if (offset >= 2 && getToken(-2).getType() == Token.DOT ||
+ getToken(0).getType() == Token.OBJECTLIT) {
+
+ result.append(symbol);
+
+ } else {
+
+ identifier = getIdentifier(symbol, currentScope);
+ if (identifier != null) {
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true);
+ }
+ } else {
+ result.append(symbol);
+ }
+ }
+ break;
+
+ case Token.REGEXP:
+ case Token.NUMBER:
+ case Token.STRING:
+ result.append(symbol);
+ break;
+
+ case Token.ADD:
+ case Token.SUB:
+ result.append((String) literals.get(new Integer(token.getType())));
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() == Token.INC ||
+ token.getType() == Token.DEC ||
+ token.getType() == Token.ADD ||
+ token.getType() == Token.DEC) {
+ // Handle the case x +/- ++/-- y
+ // We must keep a white space here. Otherwise, x +++ y would be
+ // interpreted as x ++ + y by the compiler, which is a bug (due
+ // to the implicit assignment being done on the wrong variable)
+ result.append(' ');
+ } else if (token.getType() == Token.POS && getToken(-1).getType() == Token.ADD ||
+ token.getType() == Token.NEG && getToken(-1).getType() == Token.SUB) {
+ // Handle the case x + + y and x - - y
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ result.append("function");
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ result.append(' ');
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more compact way.", true);
+ }
+ token = consumeToken();
+ }
+ assert token.getType() == Token.LP;
+ result.append('(');
+ currentScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ enterScope(currentScope);
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME || token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME) {
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ } else if (token.getType() == Token.COMMA) {
+ result.append(',');
+ }
+ }
+ result.append(')');
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ result.append('{');
+ braceNesting++;
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Skip it!
+ consumeToken();
+ consumeToken();
+ }
+ break;
+
+ case Token.RETURN:
+ case Token.TYPEOF:
+ result.append(literals.get(new Integer(token.getType())));
+ // No space needed after 'return' and 'typeof' when followed
+ // by '(', '[', '{', a string or a regexp.
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() != Token.LP &&
+ token.getType() != Token.LB &&
+ token.getType() != Token.LC &&
+ token.getType() != Token.STRING &&
+ token.getType() != Token.REGEXP &&
+ token.getType() != Token.SEMI) {
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.CASE:
+ case Token.THROW:
+ result.append(literals.get(new Integer(token.getType())));
+ // White-space needed after 'case' and 'throw' when not followed by a string.
+ if (offset < length && getToken(0).getType() != Token.STRING) {
+ result.append(' ');
+ }
+ break;
+
+ case Token.BREAK:
+ case Token.CONTINUE:
+ result.append(literals.get(new Integer(token.getType())));
+ if (offset < length && getToken(0).getType() != Token.SEMI) {
+ // If 'break' or 'continue' is not followed by a semi-colon, it must
+ // be followed by a label, hence the need for a white space.
+ result.append(' ');
+ }
+ break;
+
+ case Token.LC:
+ result.append('{');
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ result.append('}');
+ braceNesting--;
+ assert braceNesting >= currentScope.getBraceNesting();
+ if (braceNesting == currentScope.getBraceNesting()) {
+ leaveCurrentScope();
+ }
+ break;
+
+ case Token.SEMI:
+ // No need to output a semi-colon if the next character is a right-curly...
+ if (preserveAllSemiColons || offset < length && getToken(0).getType() != Token.RC) {
+ result.append(';');
+ }
+
+ if (linebreakpos >= 0 && result.length() - linestartpos > linebreakpos) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ result.append('\n');
+ linestartpos = result.length();
+ }
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
+ result.append("\n");
+ }
+ result.append("/*");
+ result.append(symbol);
+ result.append("*/\n");
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(token.getType()));
+ if (literal != null) {
+ result.append(literal);
+ } else {
+ warn("This symbol cannot be printed: " + symbol, true);
+ }
+ break;
+ }
+ }
+
+ // Append a semi-colon at the end, even if unnecessary semi-colons are
+ // supposed to be removed. This is especially useful when concatenating
+ // several minified files (the absence of an ending semi-colon at the
+ // end of one file may very likely cause a syntax error)
+ if (!preserveAllSemiColons && result.length() > 0) {
+ if (result.charAt(result.length() - 1) == '\n') {
+ result.setCharAt(result.length() - 1, ';');
+ } else {
+ result.append(';');
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
new file mode 100644
index 0000000..8668f49
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
@@ -0,0 +1,55 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import yuicompressor.org.mozilla.javascript.Token;
+
+/**
+ * JavaScriptIdentifier represents a variable/function identifier.
+ */
+class JavaScriptIdentifier extends JavaScriptToken {
+
+ private int refcount = 0;
+ private String mungedValue;
+ private ScriptOrFnScope declaredScope;
+ private boolean markedForMunging = true;
+
+ JavaScriptIdentifier(String value, ScriptOrFnScope declaredScope) {
+ super(Token.NAME, value);
+ this.declaredScope = declaredScope;
+ }
+
+ ScriptOrFnScope getDeclaredScope() {
+ return declaredScope;
+ }
+
+ void setMungedValue(String value) {
+ mungedValue = value;
+ }
+
+ String getMungedValue() {
+ return mungedValue;
+ }
+
+ void preventMunging() {
+ markedForMunging = false;
+ }
+
+ boolean isMarkedForMunging() {
+ return markedForMunging;
+ }
+
+ void incrementRefcount() {
+ refcount++;
+ }
+
+ int getRefcount() {
+ return refcount;
+ }
+}
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
new file mode 100644
index 0000000..fee21d9
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
@@ -0,0 +1,28 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+public class JavaScriptToken {
+
+ private int type;
+ private String value;
+
+ JavaScriptToken(int type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ int getType() {
+ return type;
+ }
+
+ String getValue() {
+ return value;
+ }
+}
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
new file mode 100644
index 0000000..c1a2e47
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
@@ -0,0 +1,169 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+class ScriptOrFnScope {
+
+ private int braceNesting;
+ private ScriptOrFnScope parentScope;
+ private ArrayList subScopes;
+ private Hashtable identifiers = new Hashtable();
+ private Hashtable hints = new Hashtable();
+ private boolean markedForMunging = true;
+ private int varcount = 0;
+
+ ScriptOrFnScope(int braceNesting, ScriptOrFnScope parentScope) {
+ this.braceNesting = braceNesting;
+ this.parentScope = parentScope;
+ this.subScopes = new ArrayList();
+ if (parentScope != null) {
+ parentScope.subScopes.add(this);
+ }
+ }
+
+ int getBraceNesting() {
+ return braceNesting;
+ }
+
+ ScriptOrFnScope getParentScope() {
+ return parentScope;
+ }
+
+ JavaScriptIdentifier declareIdentifier(String symbol) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) identifiers.get(symbol);
+ if (identifier == null) {
+ identifier = new JavaScriptIdentifier(symbol, this);
+ identifiers.put(symbol, identifier);
+ }
+ return identifier;
+ }
+
+ JavaScriptIdentifier getIdentifier(String symbol) {
+ return (JavaScriptIdentifier) identifiers.get(symbol);
+ }
+
+ void addHint(String variableName, String variableType) {
+ hints.put(variableName, variableType);
+ }
+
+ void preventMunging() {
+ if (parentScope != null) {
+ // The symbols in the global scope don't get munged,
+ // but the sub-scopes it contains do get munged.
+ markedForMunging = false;
+ }
+ }
+
+ private ArrayList getUsedSymbols() {
+ ArrayList result = new ArrayList();
+ Enumeration elements = identifiers.elements();
+ while (elements.hasMoreElements()) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.nextElement();
+ String mungedValue = identifier.getMungedValue();
+ if (mungedValue == null) {
+ mungedValue = identifier.getValue();
+ }
+ result.add(mungedValue);
+ }
+ return result;
+ }
+
+ private ArrayList getAllUsedSymbols() {
+ ArrayList result = new ArrayList();
+ ScriptOrFnScope scope = this;
+ while (scope != null) {
+ result.addAll(scope.getUsedSymbols());
+ scope = scope.parentScope;
+ }
+ return result;
+ }
+
+ int incrementVarCount() {
+ varcount++;
+ return varcount;
+ }
+
+ void munge() {
+
+ if (!markedForMunging) {
+ // Stop right here if this scope was flagged as unsafe for munging.
+ return;
+ }
+
+ int pickFromSet = 1;
+
+ // Do not munge symbols in the global scope!
+ if (parentScope != null) {
+
+ ArrayList freeSymbols = new ArrayList();
+
+ freeSymbols.addAll(JavaScriptCompressor.ones);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 2;
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 3;
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+
+ // APPJET: sort identifiers by popularity
+ JavaScriptIdentifier idArray[] = ((Hashtable<String,JavaScriptIdentifier>)identifiers).values().toArray(new JavaScriptIdentifier[0]);
+ java.util.Arrays.sort(idArray, new java.util.Comparator<JavaScriptIdentifier>() {
+ public int compare(JavaScriptIdentifier i1, JavaScriptIdentifier i2) {
+ return i2.getRefcount() - i1.getRefcount(); // positive if i2 is more popular, indicating i2 should come first
+ }
+ });
+ java.util.Iterator<JavaScriptIdentifier> elements = java.util.Arrays.asList(idArray).iterator();
+
+ //Enumeration elements = identifiers.elements();
+ while (elements.hasNext()) {
+ if (freeSymbols.size() == 0) {
+ pickFromSet++;
+ if (pickFromSet == 2) {
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ } else if (pickFromSet == 3) {
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ } else {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+ // It is essential to remove the symbols already used in
+ // the containing scopes, or some of the variables declared
+ // in the containing scopes will be redeclared, which can
+ // lead to errors.
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+
+ String mungedValue;
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.next();
+ if (identifier.isMarkedForMunging()) {
+ mungedValue = (String) freeSymbols.remove(0);
+ } else {
+ mungedValue = identifier.getValue();
+ }
+ identifier.setMungedValue(mungedValue);
+ }
+ }
+
+ for (int i = 0; i < subScopes.size(); i++) {
+ ScriptOrFnScope scope = (ScriptOrFnScope) subScopes.get(i);
+ scope.munge();
+ }
+ }
+}
diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/YUICompressor.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/YUICompressor.java
new file mode 100644
index 0000000..dcbaff4
--- /dev/null
+++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/YUICompressor.java
@@ -0,0 +1,232 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import jargs.gnu.CmdLineParser;
+import yuicompressor.org.mozilla.javascript.ErrorReporter;
+import yuicompressor.org.mozilla.javascript.EvaluatorException;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+public class YUICompressor {
+
+ public static void main(String args[]) {
+
+ CmdLineParser parser = new CmdLineParser();
+ CmdLineParser.Option typeOpt = parser.addStringOption("type");
+ CmdLineParser.Option verboseOpt = parser.addBooleanOption('v', "verbose");
+ CmdLineParser.Option nomungeOpt = parser.addBooleanOption("nomunge");
+ CmdLineParser.Option linebreakOpt = parser.addStringOption("line-break");
+ CmdLineParser.Option preserveSemiOpt = parser.addBooleanOption("preserve-semi");
+ CmdLineParser.Option disableOptimizationsOpt = parser.addBooleanOption("disable-optimizations");
+ CmdLineParser.Option helpOpt = parser.addBooleanOption('h', "help");
+ CmdLineParser.Option charsetOpt = parser.addStringOption("charset");
+ CmdLineParser.Option outputFilenameOpt = parser.addStringOption('o', "output");
+
+ Reader in = null;
+ Writer out = null;
+
+ try {
+
+ parser.parse(args);
+
+ Boolean help = (Boolean) parser.getOptionValue(helpOpt);
+ if (help != null && help.booleanValue()) {
+ usage();
+ System.exit(0);
+ }
+
+ boolean verbose = parser.getOptionValue(verboseOpt) != null;
+
+ String charset = (String) parser.getOptionValue(charsetOpt);
+ if (charset == null || !Charset.isSupported(charset)) {
+ charset = System.getProperty("file.encoding");
+ if (charset == null) {
+ charset = "UTF-8";
+ }
+ if (verbose) {
+ System.err.println("\n[INFO] Using charset " + charset);
+ }
+ }
+
+ String[] fileArgs = parser.getRemainingArgs();
+ String type = (String) parser.getOptionValue(typeOpt);
+
+ if (fileArgs.length == 0) {
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(System.in, charset);
+
+ } else {
+
+ if (type != null && !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ String inputFilename = fileArgs[0];
+
+ if (type == null) {
+ int idx = inputFilename.lastIndexOf('.');
+ if (idx >= 0 && idx < inputFilename.length() - 1) {
+ type = inputFilename.substring(idx + 1);
+ }
+ }
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(new FileInputStream(inputFilename), charset);
+ }
+
+ int linebreakpos = -1;
+ String linebreakstr = (String) parser.getOptionValue(linebreakOpt);
+ if (linebreakstr != null) {
+ try {
+ linebreakpos = Integer.parseInt(linebreakstr, 10);
+ } catch (NumberFormatException e) {
+ usage();
+ System.exit(1);
+ }
+ }
+
+ String outputFilename = (String) parser.getOptionValue(outputFilenameOpt);
+
+ if (type.equalsIgnoreCase("js")) {
+
+ try {
+
+ JavaScriptCompressor compressor = new JavaScriptCompressor(in, new ErrorReporter() {
+
+ public void warning(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[WARNING] " + message);
+ } else {
+ System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public void error(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[ERROR] " + message);
+ } else {
+ System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public EvaluatorException runtimeError(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ error(message, sourceName, line, lineSource, lineOffset);
+ return new EvaluatorException(message);
+ }
+ });
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ boolean munge = parser.getOptionValue(nomungeOpt) == null;
+ boolean preserveAllSemiColons = parser.getOptionValue(preserveSemiOpt) != null;
+ boolean disableOptimizations = parser.getOptionValue(disableOptimizationsOpt) != null;
+
+ compressor.compress(out, linebreakpos, munge, verbose,
+ preserveAllSemiColons, disableOptimizations);
+
+ } catch (EvaluatorException e) {
+
+ e.printStackTrace();
+ // Return a special error code used specifically by the web front-end.
+ System.exit(2);
+
+ }
+
+ } else if (type.equalsIgnoreCase("css")) {
+
+ CssCompressor compressor = new CssCompressor(in);
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ compressor.compress(out, linebreakpos);
+ }
+
+ } catch (CmdLineParser.OptionException e) {
+
+ usage();
+ System.exit(1);
+
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ System.exit(1);
+
+ } finally {
+
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static void usage() {
+ System.out.println(
+ "\nUsage: java -jar yuicompressor-x.y.z.jar [options] [input file]\n\n"
+
+ + "Global Options\n"
+ + " -h, --help Displays this information\n"
+ + " --type <js|css> Specifies the type of the input file\n"
+ + " --charset <charset> Read the input file using <charset>\n"
+ + " --line-break <column> Insert a line break after the specified column number\n"
+ + " -v, --verbose Display informational messages and warnings\n"
+ + " -o <file> Place the output into <file>. Defaults to stdout.\n\n"
+
+ + "JavaScript Options\n"
+ + " --nomunge Minify only, do not obfuscate\n"
+ + " --preserve-semi Preserve all semicolons\n"
+ + " --disable-optimizations Disable all micro optimizations\n\n"
+
+ + "If no input file is specified, it defaults to stdin. In this case, the 'type'\n"
+ + "option is required. Otherwise, the 'type' option is required only if the input\n"
+ + "file extension is neither 'js' nor 'css'.");
+ }
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java
new file mode 100644
index 0000000..348c568
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java
@@ -0,0 +1,916 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package yuicompressor.org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addJScriptConditionalComment(String str)
+ {
+ addToken(Token.SPECIALCOMMENT);
+ appendString(str);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java.orig b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java.orig
new file mode 100644
index 0000000..cdb00b7
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Decompiler.java.orig
@@ -0,0 +1,910 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java
new file mode 100644
index 0000000..bf830a8
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java
@@ -0,0 +1,2170 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package yuicompressor.org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+
+ while ((tt = ts.getToken()) == Token.SPECIALCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ }
+
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+
+ if (tt == Token.SPECIALCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ }
+
+ } while (tt == Token.EOL || tt == Token.SPECIALCOMMENT);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function <name>' does not follow
+ // by '(', assume <name> starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java.orig b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java.orig
new file mode 100644
index 0000000..628bb42
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Parser.java.orig
@@ -0,0 +1,2159 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+ tt = ts.getToken();
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+ } while (tt == Token.EOL);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function <name>' does not follow
+ // by '(', assume <name> starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java
new file mode 100644
index 0000000..f082d68
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java
@@ -0,0 +1,420 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package yuicompressor.org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see yuicompressor.org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+
+ SPECIALCOMMENT = 152, // Internet Explorer conditional comment
+
+ LAST_TOKEN = 153;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java.orig b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java.orig
new file mode 100644
index 0000000..7f7cdc2
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/Token.java.orig
@@ -0,0 +1,417 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+ LAST_TOKEN = 152;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java
new file mode 100644
index 0000000..5bee827
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java
@@ -0,0 +1,1381 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package yuicompressor.org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see yuicompressor.org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.RESERVED,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2001-06-01 17:45:01 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': X="break";id=Id_break; break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ case 'm': X="import";id=Id_import; break L;
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a <backslash>
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the <backslash>uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ this.string = (String)allStrings.intern(str);
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ parser.addError("msg.unterminated.string.lit");
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+
+ c = getChar();
+
+ switch (c) {
+
+ case '\\': // backslash
+ case 'b': // backspace
+ case 'f': // form feed
+ case 'n': // line feed
+ case 'r': // carriage return
+ case 't': // horizontal tab
+ case 'v': // vertical tab
+ case 'd': // octal sequence
+ case 'u': // unicode sequence
+ case 'x': // hexadecimal sequence
+ // Only keep the '\' character for those
+ // characters that need to be escaped...
+ // Don't escape quoting characters...
+ addToString('\\');
+ addToString(c);
+ break;
+
+ case '\n':
+ // Remove line terminator after escape
+ break;
+
+ default:
+ if (isDigit(c)) {
+ // Octal representation of a character.
+ // Preserve the escaping (see Y! bug #1637286)
+ addToString('\\');
+ }
+ addToString(c);
+ break;
+ }
+
+ } else {
+
+ addToString(c);
+ }
+
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ }
+ sb.append((char) c);
+ if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ sb.delete(sb.length()-2, sb.length());
+ String s = sb.toString();
+ if (s.startsWith("!") ||
+ s.startsWith("@cc_on") ||
+ s.startsWith("@if") ||
+ s.startsWith("@elif") ||
+ s.startsWith("@else") ||
+ s.startsWith("@end")) {
+ if (s.startsWith("!")) {
+ // Remove the leading '!'
+ this.string = s.substring(1);
+ } else {
+ this.string = s;
+ }
+ return Token.SPECIALCOMMENT;
+ } else {
+ continue retry;
+ }
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ boolean inClass = false;
+ while ((c = getChar()) != '/' || inClass) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ } else if (c == '[') {
+ inClass = true;
+ } else if (c == ']') {
+ inClass = false;
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in <!--
+ private final int[] ungetBuffer = new int[3];
+ private int ungetCursor;
+
+ private boolean hitEOF = false;
+
+ private int lineStart = 0;
+ private int lineno;
+ private int lineEndChar = -1;
+
+ private String sourceString;
+ private Reader sourceReader;
+ private char[] sourceBuffer;
+ private int sourceEnd;
+ private int sourceCursor;
+
+ // for xml tokenizer
+ private boolean xmlIsAttribute;
+ private boolean xmlIsTagContent;
+ private int xmlOpenTagsCount;
+
+ private Parser parser;
+}
diff --git a/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java.orig b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java.orig
new file mode 100644
index 0000000..c276894
--- /dev/null
+++ b/infrastructure/yuicompressor/src/yuicompressor/org/mozilla/javascript/TokenStream.java.orig
@@ -0,0 +1,1398 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.RESERVED,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2001-06-01 17:45:01 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': X="break";id=Id_break; break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ case 'm': X="import";id=Id_import; break L;
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a <backslash>
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the <backslash>uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ this.string = (String)allStrings.intern(str);
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ strLoop: while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ parser.addError("msg.unterminated.string.lit");
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+ int escapeVal;
+
+ c = getChar();
+ switch (c) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+
+ // \v a late addition to the ECMA spec,
+ // it is not in Java, so use 0xb
+ case 'v': c = 0xb; break;
+
+ case 'u':
+ // Get 4 hex digits; if the u escape is not
+ // followed by 4 hex digits, use 'u' + the
+ // literal character sequence that follows.
+ int escapeStart = stringBufferTop;
+ addToString('u');
+ escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ continue strLoop;
+ }
+ addToString(c);
+ }
+ // prepare for replace of stored 'u' sequence
+ // by escape value
+ stringBufferTop = escapeStart;
+ c = escapeVal;
+ break;
+ case 'x':
+ // Get 2 hex digits, defaulting to 'x'+literal
+ // sequence, as above.
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, 0);
+ if (escapeVal < 0) {
+ addToString('x');
+ continue strLoop;
+ } else {
+ int c1 = c;
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ addToString('x');
+ addToString(c1);
+ continue strLoop;
+ } else {
+ // got 2 hex digits
+ c = escapeVal;
+ }
+ }
+ break;
+
+ case '\n':
+ // Remove line terminator after escape to follow
+ // SpiderMonkey and C/C++
+ c = getChar();
+ continue strLoop;
+
+ default:
+ if ('0' <= c && c < '8') {
+ int val = c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8') {
+ val = 8 * val + c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8' && val <= 037) {
+ // c is 3rd char of octal sequence only
+ // if the resulting val <= 0377
+ val = 8 * val + c - '0';
+ c = getChar();
+ }
+ }
+ ungetChar(c);
+ c = val;
+ }
+ }
+ }
+ addToString(c);
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ } else if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ continue retry;
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ while ((c = getChar()) != '/') {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in <!--
+ private final int[] ungetBuffer = new int[3];
+ private int ungetCursor;
+
+ private boolean hitEOF = false;
+
+ private int lineStart = 0;
+ private int lineno;
+ private int lineEndChar = -1;
+
+ private String sourceString;
+ private Reader sourceReader;
+ private char[] sourceBuffer;
+ private int sourceEnd;
+ private int sourceCursor;
+
+ // for xml tokenizer
+ private boolean xmlIsAttribute;
+ private boolean xmlIsTagContent;
+ private int xmlOpenTagsCount;
+
+ private Parser parser;
+}