Initial commit of Modified Rhino based on CQ 6838, This is a forked version of Rhino 1.7R1. To help resolve this fork a pull request has been submitted to mozilla/rhino project[1] and google group discussion has been initiated[2].

[1] https://github.com/mozilla/rhino/pull/96
[2] https://groups.google.com/forum/?fromgroups=#!topic/mozilla-rhino/uyFBPO79i7g
diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..14b9e0a
--- /dev/null
+++ b/.DS_Store
Binary files differ
diff --git a/org.eclipse.vjet.extmod.rhino/.classpath b/org.eclipse.vjet.extmod.rhino/.classpath
new file mode 100644
index 0000000..b23b657
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+<classpathentry kind="src" path="src"/>

+<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/org.eclipse.vjet.extmod.rhino/.gitignore b/org.eclipse.vjet.extmod.rhino/.gitignore
new file mode 100644
index 0000000..5e56e04
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/org.eclipse.vjet.extmod.rhino/.project b/org.eclipse.vjet.extmod.rhino/.project
new file mode 100644
index 0000000..afa4b10
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.vjet.extmod.rhino</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/org.eclipse.vjet.extmod.rhino/ChangeLog.txt b/org.eclipse.vjet.extmod.rhino/ChangeLog.txt
new file mode 100644
index 0000000..26ab58a
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/ChangeLog.txt
@@ -0,0 +1,22 @@
+

+

+

+Yoda:

+

+- (hzariv) added a new marker interface called IWillBeScriptable. 

+  This interface is used by JsNative interfaces to indicate that implementation class of this interface 

+  is a Rhino scriptable object and can be safetly casted to Scriptable interface.

+

+- (yyao) added m_javaProxy in ScriptableObject and modified get and put methods

+  This specific field is to store IJsJavaProxy if the current native object

+  had been wrapped by an IJsJavaProxy. It wasn't added into normal property to

+  avoid different "for-in" results.

+

+

+- (yyao) added IJsJavaConvertible and IJsJavaConverter, modified Context and

+NativeJavaObject to support custom data type conversion.

+

+- (yyao) modified NativeJavaMethod to enable escaping extra args for Java

+method invocation

+  This modification is to simulate JavaScript behavior where extra args can be

+  ignored

diff --git a/org.eclipse.vjet.extmod.rhino/META-INF/MANIFEST.MF b/org.eclipse.vjet.extmod.rhino/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c103ddd
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0

+Bundle-ManifestVersion: 2

+Bundle-Vendor: %pluginProvider

+Bundle-Name: %pluginName

+Bundle-SymbolicName: org.eclipse.vjet.extmod.rhino

+Bundle-Version: 0.9.0.qualifier

+Bundle-ActivationPolicy: lazy

+Bundle-Localization: plugin

+Bundle-RequiredExecutionEnvironment: JavaSE-1.6

+Export-Package: org.mozilla.mod.classfile,

+  org.mozilla.mod.javascript,

+  org.mozilla.mod.javascript.continuations,

+  org.mozilla.mod.javascript.debug,

+  org.mozilla.mod.javascript.jdk11,

+  org.mozilla.mod.javascript.jdk13,

+  org.mozilla.mod.javascript.jdk15,

+  org.mozilla.mod.javascript.optimizer,

+  org.mozilla.mod.javascript.regexp,

+  org.mozilla.mod.javascript.serialize,

+  org.mozilla.mod.javascript.xml

+

diff --git a/org.eclipse.vjet.extmod.rhino/ant-build.properties b/org.eclipse.vjet.extmod.rhino/ant-build.properties
new file mode 100644
index 0000000..513e325
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/ant-build.properties
@@ -0,0 +1,70 @@
+###############################################################################
+# Copyright (c) 2012 eBay Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     eBay Inc. - initial API and implementation
+###############################################################################
+# The contents of this file are subject to the Netscape 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/NPL/

+#

+# 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 Netscape are

+# Copyright (C) 1997-1999 Netscape Communications Corporation. All

+# Rights Reserved.

+#

+# Contributor(s):

+# Igor Bukanov

+#

+# Alternatively, the contents of this file may be used under the

+# terms of the GNU Public License (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 NPL, indicate your decision by

+# deleting the provisions above and replace 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 NPL or the GPL.

+

+name: rhino

+Name: Rhino

+version: 1_6R2

+# See Context#getImplementationVersion() for format of this!

+implementation.version: Rhino 1.6 release 2 ${implementation.date}

+

+build.dir: build

+rhino.jar: js.jar

+small-rhino.jar: smalljs.jar

+

+dist.name: rhino${version}

+dist.dir: ${build.dir}/${dist.name}

+

+# compilation destionation

+classes: ${build.dir}/classes

+

+# compilation settings

+debug: on

+target-jvm: 1.1

+source-level: 1.3

+

+# jar generation settings 

+jar-compression: true

+

+# optional external packages

+lib: lib

+xbean.jar: ${lib}/xbean.jar

+

diff --git a/org.eclipse.vjet.extmod.rhino/ant-build.xml b/org.eclipse.vjet.extmod.rhino/ant-build.xml
new file mode 100644
index 0000000..0d2b4d1
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/ant-build.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="utf-8"?>

+

+<!--

+Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)

+Requires Ant version 1.2 or later

+-->

+

+<project name="Rhino" default="help" basedir=".">

+

+  <target name="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"/>

+    <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">

+    <jar jarfile="${dist.dir}/${rhino.jar}"

+         basedir="${classes}"

+         manifest="src/manifest"

+     compress="${jar-compression}"

+     />

+  </target>

+

+  <target name="smalljar" depends="compile">

+

+    <jar basedir="${classes}" destfile="${dist.dir}/${small-rhino.jar}"

+         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="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="copy-docs" depends="init">

+    <echo message="copy from docs"/>

+    <mkdir dir="${dist.dir}/docs"/>

+    <copy todir="${dist.dir}/docs">

+      <fileset dir="docs" includes="**/*.html,**/*.jpg,**/*.gif,**/*.js" />

+    </copy>

+  </target>

+

+  <target name="javadoc" depends="copy-docs">

+    <mkdir dir="${dist.dir}/docs/apidocs"/>

+    <javadoc sourcefiles="${apiClasses}"

+             sourcepath="src"

+             destdir="${dist.dir}/docs/apidocs"

+             overview="${dist.dir}/docs/api.html"

+             version="true"

+             author="true"

+             windowtitle="${Name}" />

+  </target>

+

+  <target name="dist" depends="deepclean,jar,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,copy-docs">

+    <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/**"/>

+        <include name="docs/**"/>

+        <exclude name="docs/apidocs/**"/>

+      </zipfileset>

+    </zip>

+  </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="${classes}"/>

+  </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>

+

+  <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}/docs/apidocs

+

+ source-zip  create ${dist.source-only-zip} with all Rhino

+             source files necessary to recreate ${dist.file}

+</echo>

+  </target>

+

+</project>

diff --git a/org.eclipse.vjet.extmod.rhino/apiClasses.properties b/org.eclipse.vjet.extmod.rhino/apiClasses.properties
new file mode 100644
index 0000000..ccdb2db
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/apiClasses.properties
@@ -0,0 +1,41 @@
+###############################################################################
+# Copyright (c) 2012 eBay Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     eBay Inc. - initial API and implementation
+###############################################################################
+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/org.eclipse.vjet.extmod.rhino/build.properties b/org.eclipse.vjet.extmod.rhino/build.properties
new file mode 100644
index 0000000..af9ed2a
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2012 eBay Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     eBay Inc. - initial API and implementation
+###############################################################################
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.properties
\ No newline at end of file
diff --git a/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/ClassDefinitionException.java b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/ClassDefinitionException.java
new file mode 100644
index 0000000..b0ae3dd
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/ClassDefinitionException.java
@@ -0,0 +1,50 @@
+

+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-

+ *

+ * The contents of this file are subject to the Netscape 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/NPL/

+ *

+ * 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 Netscape are

+ * Copyright (C) 1997, 2012 Netscape Communications Corporation. All

+ * Rights Reserved.

+ *

+ * Contributor(s):

+ *

+ * Alternatively, the contents of this file may be used under the

+ * terms of the GNU Public License (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 NPL, indicate your decision by

+ * deleting the provisions above and replace 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 NPL or the GPL.

+ */

+// API class

+

+package com.ebay.internal.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/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/NotAFunctionException.java b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/NotAFunctionException.java
new file mode 100644
index 0000000..cd100a1
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/NotAFunctionException.java
@@ -0,0 +1,49 @@
+

+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-

+ *

+ * The contents of this file are subject to the Netscape 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/NPL/

+ *

+ * 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 Netscape are

+ * Copyright (C) 1997, 2012 Netscape Communications Corporation. All

+ * Rights Reserved.

+ *

+ * Contributor(s):

+ * Igor Bukanov

+ *

+ * Alternatively, the contents of this file may be used under the

+ * terms of the GNU Public License (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 NPL, indicate your decision by

+ * deleting the provisions above and replace 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 NPL or the GPL.

+ */

+// API class

+

+package com.ebay.internal.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/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/PropertyException.java b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/PropertyException.java
new file mode 100644
index 0000000..b21616b
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/deprecatedsrc/com/ebay/internal/org/mozilla/javascript/PropertyException.java
@@ -0,0 +1,51 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-

+ *

+ * The contents of this file are subject to the Netscape 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/NPL/

+ *

+ * 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 Netscape are

+ * Copyright (C) 1997, 2012 Netscape Communications Corporation. All

+ * Rights Reserved.

+ *

+ * Contributor(s):

+ * Norris Boyd

+ *

+ * Alternatively, the contents of this file may be used under the

+ * terms of the GNU Public License (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 NPL, indicate your decision by

+ * deleting the provisions above and replace 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 NPL or the GPL.

+ */

+

+// API class

+

+package com.ebay.internal.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/org.eclipse.vjet.extmod.rhino/plugin.properties b/org.eclipse.vjet.extmod.rhino/plugin.properties
new file mode 100644
index 0000000..241a6b3
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2012 eBay Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     eBay Inc. - initial API and implementation
+###############################################################################
+pluginProvider=Eclipse.org

+pluginName = VJET Plug-in - Modified VRhino (Incubation)
\ No newline at end of file
diff --git a/org.eclipse.vjet.extmod.rhino/pom.xml b/org.eclipse.vjet.extmod.rhino/pom.xml
new file mode 100644
index 0000000..6926402
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+   <modelVersion>4.0.0</modelVersion>

+

+   <parent>

+      <groupId>org.eclipse.vjet.extmod</groupId>

+      <artifactId>org.eclipse.vjet.extmod-parent</artifactId>

+      <version>0.9.0-SNAPSHOT</version>

+   </parent>

+

+   <groupId>org.eclipse.vjet.extmod</groupId>

+   <artifactId>org.eclipse.vjet.extmod.rhino</artifactId>

+   <version>0.9.0-SNAPSHOT</version>

+   <packaging>eclipse-plugin</packaging>

+   <name>VJET: Modified Rhino (Incubation)</name>

+

+</project>
\ No newline at end of file
diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/classfile/ByteCode.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/classfile/ByteCode.java
new file mode 100644
index 0000000..024fe27
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/classfile/ClassFileWriter.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/classfile/ClassFileWriter.java
new file mode 100644
index 0000000..dc58417
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.classfile;

+

+import org.mozilla.mod.javascript.ObjArray;

+import org.mozilla.mod.javascript.ObjToIntMap;

+import org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Arguments.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Arguments.java
new file mode 100644
index 0000000..6ec5d90
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.javascript;

+

+/**

+ * This class implements the "arguments" object.

+ *

+ * See ECMA 10.1.8

+ *

+ * @see org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/BaseFunction.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/BaseFunction.java
new file mode 100644
index 0000000..ad96a3e
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/BaseFunction.java
@@ -0,0 +1,582 @@
+/* -*- 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, 2012

+ * the Initial Developer. All Rights Reserved.

+ *

+ * Contributor(s):

+ *   Norris Boyd

+ *   Igor Bukanov

+ *   Roger Lawrence

+ *   Mike McCabe

+ *

+ * Portions created by eBay are Copyright (c) 2005-2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ * 

+ * 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.mod.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();

+    }

+    

+    //EBAY MOD

+    String compress(int indent, int flags)

+    {

+        StringBuffer sb = new StringBuffer();

+		String FuncName = null;

+        boolean justbody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));

+        if (!justbody) {

+            sb.append("function");

+			FuncName = getFunctionName();

+			if(FuncName.length()>0){

+				sb.append(" "+FuncName);

+			}

+            sb.append("(){");

+        }

+        sb.append("[native code, arity=");

+        sb.append(getArity());

+        sb.append("]");

+        if (!justbody) {

+            sb.append("}");

+        }

+        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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Callable.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Callable.java
new file mode 100644
index 0000000..65cfa5f
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ClassCache.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ClassCache.java
new file mode 100644
index 0000000..4953fa6
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ClassShutter.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ClassShutter.java
new file mode 100644
index 0000000..b12f7ab
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/CompilerEnvirons.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/CompilerEnvirons.java
new file mode 100644
index 0000000..fdbe0b5
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ConstProperties.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ConstProperties.java
new file mode 100644
index 0000000..e30ddb4
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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.mod.javascript.Scriptable#has(String, Scriptable)

+     * @see org.mozilla.mod.javascript.Scriptable#get(String, Scriptable)

+     * @see org.mozilla.mod.javascript.ScriptableObject#putProperty(Scriptable, String, Object)

+     * @see org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Context.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Context.java
new file mode 100644
index 0000000..85da3b0
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Context.java
@@ -0,0 +1,2575 @@
+/* -*- 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, 2012

+ * the Initial Developer. All Rights Reserved.

+ *

+ * Contributor(s):

+ *    Bob Jervis

+ *

+ * Portions created by eBay are Copyright (c) 2005-2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ * 

+ * 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.mod.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.HashMap;

+import java.util.Hashtable;

+import java.util.Locale;

+import java.util.Map;

+

+import org.mozilla.mod.javascript.debug.DebuggableScript;

+import org.mozilla.mod.javascript.debug.Debugger;

+import org.mozilla.mod.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)

+    {

+    	//EBAY MOD

+        // Special workaround for the debugger

+        String DBG = "org.mozilla.mod.javascript.tools.debugger.Main";

+        if (DBG.equals(listener.getClass().getName())) {

+            Class cl = listener.getClass();

+            Class factoryClass = Kit.classOrNull(

+                "org.mozilla.mod.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.mod.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.mod.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.mod.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.mod.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.mod.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.mod.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.mod.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.mod.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.mod.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);

+        Parser p = new Parser(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.mod.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.mod.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.mod.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);

+    }

+    

+    //EBAY MOD

+    public final String compressScript(Script script, int indent)

+    {

+        NativeFunction scriptImpl = (NativeFunction) script;

+        return scriptImpl.compress(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;

+            }

+        }

+

+        Parser p = new Parser(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);

+        }

+    }

+

+    //EBAY MOD

+    private static Class codegenClass = Kit.classOrNull(

+                             "org.mozilla.mod.javascript.optimizer.Codegen");

+    private static Class interpreterClass = Kit.classOrNull(

+                             "org.mozilla.mod.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);

+    }

+

+    //EBAY MOD : static String getSourcePositionFromStack(int[] linep)

+    public 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) {

+        	//EBAY MOD

+            Class cl = Kit.classOrNull(

+                          "org.mozilla.mod.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;

+

+    //EBAY MOD - this is used to turn off/on the jsdoc, function source gathering

+    private boolean createMetaData;

+    

+    /**

+     * 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;

+	

+	//EBAY MOD

+	/**

+	 * @return Returns the createMetaData.

+	 */

+	public boolean isCreateMetaData() {

+		return createMetaData;

+	}

+

+	/**

+	 * @param createMetaData The createMetaData to set.

+	 */

+	public void setCreateMetaData(boolean createMetaData) {

+		this.createMetaData = createMetaData;

+	}	

+	

+	//EBAY MOD

+	public void registerConverter(Class<? extends IJsJavaConvertible> type, IJsJavaConverter converter) {

+		m_ConverterMap.put(type, converter);

+	}

+	

+	public IJsJavaConvertible convert(Scriptable s, Class<? extends IJsJavaConvertible> type) {

+		IJsJavaConverter converter = m_ConverterMap.get(type);

+		if (converter != null) {

+			return converter.convert(s);

+		}

+		return null;

+	}

+	

+	private Map<Class<? extends IJsJavaConvertible>, IJsJavaConverter> m_ConverterMap

+		= new HashMap<Class<? extends IJsJavaConvertible>, IJsJavaConverter>();

+}

diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextAction.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextAction.java
new file mode 100644
index 0000000..47f03f4
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextFactory.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextFactory.java
new file mode 100644
index 0000000..e27f2cd
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextFactory.java
@@ -0,0 +1,601 @@
+/* -*- 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, 2012

+ * the Initial Developer. All Rights Reserved.

+ *

+ * Contributor(s):

+ *   Igor Bukanov, igor@fastmail.fm

+ *

+ * Portions created by eBay are Copyright (c) 2005-2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ * 

+ * 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.mod.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.mod.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.mod.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.

+

+    	//EBAY MOD

+        if (isDom3Present()) {

+            return org.mozilla.mod.javascript.xml.XMLLib.Factory.create(

+                "org.mozilla.mod.javascript.xmlimpl.XMLLibImpl"

+            );

+        } else if (Kit.classOrNull("org.apache.xmlbeans.XmlCursor") != null) {

+            return org.mozilla.mod.javascript.xml.XMLLib.Factory.create(

+                "org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextListener.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ContextListener.java
new file mode 100644
index 0000000..8bfcd2f
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DToA.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DToA.java
new file mode 100644
index 0000000..2e05a95
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Decompiler.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Decompiler.java
new file mode 100644
index 0000000..6022573
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Decompiler.java
@@ -0,0 +1,1674 @@
+/* -*- 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, 2012

+ * the Initial Developer. All Rights Reserved.

+ *

+ * Contributor(s):

+ *   Mike Ang

+ *   Igor Bukanov

+ *   Bob Jervis

+ *   Mike McCabe

+ *

+ * Portions created by eBay are Copyright (c) 2005-2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ * 

+ * 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.mod.javascript;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+

+/**

+ * 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;

+

+    

+    //EBAY MOD

+	private static TokenMapper tm = new TokenMapper();

+    public static String compress(String source, int flags,

+            UintMap properties)

+	{

+		Decompiler.tm = new TokenMapper();

+		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 prevToken = 0;

+		boolean primeFunctionNesting = false;

+		boolean inArgsList = false;

+		boolean primeInArgsList = false;

+		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(' ');

+				result.append("");

+			}

+		} else {

+			if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {

+				result.append('(');

+			}

+		}

+

+		while (i < length) {

+			if (i > 0) {

+				prevToken = source.charAt(i - 1);

+			}

+			// System.out.println(Token.name(getNext(source, length, i)));

+			switch (source.charAt(i)) {

+			case Token.NAME:

+			case Token.REGEXP: // re-wrapped in '/'s in parser...

+				int jumpPos = getSourceStringEnd(source, i + 1);

+				if (Token.OBJECTLIT == source.charAt(jumpPos)) {

+					i = printSourceString(source, i + 1, false, result);

+				} else {

+					i = tm.printCompressed(source, i + 1, false, result,

+							prevToken, inArgsList, braceNesting);

+				}

+				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

+				primeInArgsList = true;

+				primeFunctionNesting = true;

+				result.append("function");

+				if (Token.LP != getNext(source, length, i)) {

+					result.append(' ');

+				}

+				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('{');

+				// // result.append('\n');

+				break;

+

+			case Token.RC: {

+				tm.leaveNestingLevel(braceNesting);

+				--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('\n');

+				result.append('}');

+				// // result.append(' ');

+				switch (getNext(source, length, i)) {

+				case Token.EOL:

+					tm.inVarDeclarationLine(false);

+				case FUNCTION_END:

+					indent -= indentGap;

+					break;

+				case Token.WHILE:

+				case Token.ELSE:

+					indent -= indentGap;

+					// result.append(' ');

+					result.append("");

+					break;

+				}

+				break;

+			}

+			case Token.LP:

+				if (primeInArgsList) {

+					inArgsList = true;

+					primeInArgsList = false;

+				}

+				if (primeFunctionNesting) {

+					tm.enterNestingLevel(braceNesting);

+					primeFunctionNesting = false;

+				}

+				result.append('(');

+				break;

+

+			case Token.RP:

+				if (inArgsList) {

+					inArgsList = false;

+				}

+				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: {

+				tm.inVarDeclarationLine(false);

+				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(' ');

+						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(';');

+				// result.append('\n');

+				/*

+				 * if (Token.EOL != getNext(source, length, i)) { // separators

+				 * in FOR result.append(' '); }

+				 */

+				break;

+

+			case Token.ASSIGN:

+				tm.inVarDeclarationLine(false);

+				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:

+				// FIXME: does this really need leading space?

+				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.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:

+				if (Token.ADD == prevToken) {

+					result.append(' ');

+				}

+				result.append("++");

+				if (Token.ADD == getNext(source, length, i)) {

+					result.append(' ');

+				}

+				break;

+

+			case Token.DEC:

+				if (Token.SUB == prevToken) {

+					result.append(' ');

+				}

+				result.append("--");

+				if (Token.SUB == getNext(source, length, i)) {

+					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.XMLATTR:

+				result.append('@');

+				break;

+

+			default:

+				// If we don't know how to decompile it, raise an exception.

+				throw new RuntimeException();

+			}

+			++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();

+	}

+}

+

+class TokenMapper {

+	private ArrayList functionBracePositions = new ArrayList();

+	private ArrayList scopeReplacedTokens = new ArrayList();

+	private int lastTokenCount = 0;

+	private boolean m_inVarDeclaration;

+

+	// FIXME: this isn't the brightest way to accomplish this. Fristly, we need

+	// to be sure we aren't colliding with other things in the namespace!

+	private String getMappedToken(String token, boolean newMapping){

+		String nt = null;

+		HashMap tokens = (HashMap)scopeReplacedTokens.get(scopeReplacedTokens.size()-1);

+		if(newMapping){

+			lastTokenCount++;

+			nt = new String("_"+Integer.toHexString(lastTokenCount));

+			if(nt.length() >= token.length()){

+				nt = token;

+			}

+			// System.out.println(nt);

+			tokens.put(token, nt);

+			return nt;

+		}

+		if(hasTokenMapping(token)){

+			return getTokenMapping(token);

+		}else{

+			return token;

+		}

+	}

+

+	private boolean hasLocalTokenMapping(String token){

+		if(scopeReplacedTokens.size()<1){

+			return false;

+		}

+		HashMap tokens = (HashMap)(scopeReplacedTokens.get(scopeReplacedTokens.size()-1));

+		if(tokens.containsKey(token)){

+			return true;

+		}

+		return false;

+	}

+

+	private boolean hasTokenMapping(String token){

+		String blank = new String("");

+		if(blank.equals(getTokenMapping(token))){

+			return false;

+		}

+		return true;

+	}

+

+	private String getTokenMapping(String token){

+		for(int i=scopeReplacedTokens.size()-1; i>=0; i--){

+			HashMap tokens = (HashMap)(scopeReplacedTokens.get(i));

+			if(tokens.containsKey(token)){

+				return (String)tokens.get(token);

+			}

+		}

+		return new String("");

+	}

+

+	public int printCompressed(String 		source, 

+								int 		offset,

+								boolean 	asQuotedString,

+								StringBuffer sb, 

+								int 		prevToken, 

+								boolean 	inArgsList, 

+								int 		currentLevel){

+		boolean newMapping = false;

+		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);

+			String sourceStr = new String(str);

+			

+			

+			if((prevToken== Token.SEMI || prevToken == Token.EOL || prevToken == Token.EQ) && isInVarDeclarationLine()){

+				inVarDeclarationLine(false);

+			}

+			

+			if(((prevToken == Token.COMMA  && isInVarDeclarationLine())&&(!hasLocalTokenMapping(sourceStr)))||(inArgsList)){

+				newMapping = true;

+			}

+			

+			if(((prevToken == Token.VAR)&&(!hasLocalTokenMapping(sourceStr)))||(inArgsList)){

+				newMapping = true;

+				inVarDeclarationLine(true);

+			}

+

+

+			if(((functionBracePositions.size()>0)&&(currentLevel>=(((Integer)functionBracePositions.get(functionBracePositions.size()-1)).intValue())))||(inArgsList)){

+				if(prevToken != Token.DOT){

+					str = this.getMappedToken(str, newMapping);

+				}

+			}

+			if((!inArgsList)&&(asQuotedString)){

+				if((prevToken == Token.LC)||(prevToken == Token.COMMA)){

+					str = sourceStr;

+				}

+			}

+

+			if(!asQuotedString){

+				sb.append(str);

+			}else{

+				sb.append('"');

+				sb.append(ScriptRuntime.escapeString(str));

+				sb.append('"');

+			}

+		}

+

+		return offset + length;

+	}

+

+	void inVarDeclarationLine(boolean b) {

+		m_inVarDeclaration = b;

+	}

+	private boolean isInVarDeclarationLine() {

+		return m_inVarDeclaration;

+	}

+

+	public void enterNestingLevel(int braceNesting){

+		functionBracePositions.add(new Integer(braceNesting+1));

+		scopeReplacedTokens.add(new HashMap());

+	}

+

+	public void leaveNestingLevel(int braceNesting){

+		Integer bn = new Integer(braceNesting);

+		if((functionBracePositions.contains(bn))&&(scopeReplacedTokens.size()>0)){

+			// remove our mappings now!

+			int scopedSize = scopeReplacedTokens.size();

+			/*

+			HashMap tokens = (HashMap)(scopeReplacedTokens.get(scopedSize-1));

+			Iterator titer = (tokens.keySet()).iterator();

+			String key = null;

+			while(titer.hasNext()){

+				key = (String)titer.next();

+				// System.out.println("removing: "+key);

+				tokenMappings.remove(key);

+			}

+			*/

+			scopeReplacedTokens.remove(scopedSize-1);

+			functionBracePositions.remove(bn);

+		}

+	}

+}

diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DefaultErrorReporter.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DefaultErrorReporter.java
new file mode 100644
index 0000000..7a1f9dd
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DefiningClassLoader.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/DefiningClassLoader.java
new file mode 100644
index 0000000..6bf799a
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Delegator.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Delegator.java
new file mode 100644
index 0000000..ef62ad6
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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.mod.javascript.Delegator#construct

+     */

+    public Delegator() {

+    }

+

+    /**

+     * Create a new Delegator that forwards requests to a delegee

+     * Scriptable object.

+     *

+     * @param obj the delegee

+     * @see org.mozilla.mod.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.mod.javascript.Scriptable

+     */

+    public void setDelegee(Scriptable obj) {

+        this.obj = obj;

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#getClassName

+     */

+    public String getClassName() {

+        return obj.getClassName();

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#get(String, Scriptable)

+     */

+    public Object get(String name, Scriptable start) {

+        return obj.get(name,start);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#get(int, Scriptable)

+     */

+    public Object get(int index, Scriptable start) {

+        return obj.get(index,start);

+        }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#has(String, Scriptable)

+     */

+    public boolean has(String name, Scriptable start) {

+        return obj.has(name,start);

+        }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#has(int, Scriptable)

+     */

+    public boolean has(int index, Scriptable start) {

+        return obj.has(index,start);

+        }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#put(String, Scriptable, Object)

+     */

+    public void put(String name, Scriptable start, Object value) {

+        obj.put(name,start,value);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#put(int, Scriptable, Object)

+     */

+    public void put(int index, Scriptable start, Object value) {

+        obj.put(index,start,value);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#delete(String)

+     */

+    public void delete(String name) {

+        obj.delete(name);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#delete(int)

+     */

+    public void delete(int index) {

+        obj.delete(index);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#getPrototype

+     */

+    public Scriptable getPrototype() {

+        return obj.getPrototype();

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#setPrototype

+     */

+    public void setPrototype(Scriptable prototype) {

+        obj.setPrototype(prototype);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#getParentScope

+     */

+    public Scriptable getParentScope() {

+        return obj.getParentScope();

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#setParentScope

+     */

+    public void setParentScope(Scriptable parent) {

+        obj.setParentScope(parent);

+    }

+    /**

+     * @see org.mozilla.mod.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.mod.javascript.Scriptable#getDefaultValue

+     */

+    public Object getDefaultValue(Class hint) {

+        return (hint == null ||

+                hint == ScriptRuntime.ScriptableClass ||

+                hint == ScriptRuntime.FunctionClass) ?

+            this : obj.getDefaultValue(hint);

+    }

+    /**

+     * @see org.mozilla.mod.javascript.Scriptable#hasInstance

+     */

+    public boolean hasInstance(Scriptable instance) {

+        return obj.hasInstance(instance);

+    }

+    /**

+     * @see org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/EcmaError.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/EcmaError.java
new file mode 100644
index 0000000..b3724e0
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ErrorReporter.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/ErrorReporter.java
new file mode 100644
index 0000000..f988d7e
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Evaluator.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Evaluator.java
new file mode 100644
index 0000000..894dcc1
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/EvaluatorException.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/EvaluatorException.java
new file mode 100644
index 0000000..c62e4a9
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Function.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/Function.java
new file mode 100644
index 0000000..183dcb7
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.javascript;

+

+/**

+ * This is interface that all functions in JavaScript must implement.

+ * The interface provides for calling functions and constructors.

+ *

+ * @see org.mozilla.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/FunctionNode.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/FunctionNode.java
new file mode 100644
index 0000000..5544f38
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/FunctionObject.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/FunctionObject.java
new file mode 100644
index 0000000..5c5611b
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/FunctionObject.java
@@ -0,0 +1,587 @@
+/* -*- 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, 2012

+ * the Initial Developer. All Rights Reserved.

+ *

+ * Contributor(s):

+ *   Norris Boyd

+ *   Igor Bukanov

+ *   David C. Navas

+ *   Ted Neward

+ *

+ * Portions created by eBay are Copyright (c) 2005-2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ *

+ * 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.mod.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.mod.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;

+        // EBAY MOD

+        if (ScriptRuntime.WillBeScriptableClass.isAssignableFrom(type))

+            return JAVA_WILL_BE_SCRIPTABLE_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));

+            // EBAY MOD - begin

+          case JAVA_WILL_BE_SCRIPTABLE_TYPE: // here is the moment of truth

+        	// EBAY MOD - end

+          case JAVA_SCRIPTABLE_TYPE:

+            if (arg instanceof Scriptable)

+                return arg;

+			// EBAY MOD - begin

+			if(arg==null)

+				return null;

+			// EBAY MOD - end

+			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.mod.javascript.Scriptable#setParentScope

+     * @see org.mozilla.mod.javascript.Scriptable#setPrototype

+     * @see org.mozilla.mod.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.mod.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;

+    // EBAY MOD

+    public static final int JAVA_WILL_BE_SCRIPTABLE_TYPE = 7;

+

+    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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/GeneratedClassLoader.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/GeneratedClassLoader.java
new file mode 100644
index 0000000..2bf60cc
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConverter.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConverter.java
new file mode 100644
index 0000000..5fc6cfc
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConverter.java
@@ -0,0 +1,43 @@
+/* -*- 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.

+ * 

+ * Portions created by eBay are Copyright (c) 2005, 2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ *

+ * 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.mod.javascript;

+

+/**

+ * A interface for custom data type converter to convert

+ * native js object to typed java object

+ * 

+ * an eBay extension to Rhino - EBAY MOD

+ */

+public interface IJsJavaConverter {

+	

+	IJsJavaConvertible convert(Scriptable s);

+

+}

diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConvertible.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConvertible.java
new file mode 100644
index 0000000..1e5cc6d
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaConvertible.java
@@ -0,0 +1,41 @@
+/* -*- 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.

+ *

+ * Portions created by eBay are Copyright (c) 2005, 2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ * 

+ * 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.mod.javascript;

+

+/**

+ * A tag interface to indicate a java type which could

+ * be converted from native js via customized converter

+ * 

+ * an eBay extension to Rhino - EBAY MOD

+ */

+public interface IJsJavaConvertible {

+

+}

diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaProxy.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaProxy.java
new file mode 100644
index 0000000..0e54fd6
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IJsJavaProxy.java
@@ -0,0 +1,44 @@
+/* -*- 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.

+ *

+ * Portions created by eBay are Copyright (c) 2005, 2012 eBay Inc. All rights reserved.

+ * 

+ * Contributor(s):

+ *   Yitao Yao

+ *   Justin Early

+ *

+ * 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.mod.javascript;

+

+/**

+ * Java Proxy for Native JavaScript Object

+ * 

+ * an eBay extension to Rhino - EBAY MOD

+ */

+public interface IJsJavaProxy {

+	

+	String JS_JAVA_PROXY = "_js_java_proxy";

+	

+	Scriptable getJsNative();

+

+}

diff --git a/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IRFactory.java b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/javascript/IRFactory.java
new file mode 100644
index 0000000..7c9b583
--- /dev/null
+++ b/org.eclipse.vjet.extmod.rhino/src/org/mozilla/mod/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, 2012

+ * 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.mod.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));