2003/05/12 05:31:49
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:00:28 +0000 (07:00 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:00:28 +0000 (07:00 +0000)
darcs-hash:20040130070028-2ba56-f4e73bb4a8614ff8b8a2102785ed315fd3a69689.gz

src/org/mozilla/javascript/debug/DebugFrame.java [deleted file]
src/org/mozilla/javascript/debug/DebugReader.java [deleted file]
src/org/mozilla/javascript/debug/DebuggableEngine.java [deleted file]
src/org/mozilla/javascript/debug/DebuggableScript.java [deleted file]
src/org/mozilla/javascript/debug/Debugger.java [deleted file]
src/org/mozilla/javascript/regexp/NativeRegExp.java [deleted file]
src/org/mozilla/javascript/regexp/NativeRegExpCtor.java [deleted file]
src/org/mozilla/javascript/regexp/RegExpImpl.java [deleted file]
src/org/mozilla/javascript/regexp/SubString.java [deleted file]
src/org/xwt/Box.java

diff --git a/src/org/mozilla/javascript/debug/DebugFrame.java b/src/org/mozilla/javascript/debug/DebugFrame.java
deleted file mode 100644 (file)
index 5f7687c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1999.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- * Norris Boyd\r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-// API class\r
-\r
-package org.mozilla.javascript.debug;\r
-\r
-import org.mozilla.javascript.*;\r
-\r
-public interface DebugFrame {\r
-\r
-    public Scriptable getVariableObject();\r
-    \r
-    public String getSourceName();\r
-    \r
-    public int getLineNumber();\r
-    \r
-    public DebuggableScript getScript();\r
-}\r
diff --git a/src/org/mozilla/javascript/debug/DebugReader.java b/src/org/mozilla/javascript/debug/DebugReader.java
deleted file mode 100644 (file)
index e88e46a..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1998.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-package org.mozilla.javascript.debug;\r
-\r
-import java.io.*;\r
-\r
-public class DebugReader extends Reader {\r
-\r
-    public DebugReader(Reader reader) {\r
-        this.reader = new BufferedReader(reader);  \r
-        this.saved = new StringBuffer();\r
-    }\r
-    \r
-    public StringBuffer getSaved() {\r
-        return saved;\r
-    }\r
-\r
-    public int read() throws IOException {\r
-        int c = reader.read();\r
-        if (c != -1)\r
-            saved.append((char)c);\r
-        return c;\r
-    }\r
-\r
-    public int read(char cbuf[]) throws IOException {\r
-        int i = reader.read(cbuf);\r
-        if (i != -1) \r
-            saved.append(cbuf, 0, i);\r
-        return i;\r
-    }\r
-\r
-    public int read(char cbuf[], int off, int len) throws IOException {\r
-        int i = reader.read(cbuf, off, len);\r
-        if (i > 0) \r
-            saved.append(cbuf, off, i);\r
-        return i;\r
-    }\r
-\r
-    public long skip(long n) throws IOException {\r
-        return reader.skip(n);\r
-    }\r
-\r
-    public boolean ready() throws IOException {\r
-        return reader.ready();\r
-    }\r
-\r
-    public boolean markSupported() {\r
-        return reader.markSupported();\r
-    }\r
-\r
-    public void mark(int readAheadLimit) throws IOException {\r
-        reader.mark(readAheadLimit);\r
-    }\r
-\r
-    public void reset() throws IOException {\r
-        reader.reset();\r
-    }\r
-\r
-    public void close() throws IOException {\r
-        reader.close();\r
-    }\r
-\r
-    protected void finalize() throws Throwable {\r
-        reader = null;    \r
-    }\r
-    \r
-    private BufferedReader reader;\r
-    private StringBuffer saved;\r
-}\r
diff --git a/src/org/mozilla/javascript/debug/DebuggableEngine.java b/src/org/mozilla/javascript/debug/DebuggableEngine.java
deleted file mode 100644 (file)
index 351cd8a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1999.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- * Norris Boyd\r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-// API class\r
-\r
-package org.mozilla.javascript.debug;\r
-\r
-\r
-public interface DebuggableEngine {\r
-\r
-    /**\r
-     * Set whether the engine should break when it encounters\r
-     * the next line.\r
-     * <p>\r
-     * The engine will call the attached debugger's handleBreakpointHit\r
-     * method on the next line it executes if isLineStep is true.\r
-     * May be used from another thread to interrupt execution.\r
-     * \r
-     * @param isLineStep if true, break next line\r
-     */\r
-    public void setBreakNextLine(boolean isLineStep);\r
-    \r
-    /**\r
-     * Return the value of the breakNextLine flag.\r
-     * @return true if the engine will break on execution of the \r
-     * next line.\r
-     */\r
-    public boolean getBreakNextLine();\r
-    \r
-    /**\r
-     * Set the associated debugger.\r
-     * @param debugger the debugger to be used on callbacks from\r
-     * the engine.\r
-     */\r
-    public void setDebugger(Debugger debugger);\r
-    \r
-    /**\r
-     * Return the current debugger.\r
-     * @return the debugger, or null if none is attached.\r
-     */\r
-    public Debugger getDebugger();\r
-    \r
-    /**\r
-     * Return the number of frames in current execution.\r
-     * @return the count of current frames\r
-     */\r
-    public int getFrameCount();\r
-    \r
-    /**\r
-     * Return a frame from the current execution.\r
-     * Frames are numbered starting from 0 for the innermost\r
-     * frame.\r
-     * @param frameNumber the number of the frame in the range\r
-     *        [0,frameCount-1]\r
-     * @return the relevant Frame, or null if frameNumber is out\r
-     *         of range or the engine isn't currently saving \r
-     *         frames\r
-     */\r
-    public DebugFrame getFrame(int frameNumber);\r
-}\r
diff --git a/src/org/mozilla/javascript/debug/DebuggableScript.java b/src/org/mozilla/javascript/debug/DebuggableScript.java
deleted file mode 100644 (file)
index ff26115..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1999.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- * Norris Boyd\r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-// API class\r
-\r
-package org.mozilla.javascript.debug;\r
-\r
-import org.mozilla.javascript.*;\r
-\r
-import java.util.Enumeration;\r
-\r
-/**\r
- * This interface exposes debugging information from executable \r
- * code (either functions or top-level scripts).\r
- */\r
-public interface DebuggableScript {\r
-  \r
-    /**\r
-     * Returns true if this is a function, false if it is a script.\r
-     */\r
-    public boolean isFunction();\r
-    \r
-    /**\r
-     * Get the Scriptable object (Function or Script) that is \r
-     * described by this DebuggableScript object.\r
-     */\r
-    public Scriptable getScriptable();\r
-\r
-    /**\r
-     * Get the name of the source (usually filename or URL)\r
-     * of the script.\r
-     */\r
-    public String getSourceName();\r
-    \r
-    /**\r
-     * Get array containing the line numbers that \r
-     * can have breakpoints placed on them.\r
-     */\r
-    public int[] getLineNumbers();\r
-    \r
-    /**\r
-     * Place a breakpoint at the given line.\r
-     * @return true if the breakpoint was successfully set.\r
-     */\r
-    public boolean placeBreakpoint(int line);\r
-    \r
-    /**\r
-     * Remove a breakpoint from the given line.\r
-     * @return true if there was a breakpoint at the given line.\r
-     */\r
-    public boolean removeBreakpoint(int line);\r
-}\r
diff --git a/src/org/mozilla/javascript/debug/Debugger.java b/src/org/mozilla/javascript/debug/Debugger.java
deleted file mode 100644 (file)
index bb0febb..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1999.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-2000 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- * Norris Boyd\r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-// API class\r
-\r
-package org.mozilla.javascript.debug;\r
-\r
-import org.mozilla.javascript.Context;\r
-\r
-public interface Debugger {\r
-    \r
-    void handleCompilationDone(Context cx, DebuggableScript fnOrScript, \r
-                               StringBuffer source);\r
-\r
-    void handleBreakpointHit(Context cx);\r
-    \r
-    void handleExceptionThrown(Context cx, Object exception);\r
-    \r
-}\r
diff --git a/src/org/mozilla/javascript/regexp/NativeRegExp.java b/src/org/mozilla/javascript/regexp/NativeRegExp.java
deleted file mode 100644 (file)
index d8b6337..0000000
+++ /dev/null
@@ -1,2502 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1998.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- * Norris Boyd\r
- * Brendan Eich\r
- * Matthias Radestock\r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-package org.mozilla.javascript.regexp;\r
-\r
-import org.mozilla.javascript.*;\r
-import java.lang.reflect.Method;\r
-\r
-/**\r
- * This class implements the RegExp native object.\r
- *\r
- * Revision History:\r
- * Implementation in C by Brendan Eich\r
- * Initial port to Java by Norris Boyd from jsregexp.c version 1.36\r
- * Merged up to version 1.38, which included Unicode support.\r
- * Merged bug fixes in version 1.39.\r
- * Merged JSFUN13_BRANCH changes up to 1.32.2.13\r
- *\r
- * @author Brendan Eich\r
- * @author Norris Boyd\r
- */\r
-public class NativeRegExp extends IdScriptable implements Function {\r
-\r
-    public static final int GLOB = 0x1;       // 'g' flag: global\r
-    public static final int FOLD = 0x2;       // 'i' flag: fold\r
-    public static final int MULTILINE = 0x4;  // 'm' flag: multiline\r
-\r
-    //type of match to perform\r
-    public static final int TEST = 0;\r
-    public static final int MATCH = 1;\r
-    public static final int PREFIX = 2;\r
-\r
-    private static final boolean debug = false;\r
-\r
-    public static void init(Context cx, Scriptable scope, boolean sealed) {\r
-        \r
-        NativeRegExp proto = new NativeRegExp();\r
-        proto.prototypeFlag = true;\r
-        proto.activateIdMap(MAX_PROTOTYPE_ID);\r
-        proto.setSealFunctionsFlag(sealed);\r
-        proto.setFunctionParametrs(cx);\r
-        proto.setParentScope(scope);\r
-        proto.setPrototype(getObjectPrototype(scope));\r
-\r
-\r
-        NativeRegExpCtor ctor = new NativeRegExpCtor();\r
-\r
-        ctor.setPrototype(getClassPrototype(scope, "Function"));\r
-        ctor.setParentScope(scope);\r
-\r
-        ctor.setImmunePrototypeProperty(proto);\r
-        \r
-        if (sealed) {\r
-            proto.sealObject();\r
-            ctor.sealObject();\r
-        }\r
-\r
-        defineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM);\r
-    }\r
-\r
-    public NativeRegExp(Context cx, Scriptable scope, String source, \r
-                        String global, boolean flat) {\r
-        init(cx, scope, source, global, flat);\r
-    }\r
-\r
-    public void init(Context cx, Scriptable scope, String source, \r
-                     String global, boolean flat) {\r
-        this.source = source;\r
-        flags = 0;\r
-        if (global != null) {\r
-            for (int i=0; i < global.length(); i++) {\r
-                char c = global.charAt(i);\r
-                if (c == 'g') {\r
-                    flags |= GLOB;\r
-                } else if (c == 'i') {\r
-                    flags |= FOLD;\r
-                } else if (c == 'm') {\r
-                    flags |= MULTILINE;\r
-                } else {\r
-                    Object[] errArgs = { new Character(c) };\r
-                    throw NativeGlobal.constructError(cx, "SyntaxError",\r
-                                                      ScriptRuntime.getMessage(\r
-                                                                               "msg.invalid.re.flag", errArgs),\r
-                                                      scope);\r
-                }\r
-            }\r
-        }\r
-\r
-        CompilerState state = new CompilerState(source, flags, cx, scope);\r
-        if (flat) {\r
-            ren = null;\r
-            int sourceLen = source.length();\r
-            int index = 0;\r
-            while (sourceLen > 0) {\r
-                int len = sourceLen;\r
-                if (len > REOP_FLATLEN_MAX) {\r
-                    len = REOP_FLATLEN_MAX;\r
-                }\r
-                RENode ren2 = new RENode(state, len == 1 ? REOP_FLAT1 : REOP_FLAT,\r
-                                         new Integer(index));                                 \r
-                ren2.flags = RENode.NONEMPTY;\r
-                if (len > 1) {\r
-                    ren2.kid2 = index + len;\r
-                } else {\r
-                    ren2.flags |= RENode.SINGLE;\r
-                    ren2.chr = state.source[index];                    \r
-                }\r
-                index += len;\r
-                sourceLen -= len;\r
-                if (ren == null)\r
-                    ren = ren2;\r
-                else\r
-                    setNext(state, ren, ren2);\r
-            }\r
-        }\r
-        else\r
-            this.ren = parseRegExp(state);\r
-        if (ren == null) return;\r
-        RENode end = new RENode(state, REOP_END, null);\r
-        setNext(state, ren, end);\r
-        if (debug)\r
-            dumpRegExp(state, ren);\r
-        this.lastIndex = 0;\r
-        this.parenCount = state.parenCount;\r
-        this.flags = flags;\r
-\r
-        scope = org.xwt.util.JSObject.defaultObjects;\r
-        setPrototype(getClassPrototype(scope, "RegExp"));\r
-        setParentScope(scope);\r
-    }\r
-\r
-    public String getClassName() {\r
-        return "RegExp";\r
-    }\r
-\r
-    public Object call(Context cx, Scriptable scope, Scriptable thisObj,\r
-                       Object[] args) {\r
-        return execSub(cx, scope, args, MATCH);\r
-    }\r
-\r
-    public Scriptable construct(Context cx, Scriptable scope, Object[] args) {\r
-        return (Scriptable) call(cx, scope, null, args);\r
-    }\r
-\r
-    Scriptable compile(Context cx, Scriptable scope, Object[] args) {\r
-        if (args.length > 0 && args[0] instanceof NativeRegExp) {\r
-            if (args.length > 1 && args[1] != Undefined.instance) {\r
-                // report error\r
-                throw NativeGlobal.constructError(\r
-                                                  cx, "TypeError",\r
-                                                  "only one argument may be specified " +\r
-                                                  "if the first argument is a RegExp object",\r
-                                                  scope);\r
-            }\r
-            NativeRegExp thatObj = (NativeRegExp) args[0];\r
-            source = thatObj.source; \r
-            lastIndex = thatObj.lastIndex;\r
-            parenCount = thatObj.parenCount;\r
-            flags = thatObj.flags;\r
-            program = thatObj.program;\r
-            ren = thatObj.ren;\r
-            return this;\r
-        }\r
-        String s = args.length == 0 ? "" : ScriptRuntime.toString(args[0]);\r
-        String global = args.length > 1 && args[1] != Undefined.instance\r
-            ? ScriptRuntime.toString(args[1])\r
-            : null;\r
-        init(cx, scope, s, global, false);\r
-        return this;\r
-    }\r
-\r
-    public String toString() {\r
-        StringBuffer buf = new StringBuffer();\r
-        buf.append('/');\r
-        buf.append(source);\r
-        buf.append('/');\r
-        if ((flags & GLOB) != 0)\r
-            buf.append('g');\r
-        if ((flags & FOLD) != 0)\r
-            buf.append('i');\r
-        if ((flags & MULTILINE) != 0)\r
-            buf.append('m');\r
-        return buf.toString();\r
-    }\r
-\r
-    public NativeRegExp() {\r
-    }\r
-    \r
-    private static RegExpImpl getImpl(Context cx) {\r
-        return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);\r
-    }\r
-\r
-    private Object execSub(Context cx, Scriptable scopeObj,\r
-                           Object[] args, int matchType)\r
-    {\r
-        RegExpImpl reImpl = getImpl(cx);\r
-        String str;\r
-        if (args.length == 0) {\r
-            str = reImpl.input;\r
-            if (str == null) {\r
-                Object[] errArgs = { toString() };\r
-                throw NativeGlobal.constructError(\r
-                                                  cx, "SyntaxError",\r
-                                                  ScriptRuntime.getMessage\r
-                                                  ("msg.no.re.input.for", errArgs),\r
-                                                  scopeObj);\r
-            }\r
-        } else {\r
-            str = ScriptRuntime.toString(args[0]);\r
-        }\r
-        int i = ((flags & GLOB) != 0) ? lastIndex : 0;\r
-        int indexp[] = { i };\r
-        Object rval = executeRegExp(cx, scopeObj, \r
-                                    reImpl, str, indexp, matchType);\r
-        if ((flags & GLOB) != 0) {\r
-            lastIndex = (rval == null || rval == Undefined.instance) \r
-                        ? 0 : indexp[0];\r
-        }\r
-        return rval;\r
-    }\r
-\r
-    private Object exec(Context cx, Scriptable scopeObj, Object[] args) {\r
-        return execSub(cx, scopeObj, args, MATCH);\r
-    }\r
-\r
-    private Object test(Context cx, Scriptable scopeObj, Object[] args) {\r
-        Object rval = execSub(cx, scopeObj, args, TEST);\r
-        if (rval == null || !rval.equals(Boolean.TRUE))\r
-            rval = Boolean.FALSE;\r
-        return rval;\r
-    }\r
-\r
-    private Object prefix(Context cx, Scriptable scopeObj, Object[] args) {\r
-        return execSub(cx, scopeObj, args, PREFIX);\r
-    }\r
-\r
-    static final int JS_BITS_PER_BYTE = 8;\r
-\r
-    private static final byte REOP_EMPTY      = 0;  /* match rest of input against rest of r.e. */\r
-    private static final byte REOP_ALT        = 1;  /* alternative subexpressions in kid and next */\r
-    private static final byte REOP_BOL        = 2;  /* beginning of input (or line if multiline) */\r
-    private static final byte REOP_EOL        = 3;  /* end of input (or line if multiline) */\r
-    private static final byte REOP_WBDRY      = 4;  /* match "" at word boundary */\r
-    private static final byte REOP_WNONBDRY   = 5;  /* match "" at word non-boundary */\r
-    private static final byte REOP_QUANT      = 6;  /* quantified atom: atom{1,2} */\r
-    private static final byte REOP_STAR       = 7;  /* zero or more occurrences of kid */\r
-    private static final byte REOP_PLUS       = 8;  /* one or more occurrences of kid */\r
-    private static final byte REOP_OPT        = 9;  /* optional subexpression in kid */\r
-    private static final byte REOP_LPAREN     = 10; /* left paren bytecode: kid is u.num'th sub-regexp */\r
-    private static final byte REOP_RPAREN     = 11; /* right paren bytecode */\r
-    private static final byte REOP_DOT        = 12; /* stands for any character */\r
-    private static final byte REOP_CCLASS     = 13; /* character class: [a-f] */\r
-    private static final byte REOP_DIGIT      = 14; /* match a digit char: [0-9] */\r
-    private static final byte REOP_NONDIGIT   = 15; /* match a non-digit char: [^0-9] */\r
-    private static final byte REOP_ALNUM      = 16; /* match an alphanumeric char: [0-9a-z_A-Z] */\r
-    private static final byte REOP_NONALNUM   = 17; /* match a non-alphanumeric char: [^0-9a-z_A-Z] */\r
-    private static final byte REOP_SPACE      = 18; /* match a whitespace char */\r
-    private static final byte REOP_NONSPACE   = 19; /* match a non-whitespace char */\r
-    private static final byte REOP_BACKREF    = 20; /* back-reference (e.g., \1) to a parenthetical */\r
-    private static final byte REOP_FLAT       = 21; /* match a flat string */\r
-    private static final byte REOP_FLAT1      = 22; /* match a single char */\r
-    private static final byte REOP_JUMP       = 23; /* for deoptimized closure loops */\r
-    private static final byte REOP_DOTSTAR    = 24; /* optimize .* to use a single opcode */\r
-    private static final byte REOP_ANCHOR     = 25; /* like .* but skips left context to unanchored r.e. */\r
-    private static final byte REOP_EOLONLY    = 26; /* $ not preceded by any pattern */\r
-    private static final byte REOP_UCFLAT     = 27; /* flat Unicode string; len immediate counts chars */\r
-    private static final byte REOP_UCFLAT1    = 28; /* single Unicode char */\r
-    private static final byte REOP_UCCLASS    = 29; /* Unicode character class, vector of chars to match */\r
-    private static final byte REOP_NUCCLASS   = 30; /* negated Unicode character class */\r
-    private static final byte REOP_BACKREFi   = 31; /* case-independent REOP_BACKREF */\r
-    private static final byte REOP_FLATi      = 32; /* case-independent REOP_FLAT */\r
-    private static final byte REOP_FLAT1i     = 33; /* case-independent REOP_FLAT1 */\r
-    private static final byte REOP_UCFLATi    = 34; /* case-independent REOP_UCFLAT */\r
-    private static final byte REOP_UCFLAT1i   = 35; /* case-independent REOP_UCFLAT1 */\r
-    private static final byte REOP_ANCHOR1    = 36; /* first-char discriminating REOP_ANCHOR */\r
-    private static final byte REOP_NCCLASS    = 37; /* negated 8-bit character class */\r
-    private static final byte REOP_DOTSTARMIN = 38; /* ungreedy version of REOP_DOTSTAR */\r
-    private static final byte REOP_LPARENNON  = 39; /* non-capturing version of REOP_LPAREN */\r
-    private static final byte REOP_RPARENNON  = 40; /* non-capturing version of REOP_RPAREN */\r
-    private static final byte REOP_ASSERT     = 41; /* zero width positive lookahead assertion */\r
-    private static final byte REOP_ASSERT_NOT = 42; /* zero width negative lookahead assertion */\r
-    private static final byte REOP_END        = 43;\r
-\r
-    /* maximum length of FLAT string */\r
-    private static final int REOP_FLATLEN_MAX = 255;\r
-\r
-    /* not thread safe, used only for debugging */\r
-    private static int level;\r
-\r
-    private static String[] reopname = null;\r
-    static {\r
-        if (debug) {\r
-            String a[] = {\r
-                "empty",\r
-                "alt",\r
-                "bol",\r
-                "eol",\r
-                "wbdry",\r
-                "wnonbdry",\r
-                "quant",\r
-                "star",\r
-                "plus",\r
-                "opt",\r
-                "lparen",\r
-                "rparen",\r
-                "dot",\r
-                "cclass",\r
-                "digit",\r
-                "nondigit",\r
-                "alnum",\r
-                "nonalnum",\r
-                "space",\r
-                "nonspace",\r
-                "backref",\r
-                "flat",\r
-                "flat1",\r
-                "jump",\r
-                "dotstar",\r
-                "anchor",\r
-                "eolonly",\r
-                "ucflat",\r
-                "ucflat1",\r
-                "ucclass",\r
-                "nucclass",\r
-                "backrefi",\r
-                "flati",\r
-                "flat1i",\r
-                "ucflati",\r
-                "ucflat1i",\r
-                "anchor1",\r
-                "ncclass",\r
-                "dotstar_min",\r
-                "lparen_non",\r
-                "rparen_non",\r
-                "end"\r
-            };\r
-            reopname = a;\r
-        }\r
-    }\r
-\r
-    private String getPrintableString(String str) {\r
-        if (debug) {\r
-            StringBuffer buf = new StringBuffer(str.length());\r
-            for (int i = 0; i < str.length(); i++) {\r
-                int c = str.charAt(i);\r
-                if ((c < 0x20) || (c > 0x7F)) {\r
-                    if (c == '\n')\r
-                        buf.append("\\n");\r
-                    else\r
-                        buf.append("\\u" + Integer.toHexString(c));\r
-                }\r
-                else\r
-                    buf.append((char)c);\r
-            }\r
-            return buf.toString();\r
-        } else {\r
-            return "";\r
-        }\r
-    }\r
-\r
-    private void dumpRegExp(CompilerState state, RENode ren) {\r
-        if (debug) {\r
-            if (level == 0)\r
-                System.out.print("level offset  flags  description\n");\r
-            level++;\r
-            do {\r
-                char[] source = ren.s != null ? ren.s : state.source;\r
-                System.out.print(level);\r
-                System.out.print(" ");\r
-                System.out.print(ren.offset);\r
-                System.out.print(" " +\r
-                                 ((ren.flags & RENode.ANCHORED) != 0 ? "A" : "-") +\r
-                                 ((ren.flags & RENode.SINGLE)   != 0 ? "S" : "-") +\r
-                                 ((ren.flags & RENode.NONEMPTY) != 0 ? "F" : "-") + // F for full\r
-                                 ((ren.flags & RENode.ISNEXT)   != 0 ? "N" : "-") + // N for next\r
-                                 ((ren.flags & RENode.GOODNEXT) != 0 ? "G" : "-") +\r
-                                 ((ren.flags & RENode.ISJOIN)   != 0 ? "J" : "-") +\r
-                                 ((ren.flags & RENode.MINIMAL)  != 0 ? "M" : "-") +\r
-                                 "  " +\r
-                                 reopname[ren.op]);\r
-\r
-                switch (ren.op) {\r
-                case REOP_ALT:\r
-                    System.out.print(" ");\r
-                    System.out.println(ren.next.offset);\r
-                    dumpRegExp(state, (RENode) ren.kid);\r
-                    break;\r
-\r
-                case REOP_STAR:\r
-                case REOP_PLUS:\r
-                case REOP_OPT:\r
-                case REOP_ANCHOR1:\r
-                case REOP_ASSERT:\r
-                case REOP_ASSERT_NOT:\r
-                    System.out.println();\r
-                    dumpRegExp(state, (RENode) ren.kid);\r
-                    break;\r
-\r
-                case REOP_QUANT:\r
-                    System.out.print(" next ");\r
-                    System.out.print(ren.next.offset);\r
-                    System.out.print(" min ");\r
-                    System.out.print(ren.min);\r
-                    System.out.print(" max ");\r
-                    System.out.println(ren.max);\r
-                    dumpRegExp(state, (RENode) ren.kid);\r
-                    break;\r
-\r
-                case REOP_LPAREN:\r
-                    System.out.print(" num ");\r
-                    System.out.println(ren.num);\r
-                    dumpRegExp(state, (RENode) ren.kid);\r
-                    break;\r
-\r
-                case REOP_LPARENNON:\r
-                    System.out.println();\r
-                    dumpRegExp(state, (RENode) ren.kid);\r
-                   break;\r
-\r
-                case REOP_BACKREF:\r
-                case REOP_RPAREN:\r
-                    System.out.print(" num ");\r
-                    System.out.println(ren.num);\r
-                    break;\r
-\r
-                case REOP_CCLASS: {\r
-                    int index = ((Integer) ren.kid).intValue();\r
-                    int index2 = ren.kid2;\r
-                    int len = index2 - index;\r
-                    System.out.print(" [");\r
-                    System.out.print(getPrintableString(new String(source, index, len)));\r
-                    System.out.println("]");\r
-                    break;\r
-                    }\r
-\r
-                case REOP_FLAT: {\r
-                    int index = ((Integer) ren.kid).intValue();\r
-                    int index2 = ren.kid2;\r
-                    int len = index2 - index;\r
-                    System.out.print(" ");\r
-                    System.out.print(getPrintableString(new String(source, index, len)));\r
-                    System.out.print(" (");\r
-                    System.out.print(len);\r
-                    System.out.println(")");\r
-                    break;\r
-                    }\r
-\r
-                case REOP_FLAT1:\r
-                    System.out.print(" ");\r
-                    System.out.print(ren.chr);\r
-                    System.out.print(" ('\\");\r
-                    System.out.print(Integer.toString(ren.chr, 8));\r
-                    System.out.println("')");\r
-                    break;\r
-\r
-                case REOP_JUMP:\r
-                    System.out.print(" ");\r
-                    System.out.println(ren.next.offset);\r
-                    break;\r
-\r
-                case REOP_UCFLAT: {\r
-                    int index = ((Integer) ren.kid).intValue();\r
-                    int len = ren.kid2 - index;\r
-                    for (int i = 0; i < len; i++)\r
-                        System.out.print("\\u" + \r
-                                         Integer.toHexString(source[index+i]));\r
-                    System.out.println();\r
-                    break;\r
-                    }\r
-\r
-                case REOP_UCFLAT1:\r
-                    System.out.print("\\u" + \r
-                                     Integer.toHexString(ren.chr));\r
-                    System.out.println();\r
-                    break;\r
-\r
-                case REOP_UCCLASS: {\r
-                    int index = ((Integer) ren.kid).intValue();\r
-                    int len = ren.kid2 - index;\r
-                    System.out.print(" [");\r
-                    for (int i = 0; i < len; i++)\r
-                        System.out.print("\\u" + \r
-                                         Integer.toHexString(source[index+i]));\r
-                    System.out.println("]");\r
-                    break;\r
-                    }\r
-\r
-                default:\r
-                    System.out.println();\r
-                    break;\r
-                }\r
-\r
-                if ((ren.flags & RENode.GOODNEXT) == 0)\r
-                    break;\r
-            } while ((ren = ren.next) != null);\r
-            level--;\r
-        }\r
-    }\r
-\r
-    private void fixNext(CompilerState state, RENode ren1, RENode ren2,\r
-                         RENode oldnext) {\r
-        boolean goodnext;\r
-        RENode next, kid, ren;\r
-\r
-        goodnext = ren2 != null && (ren2.flags & RENode.ISNEXT) == 0;\r
-\r
-        /*\r
-         * Find the final node in a list of alternatives, or concatenations, or\r
-         * even a concatenation of alternatives followed by non-alternatives (e.g.\r
-         * ((x|y)z)w where ((x|y)z) is ren1 and w is ren2).\r
-         */\r
-        for (; (next = ren1.next) != null && next != oldnext; ren1 = next) {\r
-            if (ren1.op == REOP_ALT) {\r
-                /* Find the end of this alternative's operand list. */\r
-                kid = (RENode) ren1.kid;\r
-                if (kid.op == REOP_JUMP)\r
-                    continue;\r
-                for (ren = kid; ren.next != null; ren = ren.next) {\r
-                    if (ren.op == REOP_ALT)\r
-                        throw new RuntimeException("REOP_ALT not expected");\r
-                }\r
-\r
-                /* Append a jump node to all but the last alternative. */\r
-                ren.next = new RENode(state, REOP_JUMP, null);\r
-                ren.next.flags |= RENode.ISNEXT;\r
-                ren.flags |= RENode.GOODNEXT;\r
-\r
-                /* Recur to fix all descendent nested alternatives. */\r
-                fixNext(state, kid, ren2, oldnext);\r
-            }\r
-        }\r
-\r
-        /*\r
-         * Now ren1 points to the last alternative, or to the final node on a\r
-         * concatenation list.  Set its next link to ren2, flagging a join point\r
-         * if appropriate.\r
-         */\r
-        if (ren2 != null) {\r
-            if ((ren2.flags & RENode.ISNEXT) == 0)\r
-                ren2.flags |= RENode.ISNEXT;\r
-            else\r
-                ren2.flags |= RENode.ISJOIN;\r
-        }\r
-        ren1.next = ren2;\r
-        if (goodnext)\r
-            ren1.flags |= RENode.GOODNEXT;\r
-\r
-        /*\r
-         * The following ops have a kid subtree through which to recur.  Here is\r
-         * where we fix the next links under the final ALT node's kid.\r
-         */\r
-        switch (ren1.op) {\r
-        case REOP_ALT:\r
-        case REOP_QUANT:\r
-        case REOP_STAR:\r
-        case REOP_PLUS:\r
-        case REOP_OPT:\r
-        case REOP_LPAREN:\r
-        case REOP_LPARENNON:\r
-        case REOP_ASSERT:\r
-        case REOP_ASSERT_NOT:\r
-            fixNext(state, (RENode) ren1.kid, ren2, oldnext);\r
-            break;\r
-        default:;\r
-        }\r
-    }\r
-\r
-    private void setNext(CompilerState state, RENode ren1, RENode ren2) {\r
-        fixNext(state, ren1, ren2, null);\r
-    }\r
-\r
-    /*\r
-     * Top-down regular expression grammar, based closely on Perl 4.\r
-     *\r
-     *  regexp:     altern                  A regular expression is one or more\r
-     *              altern '|' regexp       alternatives separated by vertical bar.\r
-     */\r
-    private RENode parseRegExp(CompilerState state) {\r
-        RENode ren = parseAltern(state);\r
-        if (ren == null)\r
-            return null;\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        if (index < source.length && source[index] == '|') {\r
-            RENode kid = ren;\r
-            ren = new RENode(state, REOP_ALT, kid);\r
-            if (ren == null)\r
-                return null;\r
-            ren.flags = (byte) (kid.flags & (RENode.ANCHORED | RENode.NONEMPTY));\r
-            RENode ren1 = ren;\r
-            do {\r
-                /* (balance: */\r
-                state.index = ++index;\r
-                if (index < source.length && (source[index] == '|' ||\r
-                                              source[index] == ')'))\r
-                    {\r
-                        kid = new RENode(state, REOP_EMPTY, null);\r
-                    } else {\r
-                        kid = parseAltern(state);\r
-                        index = state.index;\r
-                    }\r
-                if (kid == null)\r
-                    return null;\r
-                RENode ren2 = new RENode(state, REOP_ALT, kid);\r
-                if (ren2 == null)\r
-                    return null;\r
-                ren1.next = ren2;\r
-                ren1.flags |= RENode.GOODNEXT;\r
-                ren2.flags = (byte) ((kid.flags & (RENode.ANCHORED |\r
-                                                   RENode.NONEMPTY))\r
-                                     | RENode.ISNEXT);\r
-                ren1 = ren2;\r
-            } while (index < source.length && source[index] == '|');\r
-        }\r
-        return ren;\r
-    }\r
-\r
-    /*\r
-     *  altern:     item                    An alternative is one or more items,\r
-     *              item altern             concatenated together.\r
-     */\r
-    private RENode parseAltern(CompilerState state) {\r
-        RENode ren = parseItem(state);\r
-        if (ren == null)\r
-            return null;\r
-        RENode ren1 = ren;\r
-        int flags = 0;\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        char c;\r
-        /* (balance: */\r
-        while (index != source.length && (c = source[index]) != '|' &&\r
-               c != ')')\r
-            {\r
-                RENode ren2 = parseItem(state);\r
-                if (ren2 == null)\r
-                    return null;\r
-                setNext(state, ren1, ren2);\r
-                flags |= ren2.flags;\r
-                ren1 = ren2;\r
-                index = state.index;\r
-            }\r
-\r
-        /*\r
-         * Propagate NONEMPTY to the front of a concatenation list, so that the\r
-         * first alternative in (^a|b) is considered non-empty.  The first node\r
-         * in a list may match the empty string (as ^ does), but if the list is\r
-         * non-empty, then the first node's NONEMPTY flag must be set.\r
-         */\r
-        ren.flags |= flags & RENode.NONEMPTY;\r
-        return ren;\r
-    }\r
-\r
-    /*\r
-     *  item:       assertion               An item is either an assertion or\r
-     *              quantatom               a quantified atom.\r
-     *\r
-     *  assertion:  '^'                     Assertions match beginning of string\r
-     *                                      (or line if the class static property\r
-     *                                      RegExp.multiline is true).\r
-     *              '$'                     End of string (or line if the class\r
-     *                                      static property RegExp.multiline is\r
-     *                                      true).\r
-     *              '\b'                    Word boundary (between \w and \W).\r
-     *              '\B'                    Word non-boundary.\r
-     */\r
-    RENode parseItem(CompilerState state) {\r
-        RENode ren;\r
-        byte op;\r
-\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        switch (index < source.length ? source[index] : '\0') {\r
-        case '^':\r
-            state.index = index + 1;\r
-            ren = new RENode(state, REOP_BOL, null);\r
-            ren.flags |= RENode.ANCHORED;\r
-            return ren;\r
-\r
-        case '$':\r
-            state.index = index + 1;\r
-            return new RENode(state,\r
-                              (index == state.indexBegin ||\r
-                               ((source[index-1] == '(' ||\r
-                                 source[index-1] == '|') && /*balance)*/\r
-                                (index - 1 == state.indexBegin ||\r
-                                 source[index-2] != '\\')))\r
-                              ? REOP_EOLONLY\r
-                              : REOP_EOL,\r
-                              null);\r
-\r
-        case '\\':\r
-            switch (++index < source.length ? source[index] : '\0') {\r
-            case 'b':\r
-                op = REOP_WBDRY;\r
-                break;\r
-            case 'B':\r
-                op = REOP_WNONBDRY;\r
-                break;\r
-            default:\r
-                return parseQuantAtom(state);\r
-            }\r
-\r
-            /*\r
-             * Word boundaries and non-boundaries are flagged as non-empty\r
-             * so they will be prefixed by an anchoring node.\r
-             */\r
-            state.index = index + 1;\r
-            ren = new RENode(state, op, null);\r
-            ren.flags |= RENode.NONEMPTY;\r
-            return ren;\r
-\r
-        default:;\r
-        }\r
-        return parseQuantAtom(state);\r
-    }\r
-\r
-    /*\r
-     *  quantatom:  atom                    An unquantified atom.\r
-     *              quantatom '{' n ',' m '}'\r
-     *                                      Atom must occur between n and m times.\r
-     *              quantatom '{' n ',' '}' Atom must occur at least n times.\r
-     *              quantatom '{' n '}'     Atom must occur exactly n times.\r
-     *              quantatom '*'           Zero or more times (same as {0,}).\r
-     *              quantatom '+'           One or more times (same as {1,}).\r
-     *              quantatom '?'           Zero or one time (same as {0,1}).\r
-     *\r
-     *              any of which can be optionally followed by '?' for ungreedy\r
-     */\r
-    RENode parseQuantAtom(CompilerState state) {\r
-        RENode ren = parseAtom(state);\r
-        if (ren == null)\r
-            return null;\r
-\r
-        int up;\r
-        char c;\r
-        RENode ren2;\r
-        int min, max;\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        loop:\r
-        while (index < source.length) {\r
-            switch (source[index]) {\r
-            case '{':\r
-                if (++index == source.length || !isDigit(c = source[index])) {\r
-                    reportError("msg.bad.quant",\r
-                                String.valueOf(source[state.index]), state);\r
-                    return null;\r
-                }\r
-                min = unDigit(c);\r
-                while (++index < source.length && isDigit(c = source[index])) {\r
-                    min = 10 * min + unDigit(c);\r
-                    if ((min >> 16) != 0) {\r
-                        reportError("msg.overlarge.max", tail(source, index),\r
-                                    state);\r
-                        return null;\r
-                    }\r
-                }\r
-                if (source[index] == ',') {\r
-                    up = ++index;\r
-                    if (isDigit(source[index])) {\r
-                        max = unDigit(source[index]);\r
-                        while (isDigit(c = source[++index])) {\r
-                            max = 10 * max + unDigit(c);\r
-                            if ((max >> 16) != 0) {\r
-                                reportError("msg.overlarge.max",\r
-                                            String.valueOf(source[up]), state);\r
-                                return null;\r
-                            }\r
-                        }\r
-                        if (max == 0) {\r
-                            reportError("msg.zero.quant",\r
-                                        tail(source, state.index), state);\r
-                            return null;\r
-                        }\r
-                        if (min > max) {\r
-                            reportError("msg.max.lt.min", tail(source, up), state);\r
-                            return null;\r
-                        }\r
-                    } else {\r
-                        /* 0 means no upper bound. */\r
-                        max = 0;\r
-                    }\r
-                } else {\r
-                    /* Exactly n times. */\r
-                    if (min == 0) {\r
-                        reportError("msg.zero.quant",\r
-                                    tail(source, state.index), state);\r
-                        return null;\r
-                    }\r
-                    max = min;\r
-                }\r
-                if (source[index] != '}') {\r
-                    reportError("msg.unterm.quant",\r
-                                String.valueOf(source[state.index]), state);\r
-                    return null;\r
-                }\r
-                index++;\r
-\r
-                ren2 = new RENode(state, REOP_QUANT, ren);\r
-                if (min > 0 && (ren.flags & RENode.NONEMPTY) != 0)\r
-                    ren2.flags |= RENode.NONEMPTY;\r
-                ren2.min = (short) min;\r
-                ren2.max = (short) max;\r
-                ren = ren2;\r
-                break;\r
-\r
-            case '*':\r
-                index++;\r
-                ren = new RENode(state, REOP_STAR, ren);\r
-                break;\r
-\r
-            case '+':\r
-                index++;\r
-                ren2 = new RENode(state, REOP_PLUS, ren);\r
-                if ((ren.flags & RENode.NONEMPTY) != 0)\r
-                    ren2.flags |= RENode.NONEMPTY;\r
-                ren = ren2;\r
-                break;\r
-\r
-            case '?':\r
-                index++;\r
-                ren = new RENode(state, REOP_OPT, ren);\r
-                break;\r
-\r
-            default:\r
-                break loop;\r
-            }\r
-            if ((index < source.length) && (source[index] == '?')) {\r
-                ren.flags |= RENode.MINIMAL;\r
-                index++;\r
-            }\r
-        }\r
-\r
-        state.index = index;\r
-        return ren;\r
-    }\r
-\r
-    /*\r
-     *  atom:       '(' regexp ')'          A parenthesized regexp (what matched\r
-     *                                      can be addressed using a backreference,\r
-     *                                      see '\' n below).\r
-     *              '.'                     Matches any char except '\n'.\r
-     *              '[' classlist ']'       A character class.\r
-     *              '[' '^' classlist ']'   A negated character class.\r
-     *              '\f'                    Form Feed.\r
-     *              '\n'                    Newline (Line Feed).\r
-     *              '\r'                    Carriage Return.\r
-     *              '\t'                    Horizontal Tab.\r
-     *              '\v'                    Vertical Tab.\r
-     *              '\d'                    A digit (same as [0-9]).\r
-     *              '\D'                    A non-digit.\r
-     *              '\w'                    A word character, [0-9a-z_A-Z].\r
-     *              '\W'                    A non-word character.\r
-     *              '\s'                    A whitespace character, [ \b\f\n\r\t\v].\r
-     *              '\S'                    A non-whitespace character.\r
-     *              '\' n                   A backreference to the nth (n decimal\r
-     *                                      and positive) parenthesized expression.\r
-     *              '\' octal               An octal escape sequence (octal must be\r
-     *                                      two or three digits long, unless it is\r
-     *                                      0 for the null character).\r
-     *              '\x' hex                A hex escape (hex must be two digits).\r
-     *              '\c' ctrl               A control character, ctrl is a letter.\r
-     *              '\' literalatomchar     Any character except one of the above\r
-     *                                      that follow '\' in an atom.\r
-     *              otheratomchar           Any character not first among the other\r
-     *                                      atom right-hand sides.\r
-     */\r
-    static final String metachars    = "|^${*+?().[\\";\r
-    static final String closurechars = "{*+?";\r
-\r
-    RENode parseAtom(CompilerState state) {\r
-        int num = 0, len;\r
-        RENode ren = null;\r
-        RENode ren2;\r
-        char c;\r
-        byte op;\r
-\r
-        boolean skipCommon = false;\r
-        boolean doFlat = false;\r
-\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        int ocp = index;\r
-        if (index == source.length) {\r
-            state.index = index;\r
-            return new RENode(state, REOP_EMPTY, null);\r
-        }\r
-        switch (source[index]) {\r
-            /* handle /|a/ by returning an empty node for the leftside */\r
-        case '|':\r
-            return new RENode(state, REOP_EMPTY, null);\r
-\r
-        case '(':\r
-            op = REOP_END;\r
-            if (source[index + 1] == '?') {\r
-                switch (source[index + 2]) {\r
-                case ':' :\r
-                    op = REOP_LPARENNON;\r
-                    break;\r
-                case '=' :\r
-                    op = REOP_ASSERT;\r
-                    break;\r
-                case '!' :\r
-                    op = REOP_ASSERT_NOT;\r
-                    break;\r
-                }\r
-            }\r
-            if (op == REOP_END) {\r
-                op = REOP_LPAREN;\r
-                num = state.parenCount++;      /* \1 is numbered 0, etc. */\r
-                index++;\r
-            }\r
-            else\r
-                index += 3;\r
-            state.index = index;\r
-            /* Handle empty paren */\r
-            if (source[index] == ')') {\r
-                ren2 = new RENode(state, REOP_EMPTY, null);\r
-            }\r
-            else {\r
-                ren2 = parseRegExp(state);\r
-                if (ren2 == null)\r
-                    return null;\r
-                index = state.index;\r
-                if (index >= source.length || source[index] != ')') {\r
-                    reportError("msg.unterm.paren", tail(source, ocp), state);\r
-                    return null;\r
-                }\r
-            }\r
-            index++;\r
-            ren = new RENode(state, op, ren2);\r
-            ren.flags = (byte) (ren2.flags & (RENode.ANCHORED |\r
-                                              RENode.NONEMPTY));\r
-            ren.num = num;\r
-            if ((op == REOP_LPAREN) || (op == REOP_LPARENNON)) {\r
-                /* Assume RPAREN ops immediately succeed LPAREN ops */\r
-                ren2 = new RENode(state, (byte)(op + 1), null);\r
-                setNext(state, ren, ren2);\r
-                ren2.num = num;\r
-            }\r
-            break;\r
-\r
-        case '.':\r
-            ++index;\r
-            op = REOP_DOT;\r
-            if ((index < source.length) && (source[index] == '*')) {\r
-               index++;\r
-                op = REOP_DOTSTAR;\r
-                if ((index < source.length) && (source[index] == '?')) {\r
-                    index++;\r
-                    op = REOP_DOTSTARMIN;\r
-                }\r
-            }\r
-            ren = new RENode(state, op, null);\r
-            if (ren.op == REOP_DOT)\r
-                ren.flags = RENode.SINGLE | RENode.NONEMPTY;\r
-            break;\r
-\r
-        case '[':\r
-            /* A char class must have at least one char in it. */\r
-            if (++index == source.length) {\r
-                reportError("msg.unterm.class", tail(source, ocp), state);\r
-                return null;\r
-            }\r
-            c = source[index];\r
-            ren = new RENode(state, REOP_CCLASS, new Integer(index));\r
-\r
-            /* A negated class must have at least one char in it after the ^. */\r
-            if (c == '^' && ++index == source.length) {\r
-                reportError("msg.unterm.class", tail(source, ocp), state);\r
-                return null;\r
-            }\r
-\r
-            for (;;) {\r
-                if (++index == source.length) {\r
-                    reportError("msg.unterm.paren", tail(source, ocp), state);\r
-                    return null;\r
-                }\r
-                c = source[index];\r
-                if (c == ']')\r
-                    break;\r
-                if (c == '\\' && index+1 != source.length)\r
-                    index++;\r
-            }\r
-            ren.kid2 = index++;\r
-\r
-            /* Since we rule out [] and [^], we can set the non-empty flag. */\r
-            ren.flags = RENode.SINGLE | RENode.NONEMPTY;\r
-            break;\r
-\r
-        case '\\':\r
-            if (++index == source.length) {\r
-                Context.reportError(ScriptRuntime.getMessage("msg.trail.backslash",\r
-                                                             null));\r
-                return null;\r
-            }\r
-            c = source[index];\r
-            switch (c) {\r
-            case 'f':\r
-            case 'n':\r
-            case 'r':\r
-            case 't':\r
-            case 'v':\r
-                c = getEscape(c);\r
-                ren = new RENode(state, REOP_FLAT1, null);\r
-                break;\r
-            case 'd':\r
-                ren = new RENode(state, REOP_DIGIT, null);\r
-                break;\r
-            case 'D':\r
-                ren = new RENode(state, REOP_NONDIGIT, null);\r
-                break;\r
-            case 'w':\r
-                ren = new RENode(state, REOP_ALNUM, null);\r
-                break;\r
-            case 'W':\r
-                ren = new RENode(state, REOP_NONALNUM, null);\r
-                break;\r
-            case 's':\r
-                ren = new RENode(state, REOP_SPACE, null);\r
-                break;\r
-            case 'S':\r
-                ren = new RENode(state, REOP_NONSPACE, null);\r
-                break;\r
-\r
-            case '0':\r
-            case '1':\r
-            case '2':\r
-            case '3':\r
-            case '4':\r
-            case '5':\r
-            case '6':\r
-            case '7':\r
-            case '8':\r
-            case '9':\r
-                /*\r
-                  Yuk. Keeping the old style \n interpretation for 1.2\r
-                  compatibility.\r
-                */\r
-                if ((state.cx.getLanguageVersion() != Context.VERSION_DEFAULT)\r
-                    && (state.cx.getLanguageVersion() <= Context.VERSION_1_4)) {\r
-                    switch (c) {                    \r
-                    case '0':\r
-                        state.index = index;\r
-                        num = doOctal(state);\r
-                        index = state.index;\r
-                        ren = new RENode(state, REOP_FLAT1, null);\r
-                        c = (char) num;\r
-                        break;\r
-\r
-                    case '1':\r
-                    case '2':\r
-                    case '3':\r
-                    case '4':\r
-                    case '5':\r
-                    case '6':\r
-                    case '7':\r
-                    case '8':\r
-                    case '9':\r
-                        num = unDigit(c);\r
-                        len = 1;\r
-                        while (++index < source.length\r
-                               && isDigit(c = source[index])) {\r
-                            num = 10 * num + unDigit(c);\r
-                            len++;\r
-                        }\r
-                        /* n in [8-9] and > count of parenetheses, then revert to\r
-                           '8' or '9', ignoring the '\' */\r
-                        if (((num == 8) || (num == 9)) && (num > state.parenCount)) {\r
-                            ocp = --index;  /* skip beyond the '\' */\r
-                            doFlat = true;\r
-                            skipCommon = true;\r
-                            break;                        \r
-                        }\r
-                        /* more than 1 digit, or a number greater than\r
-                           the count of parentheses => it's an octal */\r
-                        if ((len > 1) || (num > state.parenCount)) {\r
-                            state.index = ocp;\r
-                            num = doOctal(state);\r
-                            index = state.index;\r
-                            ren = new RENode(state, REOP_FLAT1, null);\r
-                            c = (char) num;\r
-                            break;\r
-                        }\r
-                        index--;\r
-                        ren = new RENode(state, REOP_BACKREF, null);\r
-                        ren.num = num - 1;       /* \1 is numbered 0, etc. */\r
-\r
-                        /* Avoid common chr- and flags-setting \r
-                           code after switch. */\r
-                        ren.flags = RENode.NONEMPTY;\r
-                        skipCommon = true;\r
-                        break;\r
-                    }\r
-                }\r
-                else {\r
-                    if (c == '0') {\r
-                        ren = new RENode(state, REOP_FLAT1, null);\r
-                        c = 0;\r
-                    }\r
-                    else {\r
-                        num = unDigit(c);\r
-                        len = 1;\r
-                        while (++index < source.length\r
-                               && isDigit(c = source[index])) {\r
-                            num = 10 * num + unDigit(c);\r
-                            len++;\r
-                        }\r
-                        index--;\r
-                        ren = new RENode(state, REOP_BACKREF, null);\r
-                        ren.num = num - 1;       /* \1 is numbered 0, etc. */\r
-                        /* Avoid common chr- and flags-setting \r
-                           code after switch. */\r
-                        ren.flags = RENode.NONEMPTY;\r
-                        skipCommon = true;\r
-                    }\r
-                }\r
-                break;\r
-                \r
-            case 'x':\r
-                ocp = index;\r
-                if (++index < source.length && isHex(c = source[index])) {\r
-                    num = unHex(c);\r
-                    if (++index < source.length && isHex(c = source[index])) {\r
-                        num <<= 4;\r
-                        num += unHex(c);\r
-                    } else {\r
-                        if ((state.cx.getLanguageVersion()\r
-                             != Context.VERSION_DEFAULT)\r
-                            && (state.cx.getLanguageVersion() \r
-                                <= Context.VERSION_1_4)) \r
-                            index--; /* back up so index points to last hex char */\r
-                        else { /* ecma 2 requires pairs of hex digits. */\r
-                            index = ocp;\r
-                            num = 'x';\r
-                        }\r
-                    }\r
-                } else {\r
-                    index = ocp;       /* \xZZ is xZZ (Perl does \0ZZ!) */\r
-                    num = 'x';\r
-                }\r
-                ren = new RENode(state, REOP_FLAT1, null);\r
-                c = (char)num;\r
-                break;\r
-\r
-            case 'c':\r
-                c = source[++index];\r
-                if (!('A' <= c && c <= 'Z') && !('a' <= c && c <= 'z')) {\r
-                    index -= 2;\r
-                    ocp = index;\r
-                    doFlat = true;\r
-                    skipCommon = true;\r
-                    break;\r
-                }\r
-                c = Character.toUpperCase(c);\r
-                c = (char) (c ^ 64); // JS_TOCTRL\r
-                ren = new RENode(state, REOP_FLAT1, null);\r
-                break;\r
-\r
-            case 'u':\r
-                if (index+4 < source.length &&\r
-                    isHex(source[index+1]) && isHex(source[index+2]) &&\r
-                    isHex(source[index+3]) && isHex(source[index+4]))\r
-                    {\r
-                        num = (((((unHex(source[index+1]) << 4) +\r
-                                  unHex(source[index+2])) << 4) +\r
-                                unHex(source[index+3])) << 4) +\r
-                            unHex(source[index+4]);\r
-                        c = (char) num;\r
-                        index += 4;\r
-                        ren = new RENode(state, REOP_FLAT1, null);\r
-                        break;\r
-                    }\r
-\r
-                /* Unlike Perl \\xZZ, we take \\uZZZ to be literal-u then ZZZ. */\r
-                ocp = index;\r
-                doFlat = true;\r
-                skipCommon = true;\r
-                break;\r
-\r
-            default:\r
-                ocp = index;\r
-                doFlat = true;\r
-                skipCommon = true;\r
-                break;\r
-            }\r
-\r
-            /* Common chr- and flags-setting code for escape opcodes. */\r
-            if (ren != null && !skipCommon) {\r
-                ren.chr = c;\r
-                ren.flags = RENode.SINGLE | RENode.NONEMPTY;\r
-            }\r
-            skipCommon = false;\r
-\r
-            if (!doFlat) {\r
-                /* Skip to next unparsed char. */\r
-                index++;\r
-                break;\r
-            }\r
-\r
-            /* fall through since doFlat was true */\r
-            doFlat = false;\r
-\r
-        default:\r
-            while (++index != source.length &&\r
-                   metachars.indexOf(source[index]) == -1)\r
-                ;\r
-            len = (int)(index - ocp);\r
-            if (index != source.length && len > 1 &&\r
-                closurechars.indexOf(source[index]) != -1)\r
-                {\r
-                    index--;\r
-                    len--;\r
-                }\r
-            if (len > REOP_FLATLEN_MAX) {\r
-                len = REOP_FLATLEN_MAX;\r
-                index = ocp + len;\r
-            }\r
-            ren = new RENode(state, len == 1 ? REOP_FLAT1 : REOP_FLAT,\r
-                             new Integer(ocp));\r
-            ren.flags = RENode.NONEMPTY;\r
-            if (len > 1) {\r
-                ren.kid2 = index;\r
-            } else {\r
-                ren.flags |= RENode.SINGLE;\r
-                ren.chr = source[ocp];\r
-            }\r
-            break;\r
-        }\r
-\r
-        state.index = index;\r
-        return ren;\r
-    }\r
-\r
-    private int doOctal(CompilerState state) {\r
-        char[] source = state.source;\r
-        int index = state.index;\r
-        int tmp, num = 0;\r
-        char c;\r
-        while (++index < source.length && '0' <= (c = source[index]) &&\r
-               c <= '7')\r
-            {\r
-                tmp = 8 * num + (int)(c - '0');\r
-                if (tmp > 0377) {\r
-                    break;\r
-                }\r
-                num = tmp;\r
-            }\r
-        index--;\r
-        state.index = index;\r
-        return num;\r
-    }\r
-\r
-    static char getEscape(char c) {\r
-        switch (c) {\r
-        case 'b':\r
-            return '\b';\r
-        case 'f':\r
-            return '\f';\r
-        case 'n':\r
-            return '\n';\r
-        case 'r':\r
-            return '\r';\r
-        case 't':\r
-            return '\t';\r
-        case 'v':\r
-            return (char) 11; // '\v' is not vtab in Java\r
-        }\r
-        throw new RuntimeException();\r
-    }\r
-\r
-    static public boolean isDigit(char c) {\r
-        return '0' <= c && c <= '9';\r
-    }\r
-\r
-    static int unDigit(char c) {\r
-        return c - '0';\r
-    }\r
-\r
-    static boolean isHex(char c) {\r
-        return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') ||\r
-            ('A' <= c && c <= 'F');\r
-    }\r
-\r
-    static int unHex(char c) {\r
-        if ('0' <= c && c <= '9')\r
-            return c - '0';\r
-        return 10 + Character.toLowerCase(c) - 'a';\r
-    }\r
-\r
-    static boolean isWord(char c) {\r
-        return Character.isLetter(c) || isDigit(c) || c == '_';\r
-    }\r
-\r
-    private String tail(char[] a, int i) {\r
-        return new String(a, i, a.length - i);\r
-    }\r
-\r
-    private static boolean matchChar(int flags, char c, char c2) {\r
-        if (c == c2)\r
-            return true;\r
-        else\r
-            if ((flags & FOLD) != 0) {\r
-                c = Character.toUpperCase(c);\r
-                c2 = Character.toUpperCase(c2);\r
-                return c == c2 ||\r
-                    Character.toLowerCase(c) == Character.toLowerCase(c2);\r
-            }\r
-            else\r
-                return false;\r
-    }\r
-    \r
-    \r
-    int greedyRecurse(GreedyState grState, int index, int previousKid) {\r
-        int kidMatch;\r
-        int match;\r
-        int num;\r
-\r
-       /*\r
-         *    when the kid match fails, we reset the parencount and run any \r
-         *    previously succesful kid in order to restablish it's paren\r
-         *    contents.\r
-         */\r
-\r
-        num = grState.state.parenCount;\r
-        kidMatch = matchRENodes(grState.state, grState.kid, grState.next, index);\r
-        if (kidMatch == -1) {\r
-            match = matchRENodes(grState.state, grState.next, grState.stop, index);\r
-            if (match != -1) {\r
-                grState.state.parenCount = num;\r
-                if (previousKid != -1)\r
-                    matchRENodes(grState.state, grState.kid, grState.next, previousKid);\r
-                return index;\r
-            }\r
-            else\r
-                return -1;\r
-        }\r
-        else {\r
-            if (kidMatch == index) {\r
-                if (previousKid != -1)\r
-                    matchRENodes(grState.state, grState.kid, grState.next, previousKid);\r
-                return kidMatch;    /* no point pursuing an empty match forever */\r
-            }\r
-            if ((grState.maxKid == 0) || (++grState.kidCount < grState.maxKid)) {\r
-                match = greedyRecurse(grState, kidMatch, index);\r
-                if (match != -1) return match;\r
-                if (grState.maxKid != 0) --grState.kidCount;\r
-            }\r
-            grState.state.parenCount = num;\r
-            match = matchRENodes(grState.state, grState.next, grState.stop, kidMatch);\r
-            if (match != -1) {\r
-                matchRENodes(grState.state, grState.kid, grState.next, index);\r
-                return kidMatch;\r
-            }\r
-            else\r
-                return -1;\r
-        }\r
-    }\r
-\r
-    int matchGreedyKid(MatchState state, RENode ren, RENode stop,\r
-                       int kidCount, int index, int previousKid) {\r
-        GreedyState grState = new GreedyState();\r
-        grState.state = state;\r
-        grState.kid = (RENode)ren.kid;\r
-        grState.next = ren.next;\r
-        grState.maxKid = (ren.op == REOP_QUANT) ? ren.max : 0;\r
-        /*\r
-         * We try to match the sub-tree to completion first, and if that\r
-         * doesn't work, match only up to the given end of the sub-tree.\r
-         */\r
-        grState.stop = null;\r
-        grState.kidCount = kidCount;\r
-        int match = greedyRecurse(grState, index, previousKid);\r
-        if (match != -1 || stop == null) return match;\r
-        grState.kidCount = kidCount;\r
-        grState.stop = stop;\r
-        return greedyRecurse(grState, index, previousKid);\r
-    }\r
-\r
-    int matchNonGreedyKid(MatchState state, RENode ren,\r
-                          int kidCount, int maxKid,\r
-                          int index) {\r
-        int kidMatch;\r
-        int match;\r
-\r
-        match = matchRENodes(state, ren.next, null, index);\r
-        if (match != -1) return index;\r
-        kidMatch = matchRENodes(state, (RENode)ren.kid, ren.next, index);\r
-        if (kidMatch == -1) return -1;\r
-        if (kidMatch == index) return kidMatch;    /* no point pursuing an empty match forever */\r
-        return matchNonGreedyKid(state, ren, kidCount, maxKid, kidMatch);\r
-    }\r
-\r
-    int matchRENodes(MatchState state, RENode ren, RENode stop, int index) {\r
-        int num;\r
-        char[] input = state.input;\r
-        while ((ren != stop) && (ren != null)) {\r
-                switch (ren.op) {\r
-                case REOP_EMPTY:\r
-                    break;\r
-                case REOP_ALT: {\r
-                    if (ren.next.op != REOP_ALT) {\r
-                        ren = (RENode)ren.kid;\r
-                        continue;\r
-                    }\r
-                    else {\r
-                        num = state.parenCount;\r
-                        int kidMatch = matchRENodes(state, (RENode)ren.kid,\r
-                                                    stop, index);\r
-                        if (kidMatch != -1) return kidMatch;\r
-                        for (int i = num; i < state.parenCount; i++)\r
-                            state.parens[i] = null;\r
-                        state.parenCount = num;\r
-                    }\r
-                }\r
-                    break;\r
-                case REOP_QUANT: {\r
-                    int lastKid = -1;\r
-                    for (num = 0; num < ren.min; num++) {\r
-                        int kidMatch = matchRENodes(state, (RENode)ren.kid,\r
-                                                    ren.next, index);\r
-                        if (kidMatch == -1)\r
-                            return -1;\r
-                        else {\r
-                            lastKid = index;\r
-                            index = kidMatch;\r
-                        }\r
-                    }\r
-                    if (num == ren.max)\r
-                        // Have matched the exact count required, \r
-                        // need to match the rest of the regexp.\r
-                        break;\r
-                    if ((ren.flags & RENode.MINIMAL) == 0) {\r
-                        int kidMatch = matchGreedyKid(state, ren, stop, num,\r
-                                                      index, lastKid);\r
-                        if (kidMatch == -1)\r
-                            index = matchRENodes(state, (RENode)ren.kid,\r
-                                                 ren.next, index);\r
-                        else \r
-                            index = kidMatch;\r
-                    }        \r
-                    else {\r
-                        index = matchNonGreedyKid(state, ren, num,\r
-                                                  ren.max, index);\r
-                    }                          \r
-                    if (index == -1) return -1;\r
-                }\r
-                    break;\r
-                case REOP_PLUS: {\r
-                    int kidMatch = matchRENodes(state, (RENode)ren.kid, \r
-                                                ren.next, index);\r
-                    if (kidMatch == -1)\r
-                        return -1;\r
-                    if ((ren.flags & RENode.MINIMAL) == 0) {\r
-                        kidMatch = matchGreedyKid(state, ren, stop, 1, \r
-                                                  kidMatch, index);\r
-                        if (kidMatch == -1)\r
-                            index = matchRENodes(state,(RENode)ren.kid,\r
-                                                 ren.next, index);\r
-                        else\r
-                            index = kidMatch;\r
-                    }\r
-                    else\r
-                        index = matchNonGreedyKid(state, ren, 1, 0, kidMatch);\r
-                    if (index == -1) return -1;\r
-                }\r
-                    break;\r
-                case REOP_STAR:                                        \r
-                    if ((ren.flags & RENode.MINIMAL) == 0) {\r
-                        int kidMatch = matchGreedyKid(state, ren, stop, 0, index, -1);\r
-                        if (kidMatch != -1)\r
-                            index = kidMatch;\r
-                    }\r
-                    else {\r
-                        index = matchNonGreedyKid(state, ren, 0, 0, index);\r
-                        if (index == -1) return -1;\r
-                    }\r
-                    break;\r
-                case REOP_OPT: {\r
-                    int saveNum = state.parenCount;\r
-                    if (((ren.flags & RENode.MINIMAL) != 0)) {\r
-                        int restMatch = matchRENodes(state, ren.next,\r
-                                                     stop, index);\r
-                        if (restMatch != -1) return restMatch;\r
-                    }\r
-                    int kidMatch = matchRENodes(state, (RENode)ren.kid,\r
-                                                ren.next, index);\r
-                    if (kidMatch == -1) {\r
-                        state.parenCount = saveNum;\r
-                        break;\r
-                    }\r
-                    else {\r
-                        int restMatch = matchRENodes(state, ren.next,\r
-                                                     stop, kidMatch);\r
-                        if (restMatch == -1) {\r
-                            // need to undo the result of running the kid\r
-                            state.parenCount = saveNum;\r
-                            break;\r
-                        }\r
-                        else\r
-                            return restMatch;\r
-                    }\r
-                }\r
-                case REOP_LPARENNON:\r
-                    ren = (RENode)ren.kid;\r
-                    continue;\r
-                case REOP_RPARENNON:\r
-                    break;\r
-                case REOP_LPAREN: {\r
-                    num = ren.num;\r
-                    ren = (RENode)ren.kid;\r
-                    SubString parsub = state.parens[num];\r
-                    if (parsub == null) {\r
-                        parsub = state.parens[num] = new SubString();\r
-                        parsub.charArray = input;\r
-                    }\r
-                    parsub.index = index;\r
-                    parsub.length = 0;\r
-                    if (num >= state.parenCount)\r
-                        state.parenCount = num + 1;\r
-                    continue;\r
-                }\r
-                case REOP_RPAREN: {\r
-                    num = ren.num;\r
-                    SubString parsub = state.parens[num];\r
-                    if (parsub == null)\r
-                        throw new RuntimeException("Paren problem");\r
-                    parsub.length = index - parsub.index;\r
-                    break;\r
-                }\r
-                case REOP_ASSERT: {\r
-                    int kidMatch = matchRENodes(state, (RENode)ren.kid,\r
-                                                ren.next, index);\r
-                    if (kidMatch == -1) return -1;\r
-                    break;\r
-                }\r
-                case REOP_ASSERT_NOT: {\r
-                    int kidMatch = matchRENodes(state, (RENode)ren.kid,\r
-                                                ren.next, index);\r
-                    if (kidMatch != -1) return -1;\r
-                    break;\r
-                }\r
-                case REOP_BACKREF: {\r
-                    num = ren.num;\r
-                    if (num >= state.parens.length) {\r
-                        Context.reportError(\r
-                                            ScriptRuntime.getMessage(\r
-                                                                     "msg.bad.backref", null));\r
-                        return -1;\r
-                    }\r
-                    SubString parsub = state.parens[num];\r
-                    if (parsub == null)\r
-                        parsub = state.parens[num] = new SubString();\r
-                    int length = parsub.length;\r
-                    for (int i = 0; i < length; i++, index++) {\r
-                        if (index >= input.length) {\r
-                            return state.noMoreInput();\r
-                        }\r
-                        if (!matchChar(state.flags, input[index],\r
-                                       parsub.charArray[parsub.index + i]))\r
-                            return -1;\r
-                    }\r
-                }\r
-                    break;\r
-                case REOP_CCLASS:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (ren.bitmap == null) {\r
-                        char[] source = (ren.s != null) \r
-                            ? ren.s \r
-                            : this.source.toCharArray();\r
-                        ren.buildBitmap(state, source, ((state.flags & FOLD) != 0));\r
-                    }\r
-                    char c = input[index];\r
-                    int b = (c >>> 3);\r
-                    if (b >= ren.bmsize) {\r
-                        if (ren.kid2 == -1) // a ^ class\r
-                            index++;\r
-                        else\r
-                            return -1;\r
-                    } else {\r
-                        int bit = c & 7;\r
-                        bit = 1 << bit;\r
-                        if ((ren.bitmap[b] & bit) != 0)\r
-                            index++;\r
-                        else\r
-                            return -1;\r
-                    }\r
-                    break;\r
-                case REOP_DOT:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (input[index] != '\n')\r
-                        index++;\r
-                    else\r
-                        return -1;\r
-                    break;\r
-                case REOP_DOTSTARMIN: {\r
-                    int cp2;\r
-                    for (cp2 = index; cp2 < input.length; cp2++) {\r
-                        int cp3 = matchRENodes(state, ren.next, stop, cp2);\r
-                        if (cp3 != -1) return cp3;\r
-                        if (input[cp2] == '\n')\r
-                            return -1;\r
-                    }\r
-                    return state.noMoreInput();\r
-                }\r
-                case REOP_DOTSTAR: {\r
-                    int cp2;\r
-                    for (cp2 = index; cp2 < input.length; cp2++)\r
-                        if (input[cp2] == '\n')\r
-                            break;\r
-                    while (cp2 >= index) {\r
-                        int cp3 = matchRENodes(state, ren.next, stop, cp2);\r
-                        if (cp3 != -1) {\r
-                            index = cp2;\r
-                            break;\r
-                        }\r
-                        cp2--;\r
-                    }\r
-                    break;\r
-                }\r
-                case REOP_WBDRY:\r
-                    if (index == 0 || !isWord(input[index-1])) {\r
-                        if (index >= input.length)\r
-                            return state.noMoreInput();\r
-                        if (!isWord(input[index]))\r
-                            return -1;\r
-                    }\r
-                    else {\r
-                        if (index < input.length && isWord(input[index]))\r
-                            return -1;\r
-                    }\r
-                    break;\r
-                case REOP_WNONBDRY:\r
-                    if (index == 0 || !isWord(input[index-1])) {\r
-                        if (index < input.length && isWord(input[index]))\r
-                            return -1;\r
-                    }\r
-                    else {\r
-                        if (index >= input.length)\r
-                            return state.noMoreInput();\r
-                        if (!isWord(input[index]))\r
-                            return -1;\r
-                    }\r
-                    break;\r
-                case REOP_EOLONLY:\r
-                case REOP_EOL: {\r
-                    if (index == input.length)\r
-                        ; // leave index;\r
-                    else {\r
-                        Context cx = Context.getCurrentContext();\r
-                        RegExpImpl reImpl = getImpl(cx);\r
-                        if ((reImpl.multiline)\r
-                            || ((state.flags & MULTILINE) != 0))\r
-                            if (input[index] == '\n')\r
-                                ;// leave index\r
-                            else\r
-                                return -1;\r
-                        else\r
-                            return -1;\r
-                    }\r
-                }\r
-                    break;\r
-                case REOP_BOL: {\r
-                    Context cx = Context.getCurrentContext();\r
-                    RegExpImpl reImpl = getImpl(cx);\r
-                    if (index != 0) {\r
-                        if (reImpl.multiline ||\r
-                            ((state.flags & MULTILINE) != 0)) {\r
-                            if (index >= input.length) {\r
-                                return state.noMoreInput();\r
-                            }\r
-                            if (input[index - 1] == '\n') {\r
-                                break;\r
-                            }\r
-                        }\r
-                        return -1;\r
-                    }\r
-                    // leave index\r
-                }\r
-                    break;\r
-                case REOP_DIGIT:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (!isDigit(input[index])) return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_NONDIGIT:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (isDigit(input[index])) return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_ALNUM:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (!isWord(input[index])) return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_NONALNUM:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (isWord(input[index])) return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_SPACE:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (!(TokenStream.isJSSpace(input[index]) ||\r
-                          TokenStream.isJSLineTerminator(input[index])))\r
-                        return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_NONSPACE:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (TokenStream.isJSSpace(input[index]) ||\r
-                        TokenStream.isJSLineTerminator(input[index]))\r
-                        return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_FLAT1:\r
-                    if (index >= input.length) {\r
-                        return state.noMoreInput();\r
-                    }\r
-                    if (!matchChar(state.flags, ren.chr, input[index]))\r
-                        return -1;\r
-                    index++;\r
-                    break;\r
-                case REOP_FLAT: {\r
-                    char[] source = (ren.s != null)\r
-                        ? ren.s\r
-                        : this.source.toCharArray();\r
-                    int start = ((Integer)ren.kid).intValue();\r
-                    int length = ren.kid2 - start;\r
-                    for (int i = 0; i < length; i++, index++) {\r
-                        if (index >= input.length) {\r
-                            return state.noMoreInput();\r
-                        }\r
-                        if (!matchChar(state.flags, input[index],\r
-                                       source[start + i]))\r
-                            return -1;\r
-                    }\r
-                }\r
-                    break;\r
-                case REOP_JUMP:\r
-                    break;\r
-                case REOP_END:\r
-                    break;\r
-                default :\r
-                    throw new RuntimeException("Unsupported by node matcher");\r
-                }\r
-                ren = ren.next;\r
-            }\r
-        return index;\r
-    }\r
-\r
-    int matchRegExp(MatchState state, RENode ren, int index) {\r
-        // have to include the position beyond the last character\r
-        // in order to detect end-of-input/line condition\r
-        for (int i = index; i <= state.input.length; i++) {            \r
-            state.skipped = i - index;\r
-            state.parenCount = 0;\r
-            int result = matchRENodes(state, ren, null, i);\r
-            if (result != -1)\r
-                return result;\r
-        }\r
-        return -1;\r
-    }\r
-\r
-    /*\r
-     * indexp is assumed to be an array of length 1\r
-     */\r
-    Object executeRegExp(Context cx, Scriptable scopeObj, RegExpImpl res,\r
-                         String str, int indexp[], int matchType) \r
-    {\r
-        NativeRegExp re = this;\r
-        /*\r
-         * Initialize a CompilerState to minimize recursive argument traffic.\r
-         */\r
-        MatchState state = new MatchState();\r
-        state.inputExhausted = false;\r
-        state.anchoring = false;\r
-        state.flags = re.flags;\r
-        state.scope = scopeObj;\r
-\r
-        char[] charArray = str.toCharArray();\r
-        int start = indexp[0];\r
-        if (start > charArray.length)\r
-            start = charArray.length;\r
-        int index = start;\r
-        state.cpbegin = 0;\r
-        state.cpend = charArray.length;\r
-        state.start = start;\r
-        state.skipped = 0;\r
-        state.input = charArray;\r
-\r
-        state.parenCount = 0;\r
-        state.maybeParens = new SubString[re.parenCount];\r
-        state.parens = new SubString[re.parenCount];\r
-        // We allocate the elements of "parens" and "maybeParens" lazily in\r
-        // the Java port since we don't have arenas.\r
-\r
-        /*\r
-         * Call the recursive matcher to do the real work.  Return null on mismatch\r
-         * whether testing or not.  On match, return an extended Array object.\r
-         */\r
-        index = matchRegExp(state, ren, index);\r
-        if (index == -1) {\r
-            if (matchType != PREFIX || !state.inputExhausted) return null;\r
-            return Undefined.instance;\r
-        }\r
-        int i = index - state.cpbegin;\r
-        indexp[0] = i;\r
-        int matchlen = i - (start + state.skipped);\r
-        int ep = index; \r
-        index -= matchlen;\r
-        Object result;\r
-        Scriptable obj;\r
-\r
-        if (matchType == TEST) {\r
-            /*\r
-             * Testing for a match and updating cx.regExpImpl: don't allocate\r
-             * an array object, do return true.\r
-             */\r
-            result = Boolean.TRUE;\r
-            obj = null;\r
-        }\r
-        else {\r
-            /*\r
-             * The array returned on match has element 0 bound to the matched\r
-             * string, elements 1 through state.parenCount bound to the paren\r
-             * matches, an index property telling the length of the left context,\r
-             * and an input property referring to the input string.\r
-             */\r
-            Scriptable scope = getTopLevelScope(scopeObj);\r
-            result = ScriptRuntime.newObject(cx, scope, "Array", null);\r
-            obj = (Scriptable) result;\r
-\r
-            String matchstr = new String(charArray, index, matchlen);\r
-            obj.put(0, obj, matchstr);\r
-        }\r
-\r
-        if (state.parenCount > re.parenCount)\r
-            throw new RuntimeException();\r
-        if (state.parenCount == 0) {\r
-            res.parens.setSize(0);\r
-            res.lastParen = SubString.emptySubString;\r
-        } else {\r
-            SubString parsub = null;\r
-            int num;\r
-            res.parens.setSize(state.parenCount);\r
-            for (num = 0; num < state.parenCount; num++) {\r
-                parsub = state.parens[num];\r
-                res.parens.setElementAt(parsub, num);\r
-                if (matchType == TEST) continue;\r
-                String parstr = parsub == null ? "": parsub.toString();\r
-                obj.put(num+1, obj, parstr);\r
-            }\r
-            res.lastParen = parsub;\r
-        }\r
-\r
-        if (! (matchType == TEST)) {\r
-            /*\r
-             * Define the index and input properties last for better for/in loop\r
-             * order (so they come after the elements).\r
-             */\r
-            obj.put("index", obj, new Integer(start + state.skipped));\r
-            obj.put("input", obj, str);\r
-        }\r
-\r
-        if (res.lastMatch == null) {\r
-            res.lastMatch = new SubString();\r
-            res.leftContext = new SubString();\r
-            res.rightContext = new SubString();\r
-        }\r
-        res.lastMatch.charArray = charArray;\r
-        res.lastMatch.index = index;\r
-        res.lastMatch.length = matchlen;\r
-\r
-        res.leftContext.charArray = charArray;\r
-        if (cx.getLanguageVersion() == Context.VERSION_1_2) {\r
-            /*\r
-             * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used\r
-             * in scalar contexts, and unintentionally for the string.match "list"\r
-             * psuedo-context.  On "hi there bye", the following would result:\r
-             *\r
-             * Language     while(/ /g){print("$`");}   s/ /$`/g\r
-             * perl4.036    "hi", "there"               "hihitherehi therebye"\r
-             * perl5        "hi", "hi there"            "hihitherehi therebye"\r
-             * js1.2        "hi", "there"               "hihitheretherebye"\r
-             *\r
-             * Insofar as JS1.2 always defined $` as "left context from the last\r
-             * match" for global regexps, it was more consistent than perl4.\r
-             */\r
-            res.leftContext.index = start;\r
-            res.leftContext.length = state.skipped;\r
-        } else {\r
-            /*\r
-             * For JS1.3 and ECMAv2, emulate Perl5 exactly:\r
-             *\r
-             * js1.3        "hi", "hi there"            "hihitherehi therebye"\r
-             */\r
-            res.leftContext.index = 0;\r
-            res.leftContext.length = start + state.skipped;\r
-        }\r
-\r
-        res.rightContext.charArray = charArray;\r
-        res.rightContext.index = ep;\r
-        res.rightContext.length = state.cpend - ep;\r
-\r
-        return result;\r
-    }\r
-\r
-    public byte getFlags() {\r
-        return flags;\r
-    }\r
-\r
-    private void reportError(String msg, String arg, CompilerState state) {\r
-        Object[] args = { arg };\r
-        throw NativeGlobal.constructError(\r
-                                          state.cx, "SyntaxError",\r
-                                          ScriptRuntime.getMessage(msg, args),\r
-                                          state.scope);\r
-    }\r
-\r
-    protected int getIdDefaultAttributes(int id) {\r
-        switch (id) {\r
-            case Id_lastIndex:\r
-                return ScriptableObject.PERMANENT;\r
-            case Id_source:     \r
-            case Id_global:     \r
-            case Id_ignoreCase: \r
-            case Id_multiline:  \r
-                return ScriptableObject.PERMANENT | ScriptableObject.READONLY;\r
-        }\r
-        return super.getIdDefaultAttributes(id);\r
-    }\r
-    \r
-    protected Object getIdValue(int id) {\r
-        switch (id) {\r
-            case Id_lastIndex:  return wrap_long(0xffffffffL & lastIndex);\r
-            case Id_source:     return source;\r
-            case Id_global:     return wrap_boolean((flags & GLOB) != 0);\r
-            case Id_ignoreCase: return wrap_boolean((flags & FOLD) != 0);\r
-            case Id_multiline:  return wrap_boolean((flags & MULTILINE) != 0);\r
-        }\r
-        return super.getIdValue(id);\r
-    }\r
-    \r
-    protected void setIdValue(int id, Object value) {\r
-        if (id == Id_lastIndex) {\r
-            setLastIndex(ScriptRuntime.toInt32(value));\r
-            return;\r
-        }\r
-        super.setIdValue(id, value);\r
-    }\r
-\r
-    void setLastIndex(int value) {\r
-        lastIndex = value;\r
-    }\r
-    \r
-    public int methodArity(int methodId) {\r
-        if (prototypeFlag) {\r
-            switch (methodId) {\r
-                case Id_compile:  return 1;\r
-                case Id_toString: return 0;\r
-                case Id_exec:     return 1;\r
-                case Id_test:     return 1;\r
-                case Id_prefix:   return 1;\r
-            }\r
-        }\r
-        return super.methodArity(methodId);\r
-    }\r
-\r
-    public Object execMethod(int methodId, IdFunction f, Context cx,\r
-                             Scriptable scope, Scriptable thisObj, \r
-                             Object[] args)\r
-        throws JavaScriptException\r
-    {\r
-        if (prototypeFlag) {\r
-            switch (methodId) {\r
-                case Id_compile:\r
-                    return realThis(thisObj, f, false).compile(cx, scope, args);\r
-                \r
-                case Id_toString:\r
-                    return realThis(thisObj, f, true).toString();\r
-                \r
-                case Id_exec:\r
-                    return realThis(thisObj, f, false).exec(cx, scope, args);\r
-                \r
-                case Id_test:\r
-                    return realThis(thisObj, f, false).test(cx, scope, args);\r
-                \r
-                case Id_prefix:\r
-                    return realThis(thisObj, f, false).prefix(cx, scope, args);\r
-            }\r
-        }\r
-        return super.execMethod(methodId, f, cx, scope, thisObj, args);\r
-    }\r
-\r
-    private NativeRegExp realThis(Scriptable thisObj, IdFunction f, \r
-                                  boolean readOnly)\r
-    {\r
-        while (!(thisObj instanceof NativeRegExp)) {\r
-            thisObj = nextInstanceCheck(thisObj, f, readOnly);\r
-        }\r
-        return (NativeRegExp)thisObj;\r
-    }\r
-\r
-    protected String getIdName(int id) {\r
-        switch (id) {\r
-            case Id_lastIndex:  return "lastIndex";\r
-            case Id_source:     return "source";\r
-            case Id_global:     return "global";\r
-            case Id_ignoreCase: return "ignoreCase";\r
-            case Id_multiline:  return "multiline";\r
-        }\r
-        \r
-        if (prototypeFlag) {\r
-            switch (id) {\r
-                case Id_compile:  return "compile";\r
-                case Id_toString: return "toString";\r
-                case Id_exec:     return "exec";\r
-                case Id_test:     return "test";\r
-                case Id_prefix:   return "prefix";\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    protected int maxInstanceId() { return MAX_INSTANCE_ID; }\r
-\r
-// #string_id_map#\r
-\r
-    private static final int\r
-        Id_lastIndex    = 1,\r
-        Id_source       = 2,\r
-        Id_global       = 3,\r
-        Id_ignoreCase   = 4,\r
-        Id_multiline    = 5,\r
-        \r
-        MAX_INSTANCE_ID = 5;\r
-\r
-    protected int mapNameToId(String s) {\r
-        int id;\r
-// #generated# Last update: 2001-05-24 12:01:22 GMT+02:00\r
-        L0: { id = 0; String X = null; int c;\r
-            int s_length = s.length();\r
-            if (s_length==6) {\r
-                c=s.charAt(0);\r
-                if (c=='g') { X="global";id=Id_global; }\r
-                else if (c=='s') { X="source";id=Id_source; }\r
-            }\r
-            else if (s_length==9) {\r
-                c=s.charAt(0);\r
-                if (c=='l') { X="lastIndex";id=Id_lastIndex; }\r
-                else if (c=='m') { X="multiline";id=Id_multiline; }\r
-            }\r
-            else if (s_length==10) { X="ignoreCase";id=Id_ignoreCase; }\r
-            if (X!=null && X!=s && !X.equals(s)) id = 0;\r
-        }\r
-// #/generated#\r
-// #/string_id_map#\r
-\r
-        if (id != 0 || !prototypeFlag) { return id; }\r
-\r
-// #string_id_map#\r
-// #generated# Last update: 2001-05-24 12:01:22 GMT+02:00\r
-        L0: { id = 0; String X = null; int c;\r
-            L: switch (s.length()) {\r
-            case 4: c=s.charAt(0);\r
-                if (c=='e') { X="exec";id=Id_exec; }\r
-                else if (c=='t') { X="test";id=Id_test; }\r
-                break L;\r
-            case 6: X="prefix";id=Id_prefix; break L;\r
-            case 7: X="compile";id=Id_compile; break L;\r
-            case 8: X="toString";id=Id_toString; break L;\r
-            }\r
-            if (X!=null && X!=s && !X.equals(s)) id = 0;\r
-        }\r
-// #/generated#\r
-        return id;\r
-    }\r
-\r
-    private static final int\r
-        Id_compile       = MAX_INSTANCE_ID + 1,\r
-        Id_toString      = MAX_INSTANCE_ID + 2,\r
-        Id_exec          = MAX_INSTANCE_ID + 3,\r
-        Id_test          = MAX_INSTANCE_ID + 4,\r
-        Id_prefix        = MAX_INSTANCE_ID + 5,\r
-        \r
-        MAX_PROTOTYPE_ID = MAX_INSTANCE_ID + 5;\r
-\r
-// #/string_id_map#\r
-    private boolean prototypeFlag;\r
-\r
-    private String source;      /* locked source string, sans // */\r
-    private int lastIndex;      /* index after last match, for //g iterator */\r
-    private int parenCount;     /* number of parenthesized submatches */\r
-    private byte flags;         /* flags  */\r
-    private byte[] program;     /* regular expression bytecode */\r
-\r
-    RENode ren;\r
-}\r
-\r
-class CompilerState {\r
-    CompilerState(String source, int flags, Context cx, Scriptable scope) {\r
-        this.source = source.toCharArray();\r
-        this.scope = scope;\r
-        this.flags = flags;\r
-        this.cx = cx;\r
-    }\r
-    Context     cx;\r
-    Scriptable  scope;\r
-    char[]      source;\r
-    int         indexBegin;\r
-    int         index;\r
-    int         flags;\r
-    int         parenCount;\r
-    int         progLength;\r
-    byte[]      prog;\r
-}\r
-\r
-\r
-class RENode {\r
-    public static final int ANCHORED = 0x01;    /* anchored at the front */\r
-    public static final int SINGLE   = 0x02;    /* matches a single char */\r
-    public static final int NONEMPTY = 0x04;    /* does not match empty string */\r
-    public static final int ISNEXT   = 0x08;    /* ren is next after at least one node */\r
-    public static final int GOODNEXT = 0x10;    /* ren.next is a tree-like edge in the graph */\r
-    public static final int ISJOIN   = 0x20;    /* ren is a join point in the graph */\r
-    public static final int REALLOK  = 0x40;    /* REOP_FLAT owns tempPool space to realloc */\r
-    public static final int MINIMAL  = 0x80;    /* un-greedy matching for ? * + {} */\r
-\r
-    RENode(CompilerState state, byte op, Object kid) {\r
-        this.op = op;\r
-        this.kid = kid;\r
-    }\r
-    \r
-    private void calcBMSize(char[] s, int index, int cp2, boolean fold) {\r
-        char maxc = 0;\r
-        while (index < cp2) {\r
-            char c = s[index++];\r
-            if (c == '\\') {\r
-                if (index + 5 <= cp2 && s[index] == 'u'\r
-                    && NativeRegExp.isHex(s[index+1]) \r
-                    && NativeRegExp.isHex(s[index+2])\r
-                    && NativeRegExp.isHex(s[index+3]) \r
-                    && NativeRegExp.isHex(s[index+4]))\r
-                    {\r
-                        int x = (((((NativeRegExp.unHex(s[index+0]) << 4) +\r
-                                    NativeRegExp.unHex(s[index+1])) << 4) +\r
-                                  NativeRegExp.unHex(s[index+2])) << 4) +\r
-                            NativeRegExp.unHex(s[index+3]);\r
-                        c = (char) x;\r
-                        index += 5;\r
-                    } else {\r
-                        /*\r
-                         * Octal and hex escapes can't be > 255.  Skip this\r
-                         * backslash and let the loop pass over the remaining\r
-                         * escape sequence as if it were text to match.\r
-                         */\r
-                        if (maxc < 255) maxc = 255;\r
-                        continue;\r
-                    }\r
-            }\r
-            if (fold) {\r
-                /*\r
-                 * Don't assume that lowercase are above uppercase, or\r
-                 * that c is either even when c has upper and lowercase\r
-                 * versions.\r
-                 */\r
-                char c2;\r
-                if ((c2 = Character.toUpperCase(c)) > maxc)\r
-                    maxc = c2;\r
-                if ((c2 = Character.toLowerCase(c2)) > maxc)\r
-                    maxc = c2;\r
-            }\r
-            if (c > maxc)\r
-                maxc = c;\r
-        }\r
-        bmsize = (short)((maxc + NativeRegExp.JS_BITS_PER_BYTE) \r
-                         / NativeRegExp.JS_BITS_PER_BYTE);\r
-    }\r
-    \r
-    private void matchBit(char c, int fill) {\r
-        int i = (c) >> 3;\r
-        byte b = (byte) (c & 7);\r
-        b = (byte) (1 << b);\r
-        if (fill != 0)\r
-            bitmap[i] &= ~b;\r
-        else\r
-            bitmap[i] |= b;\r
-    }\r
-\r
-    private void checkRange(char lastc, int fill) {\r
-        matchBit(lastc, fill);\r
-        matchBit('-', fill);\r
-    }\r
-\r
-    void buildBitmap(MatchState state, char[] s, boolean fold) {\r
-        int index = ((Integer) kid).intValue();\r
-        int end = kid2;\r
-        byte fill = 0;\r
-        int i,n,ocp;\r
-        \r
-        boolean not = false;\r
-        kid2 = 0;\r
-        if (s[index] == '^') {\r
-            not = true;\r
-            kid2 = -1;\r
-            index++;\r
-        }\r
-        \r
-        calcBMSize(s, index, end, fold);\r
-        bitmap = new byte[bmsize];\r
-        if (not) {\r
-            fill = (byte)0xff;\r
-            for (i = 0; i < bmsize; i++)\r
-                bitmap[i] = (byte)0xff;\r
-            bitmap[0] = (byte)0xfe;\r
-        }\r
-        int nchars = bmsize * NativeRegExp.JS_BITS_PER_BYTE;\r
-        char lastc = (char)nchars;\r
-        boolean inrange = false;\r
-        \r
-        while (index < end) {\r
-            char c = s[index++];\r
-            if (c == '\\') {\r
-                c = s[index++];\r
-                switch (c) {\r
-                case 'b':\r
-                case 'f':\r
-                case 'n':\r
-                case 'r':\r
-                case 't':\r
-                case 'v':\r
-                    c = NativeRegExp.getEscape(c);\r
-                    break;\r
-\r
-                case 'd':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = '0'; c <= '9'; c++)\r
-                        matchBit(c, fill);\r
-                    continue;\r
-\r
-                case 'D':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = 0; c < '0'; c++)\r
-                        matchBit(c, fill);\r
-                    for (c = '9' + 1; c < nchars; c++)\r
-                        matchBit(c, fill);\r
-                    continue;\r
-\r
-                case 'w':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = 0; c < nchars; c++)\r
-                        if (NativeRegExp.isWord(c))\r
-                            matchBit(c, fill);\r
-                    continue;\r
-\r
-                case 'W':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = 0; c < nchars; c++)\r
-                        if (!NativeRegExp.isWord(c))\r
-                            matchBit(c, fill);\r
-                    continue;\r
-\r
-                case 's':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = 0; c < nchars; c++)\r
-                        if (Character.isWhitespace(c))\r
-                            matchBit(c, fill);\r
-                    continue;\r
-\r
-                case 'S':\r
-                    if (inrange)\r
-                        checkRange(lastc, fill);\r
-                    lastc = (char) nchars;\r
-                    for (c = 0; c < nchars; c++)\r
-                        if (!Character.isWhitespace(c))\r
-                            matchBit(c, fill);\r
-                    continue;\r
-\r
-                case '0':\r
-                case '1':\r
-                case '2':\r
-                case '3':\r
-                case '4':\r
-                case '5':\r
-                case '6':\r
-                case '7':\r
-                    n = NativeRegExp.unDigit(c);\r
-                    ocp = index - 2;\r
-                    c = s[index];\r
-                    if ('0' <= c && c <= '7') {\r
-                        index++;\r
-                        n = 8 * n + NativeRegExp.unDigit(c);\r
-\r
-                        c = s[index];\r
-                        if ('0' <= c && c <= '7') {\r
-                            index++;\r
-                            i = 8 * n + NativeRegExp.unDigit(c);\r
-                            if (i <= 0377)\r
-                                n = i;\r
-                            else\r
-                                index--;\r
-                        }\r
-                    }\r
-                    c = (char) n;\r
-                    break;\r
-\r
-                case 'x':\r
-                    ocp = index;\r
-                    if (index < s.length &&\r
-                        NativeRegExp.isHex(c = s[index++]))\r
-                        {\r
-                            n = NativeRegExp.unHex(c);\r
-                            if (index < s.length &&\r
-                                NativeRegExp.isHex(c = s[index++]))\r
-                                {\r
-                                    n <<= 4;\r
-                                    n += NativeRegExp.unHex(c);\r
-                                }\r
-                        } else {\r
-                            index = ocp;       /* \xZZ is xZZ (Perl does \0ZZ!) */\r
-                            n = 'x';\r
-                        }\r
-                    c = (char) n;\r
-                    break;\r
-\r
-                case 'u':\r
-                    if (s.length > index+3\r
-                        && NativeRegExp.isHex(s[index+0])\r
-                        && NativeRegExp.isHex(s[index+1]) \r
-                        && NativeRegExp.isHex(s[index+2])\r
-                        && NativeRegExp.isHex(s[index+3])) {\r
-                        n = (((((NativeRegExp.unHex(s[index+0]) << 4) +\r
-                                NativeRegExp.unHex(s[index+1])) << 4) +\r
-                              NativeRegExp.unHex(s[index+2])) << 4) +\r
-                            NativeRegExp.unHex(s[index+3]);\r
-                        c = (char) n;\r
-                        index += 4;\r
-                    }\r
-                    break;\r
-\r
-                case 'c':\r
-                    c = s[index++];\r
-                    c = Character.toUpperCase(c);\r
-                    c = (char) (c ^ 64); // JS_TOCTRL\r
-                    break;\r
-                }\r
-            }\r
-\r
-            if (inrange) {\r
-                if (lastc > c) {\r
-                    throw NativeGlobal.constructError(\r
-                                                      Context.getCurrentContext(), "RangeError",\r
-                                                      ScriptRuntime.getMessage(\r
-                                                                               "msg.bad.range", null),\r
-                                                      state.scope);\r
-                }\r
-                inrange = false;\r
-            } else {\r
-                // Set lastc so we match just c's bit in the for loop.\r
-                lastc = c;\r
-\r
-                // [balance:\r
-                if (index + 1 < end && s[index] == '-' &&\r
-                    s[index+1] != ']')\r
-                    {\r
-                        index++;\r
-                        inrange = true;\r
-                        continue;\r
-                    }\r
-            }\r
-\r
-            // Match characters in the range [lastc, c].\r
-            for (; lastc <= c; lastc++) {\r
-                matchBit(lastc, fill);\r
-                if (fold) {\r
-                    /*\r
-                     * Must do both upper and lower for Turkish dotless i,\r
-                     * Georgian, etc.\r
-                     */\r
-                    char foldc = Character.toUpperCase(lastc);\r
-                    matchBit(foldc, fill);\r
-                    foldc = Character.toLowerCase(foldc);\r
-                    matchBit(foldc, fill);\r
-                }\r
-            }\r
-            lastc = c;\r
-        }\r
-    }\r
-    byte            op;         /* packed r.e. op bytecode */\r
-    byte            flags;      /* flags, see below */\r
-    short           offset;     /* bytecode offset */\r
-    RENode          next;       /* next in concatenation order */\r
-    Object          kid;        /* first operand */\r
-    int             kid2;       /* second operand */\r
-    int             num;        /* could be a number */\r
-    char            chr;        /* or a char */\r
-    short           min,max;    /* or a range */\r
-    short           kidlen;     /* length of string at kid, in chars */\r
-    short           bmsize;     /* bitmap size, based on max char code */\r
-    char[]          s;          /* if null, use state.source */\r
-    byte[]          bitmap;     /* cclass bitmap */\r
-}\r
-\r
-\r
-class MatchState {\r
-    boolean    inputExhausted;         /* did we run out of input chars ? */\r
-    boolean     anchoring;              /* true if multiline anchoring ^/$ */\r
-    int         pcend;                  /* pc limit (fencepost) */\r
-    int         cpbegin, cpend;         /* cp base address and limit */\r
-    int         start;                  /* offset from cpbegin to start at */\r
-    int         skipped;                /* chars skipped anchoring this r.e. */\r
-    byte        flags;                  /* pennants  */\r
-    int         parenCount;             /* number of paren substring matches */\r
-    SubString[] maybeParens;            /* possible paren substring pointers */\r
-    SubString[] parens;                 /* certain paren substring matches */\r
-    Scriptable  scope;\r
-    char[]             input;\r
-\r
-    public int noMoreInput() {\r
-        inputExhausted = true;\r
-        /*\r
-        try {\r
-            throw new Exception();\r
-        }\r
-        catch (Exception e) {\r
-            e.printStackTrace();\r
-        }\r
-        */\r
-        return -1;\r
-    }\r
-}\r
-\r
-class GreedyState {\r
-    MatchState state;\r
-    RENode kid;\r
-    RENode next;\r
-    RENode stop;\r
-    int kidCount;\r
-    int maxKid;\r
-}\r
-\r
diff --git a/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java b/src/org/mozilla/javascript/regexp/NativeRegExpCtor.java
deleted file mode 100644 (file)
index 3b8e7c0..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1998.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-package org.mozilla.javascript.regexp;\r
-\r
-import org.mozilla.javascript.*;\r
-import java.lang.reflect.Method;\r
-\r
-/**\r
- * This class implements the RegExp constructor native object.\r
- *\r
- * Revision History:\r
- * Implementation in C by Brendan Eich\r
- * Initial port to Java by Norris Boyd from jsregexp.c version 1.36\r
- * Merged up to version 1.38, which included Unicode support.\r
- * Merged bug fixes in version 1.39.\r
- * Merged JSFUN13_BRANCH changes up to 1.32.2.11\r
- *\r
- * @author Brendan Eich\r
- * @author Norris Boyd\r
- */\r
-public class NativeRegExpCtor extends NativeFunction {\r
-\r
-    public NativeRegExpCtor() {\r
-        functionName = "RegExp";\r
-    }\r
-    \r
-    public String getClassName() {\r
-        return "Function";\r
-    }\r
-\r
-    public Object call(Context cx, Scriptable scope, Scriptable thisObj,\r
-                       Object[] args)\r
-    {\r
-        if (args.length > 0 && args[0] instanceof NativeRegExp &&\r
-            (args.length == 1 || args[1] == Undefined.instance))\r
-          {\r
-            return args[0];\r
-        }\r
-        return construct(cx, parent, args);\r
-    }\r
-\r
-    public Scriptable construct(Context cx, Scriptable scope, Object[] args) {\r
-        NativeRegExp re = new NativeRegExp();\r
-        re.compile(cx, scope, args);\r
-        re.setPrototype(getClassPrototype(scope, "RegExp"));\r
-        re.setParentScope(getParentScope());\r
-        return re;\r
-    }\r
-\r
-    static RegExpImpl getImpl() {\r
-        Context cx = Context.getCurrentContext();\r
-        return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);\r
-    }\r
-\r
-    protected int getIdDefaultAttributes(int id) {\r
-        int shifted = id - idBase;\r
-        if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
-            switch (shifted) {\r
-                case Id_multiline:\r
-                case Id_STAR:\r
-                case Id_input:\r
-                case Id_UNDERSCORE:\r
-                    return PERMANENT;\r
-            }\r
-            return PERMANENT | READONLY;\r
-        }\r
-        return super.getIdDefaultAttributes(id);\r
-    }\r
-    \r
-    private static String stringResult(Object obj) {\r
-        return (obj == null) ? "" : obj.toString();\r
-    }\r
-\r
-    protected Object getIdValue(int id) {\r
-        int shifted = id - idBase;\r
-        if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
-            RegExpImpl impl = getImpl();\r
-            switch (shifted) {\r
-                case Id_multiline:\r
-                case Id_STAR:\r
-                    return wrap_boolean(impl.multiline);\r
-\r
-                case Id_input:\r
-                case Id_UNDERSCORE: \r
-                    return stringResult(impl.input);\r
-\r
-                case Id_lastMatch:\r
-                case Id_AMPERSAND:\r
-                    return stringResult(impl.lastMatch);\r
-\r
-                case Id_lastParen:\r
-                case Id_PLUS:\r
-                    return stringResult(impl.lastParen);\r
-\r
-                case Id_leftContext:\r
-                case Id_BACK_QUOTE:\r
-                    return stringResult(impl.leftContext);\r
-\r
-                case Id_rightContext:\r
-                case Id_QUOTE:\r
-                    return stringResult(impl.rightContext);\r
-            }\r
-            // Must be one of $1..$9, convert to 0..8\r
-            int substring_number = shifted - DOLLAR_ID_BASE - 1;\r
-            return impl.getParenSubString(substring_number).toString();\r
-        }\r
-        return super.getIdValue(id);\r
-    }\r
-    \r
-    protected void setIdValue(int id, Object value) {\r
-        switch (id - idBase) {\r
-            case Id_multiline:\r
-            case Id_STAR:\r
-                getImpl().multiline = ScriptRuntime.toBoolean(value);\r
-                return;\r
-\r
-            case Id_input:\r
-            case Id_UNDERSCORE: \r
-                getImpl().input = ScriptRuntime.toString(value); \r
-                return;\r
-        }\r
-        super.setIdValue(id, value);\r
-    }\r
-\r
-    protected String getIdName(int id) {\r
-        int shifted = id - idBase;\r
-        if (1 <= shifted && shifted <= MAX_INSTANCE_ID) { \r
-            switch (shifted) {\r
-                case Id_multiline:    return "multiline";\r
-                case Id_STAR:         return "$*";\r
-\r
-                case Id_input:        return "input";\r
-                case Id_UNDERSCORE:   return "$_";\r
-\r
-                case Id_lastMatch:    return "lastMatch";\r
-                case Id_AMPERSAND:    return "$&";\r
-\r
-                case Id_lastParen:    return "lastParen";\r
-                case Id_PLUS:         return "$+";\r
-\r
-                case Id_leftContext:  return "leftContext";\r
-                case Id_BACK_QUOTE:   return "$`";\r
-\r
-                case Id_rightContext: return "rightContext";\r
-                case Id_QUOTE:        return "$'";\r
-            }\r
-            // Must be one of $1..$9, convert to 0..8\r
-            int substring_number = shifted - DOLLAR_ID_BASE - 1;\r
-            char[] buf = { '$', (char)('1' + substring_number) };\r
-            return new String(buf);\r
-        }\r
-        return super.getIdName(id);\r
-    }\r
-\r
-    protected int maxInstanceId() {\r
-        // Note: check for idBase == 0 can not be done in constructor, \r
-        // because IdScriptable calls maxInstanceId in its constructor\r
-        // before NativeRegExpCtor constructor gets chance to run any code\r
-        if (idBase == 0) { idBase = super.maxInstanceId(); }\r
-        return idBase + MAX_INSTANCE_ID; \r
-    }\r
-\r
-// #string_id_map#\r
-\r
-    private static final int\r
-        Id_multiline     = 1,\r
-        Id_STAR          = 2,  // #string=$*#\r
-\r
-        Id_input         = 3,\r
-        Id_UNDERSCORE    = 4,  // #string=$_#\r
-\r
-        Id_lastMatch     = 5,\r
-        Id_AMPERSAND     = 6,  // #string=$&#\r
-\r
-        Id_lastParen     = 7,\r
-        Id_PLUS          = 8,  // #string=$+#\r
-\r
-        Id_leftContext   = 9,\r
-        Id_BACK_QUOTE    = 10, // #string=$`#\r
-\r
-        Id_rightContext  = 11,\r
-        Id_QUOTE         = 12, // #string=$'#\r
-        \r
-        DOLLAR_ID_BASE   = 12;\r
-        \r
-    private static final int\r
-        Id_DOLLAR_1 = DOLLAR_ID_BASE + 1, // #string=$1#\r
-        Id_DOLLAR_2 = DOLLAR_ID_BASE + 2, // #string=$2#\r
-        Id_DOLLAR_3 = DOLLAR_ID_BASE + 3, // #string=$3#\r
-        Id_DOLLAR_4 = DOLLAR_ID_BASE + 4, // #string=$4#\r
-        Id_DOLLAR_5 = DOLLAR_ID_BASE + 5, // #string=$5#\r
-        Id_DOLLAR_6 = DOLLAR_ID_BASE + 6, // #string=$6#\r
-        Id_DOLLAR_7 = DOLLAR_ID_BASE + 7, // #string=$7#\r
-        Id_DOLLAR_8 = DOLLAR_ID_BASE + 8, // #string=$8#\r
-        Id_DOLLAR_9 = DOLLAR_ID_BASE + 9, // #string=$9#\r
-\r
-        MAX_INSTANCE_ID = DOLLAR_ID_BASE + 9;\r
-\r
-    protected int mapNameToId(String s) {\r
-        int id;\r
-// #generated# Last update: 2001-05-24 16:09:31 GMT+02:00\r
-        L0: { id = 0; String X = null; int c;\r
-            L: switch (s.length()) {\r
-            case 2: switch (s.charAt(1)) {\r
-                case '&': if (s.charAt(0)=='$') {id=Id_AMPERSAND; break L0;} break L;\r
-                case '\'': if (s.charAt(0)=='$') {id=Id_QUOTE; break L0;} break L;\r
-                case '*': if (s.charAt(0)=='$') {id=Id_STAR; break L0;} break L;\r
-                case '+': if (s.charAt(0)=='$') {id=Id_PLUS; break L0;} break L;\r
-                case '1': if (s.charAt(0)=='$') {id=Id_DOLLAR_1; break L0;} break L;\r
-                case '2': if (s.charAt(0)=='$') {id=Id_DOLLAR_2; break L0;} break L;\r
-                case '3': if (s.charAt(0)=='$') {id=Id_DOLLAR_3; break L0;} break L;\r
-                case '4': if (s.charAt(0)=='$') {id=Id_DOLLAR_4; break L0;} break L;\r
-                case '5': if (s.charAt(0)=='$') {id=Id_DOLLAR_5; break L0;} break L;\r
-                case '6': if (s.charAt(0)=='$') {id=Id_DOLLAR_6; break L0;} break L;\r
-                case '7': if (s.charAt(0)=='$') {id=Id_DOLLAR_7; break L0;} break L;\r
-                case '8': if (s.charAt(0)=='$') {id=Id_DOLLAR_8; break L0;} break L;\r
-                case '9': if (s.charAt(0)=='$') {id=Id_DOLLAR_9; break L0;} break L;\r
-                case '_': if (s.charAt(0)=='$') {id=Id_UNDERSCORE; break L0;} break L;\r
-                case '`': if (s.charAt(0)=='$') {id=Id_BACK_QUOTE; break L0;} break L;\r
-                } break L;\r
-            case 5: X="input";id=Id_input; break L;\r
-            case 9: c=s.charAt(4);\r
-                if (c=='M') { X="lastMatch";id=Id_lastMatch; }\r
-                else if (c=='P') { X="lastParen";id=Id_lastParen; }\r
-                else if (c=='i') { X="multiline";id=Id_multiline; }\r
-                break L;\r
-            case 11: X="leftContext";id=Id_leftContext; break L;\r
-            case 12: X="rightContext";id=Id_rightContext; break L;\r
-            }\r
-            if (X!=null && X!=s && !X.equals(s)) id = 0;\r
-        }\r
-// #/generated#\r
-// #/string_id_map#\r
-\r
-        return (id != 0) ? idBase + id : super.mapNameToId(s); \r
-    }\r
-    \r
-    private static int idBase;\r
-}\r
diff --git a/src/org/mozilla/javascript/regexp/RegExpImpl.java b/src/org/mozilla/javascript/regexp/RegExpImpl.java
deleted file mode 100644 (file)
index dcba755..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1998.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-package org.mozilla.javascript.regexp;\r
-\r
-import org.mozilla.javascript.*;\r
-import java.util.Vector;\r
-\r
-/**\r
- * \r
- */\r
-public class RegExpImpl implements RegExpProxy {\r
-    \r
-    public RegExpImpl() {\r
-        parens = new Vector(9);\r
-    }\r
-    \r
-    public boolean isRegExp(Object obj) {\r
-        return obj instanceof NativeRegExp;\r
-    }\r
-\r
-    public Object newRegExp(Context cx, Scriptable scope, String source, \r
-                                                String global, boolean flat)\r
-    {\r
-        return new NativeRegExp(cx, scope, source, global, flat);\r
-    }\r
-    \r
-    public Object match(Context cx, Scriptable scope, \r
-                        Scriptable thisObj, Object[] args)\r
-        throws JavaScriptException\r
-    {\r
-        MatchData mdata = new MatchData();\r
-        mdata.optarg = 1;\r
-        mdata.mode = GlobData.GLOB_MATCH;\r
-        mdata.parent = ScriptableObject.getTopLevelScope(scope);\r
-        Object rval = matchOrReplace(cx, scope, thisObj, args,\r
-                                     this, mdata, false);\r
-        return mdata.arrayobj == null ? rval : mdata.arrayobj;\r
-    }\r
-\r
-    public Object search(Context cx, Scriptable scope,\r
-                         Scriptable thisObj, Object[] args)\r
-        throws JavaScriptException\r
-    {\r
-        MatchData mdata = new MatchData();\r
-        mdata.optarg = 1;\r
-        mdata.mode = GlobData.GLOB_SEARCH;\r
-        mdata.parent = ScriptableObject.getTopLevelScope(scope);\r
-        return matchOrReplace(cx, scope, thisObj, args, this, mdata, false);\r
-    }\r
-\r
-    public Object replace(Context cx, Scriptable scope, \r
-                          Scriptable thisObj, Object[] args)\r
-        throws JavaScriptException\r
-    {\r
-        Object arg1 = args.length < 2 ? Undefined.instance : args[1];\r
-        String repstr = null;\r
-        Function lambda = null;\r
-        if (arg1 instanceof Function) {\r
-            lambda = (Function) arg1;\r
-        } else {\r
-            repstr = ScriptRuntime.toString(arg1);\r
-        }\r
-\r
-        ReplaceData rdata = new ReplaceData();\r
-        rdata.optarg = 2;\r
-        rdata.mode = GlobData.GLOB_REPLACE;\r
-        rdata.lambda = lambda;\r
-        rdata.repstr = repstr == null ? null : repstr.toCharArray();\r
-        rdata.dollar = repstr == null ? -1 : repstr.indexOf('$');\r
-        rdata.charArray = null;\r
-        rdata.length = 0;\r
-        rdata.index = 0;\r
-        rdata.leftIndex = 0;\r
-        Object val = matchOrReplace(cx, scope, thisObj, args,\r
-                                    this, rdata, true);\r
-        char[] charArray;\r
-\r
-        if (rdata.charArray == null) {\r
-            if (rdata.global || val == null || !val.equals(Boolean.TRUE)) {\r
-                /* Didn't match even once. */\r
-                return rdata.str;\r
-            }\r
-            int leftlen = this.leftContext.length;\r
-            int length = leftlen + rdata.findReplen(cx, this);\r
-            charArray = new char[length];\r
-            SubString leftContext = this.leftContext;\r
-            System.arraycopy(leftContext.charArray, leftContext.index,\r
-                             charArray, 0, leftlen);\r
-            rdata.doReplace(cx, this, charArray, leftlen);\r
-            rdata.charArray = charArray;\r
-            rdata.length = length;\r
-        }\r
-\r
-        SubString rc = this.rightContext;\r
-        int rightlen = rc.length;\r
-        int length = rdata.length + rightlen;\r
-        charArray = new char[length];\r
-        System.arraycopy(rdata.charArray, 0,\r
-                         charArray, 0, rdata.charArray.length);\r
-        System.arraycopy(rc.charArray, rc.index, charArray,\r
-                         rdata.length, rightlen);\r
-        return new String(charArray, 0, length);\r
-    }\r
-\r
-    /**\r
-     * Analog of C match_or_replace.\r
-     */\r
-    private static Object matchOrReplace(Context cx, Scriptable scope,\r
-                                         Scriptable thisObj, Object[] args, \r
-                                         RegExpImpl reImpl,\r
-                                         GlobData data, boolean forceFlat)\r
-        throws JavaScriptException\r
-    {\r
-        NativeRegExp re;\r
-\r
-        String str = ScriptRuntime.toString(thisObj);\r
-        data.str = str;\r
-        Scriptable topScope = ScriptableObject.getTopLevelScope(scope);\r
-        \r
-        if (args.length == 0)\r
-            re = new NativeRegExp(cx, topScope, "", "", false);\r
-        else\r
-            if (args[0] instanceof NativeRegExp) {\r
-                re = (NativeRegExp) args[0];\r
-            } else {\r
-                String src = ScriptRuntime.toString(args[0]);\r
-                String opt;\r
-                if (data.optarg < args.length) {\r
-                    args[0] = src;\r
-                    opt = ScriptRuntime.toString(args[data.optarg]);\r
-                } else {\r
-                    opt = null;\r
-                }                \r
-                re = new NativeRegExp(cx, topScope, src, opt, forceFlat);\r
-            }\r
-        data.regexp = re;\r
-\r
-        data.global = (re.getFlags() & NativeRegExp.GLOB) != 0;\r
-        int[] indexp = { 0 };\r
-        Object result = null;\r
-        if (data.mode == GlobData.GLOB_SEARCH) {\r
-            result = re.executeRegExp(cx, scope, reImpl,\r
-                                      str, indexp, NativeRegExp.TEST);\r
-            if (result != null && result.equals(Boolean.TRUE))\r
-                result = new Integer(reImpl.leftContext.length);\r
-            else\r
-                result = new Integer(-1);\r
-        } else if (data.global) {\r
-            re.setLastIndex(0);\r
-            for (int count = 0; indexp[0] <= str.length(); count++) {\r
-                result = re.executeRegExp(cx, scope, reImpl,\r
-                                          str, indexp, NativeRegExp.TEST);\r
-                if (result == null || !result.equals(Boolean.TRUE))\r
-                    break;\r
-                data.doGlobal(cx, scope, count, reImpl);\r
-                if (reImpl.lastMatch.length == 0) {\r
-                    if (indexp[0] == str.length())\r
-                        break;\r
-                    indexp[0]++;\r
-                }\r
-            }\r
-        } else {\r
-            result = re.executeRegExp(cx, scope, reImpl, str, indexp,\r
-                                      ((data.mode == GlobData.GLOB_REPLACE) \r
-                                       ? NativeRegExp.TEST \r
-                                       : NativeRegExp.MATCH));\r
-        }\r
-\r
-        return result;\r
-    } \r
-    \r
-    \r
-    \r
-    public int find_split(Scriptable scope, String target, String separator, \r
-                          Object reObj, int[] ip, int[] matchlen, \r
-                          boolean[] matched, String[][] parensp)\r
-    {\r
-        int i = ip[0];\r
-        int length = target.length();\r
-        int result;\r
-        Context cx = Context.getCurrentContext();\r
\r
-        int version = cx.getLanguageVersion();\r
-        NativeRegExp re = (NativeRegExp) reObj;\r
-        again:\r
-        while (true) {  // imitating C label\r
-            /* JS1.2 deviated from Perl by never matching at end of string. */\r
-            int ipsave = ip[0]; // reuse ip to save object creation\r
-            ip[0] = i;\r
-            Object ret = re.executeRegExp(cx, scope, this, target, ip,\r
-                                          NativeRegExp.TEST);\r
-            if (ret != Boolean.TRUE) {\r
-                // Mismatch: ensure our caller advances i past end of string.\r
-                ip[0] = ipsave;\r
-                matchlen[0] = 1;\r
-                matched[0] = false;\r
-                return length;\r
-            }\r
-            i = ip[0];\r
-            ip[0] = ipsave;\r
-            matched[0] = true;\r
-\r
-            SubString sep = this.lastMatch;\r
-            matchlen[0] = sep.length;\r
-            if (matchlen[0] == 0) {\r
-                /*\r
-                 * Empty string match: never split on an empty\r
-                 * match at the start of a find_split cycle.  Same\r
-                 * rule as for an empty global match in\r
-                 * match_or_replace.\r
-                 */\r
-                if (i == ip[0]) {\r
-                    /*\r
-                     * "Bump-along" to avoid sticking at an empty\r
-                     * match, but don't bump past end of string --\r
-                     * our caller must do that by adding\r
-                     * sep->length to our return value.\r
-                     */\r
-                    if (i == length) {\r
-                        if (version == Context.VERSION_1_2) {\r
-                            matchlen[0] = 1;\r
-                            result = i;\r
-                        }\r
-                        else\r
-                            result = -1;\r
-                        break;\r
-                    }\r
-                    i++;\r
-                    continue again; // imitating C goto\r
-                }\r
-            }\r
-            // PR_ASSERT((size_t)i >= sep->length);\r
-            result = i - matchlen[0];\r
-            break;\r
-        }\r
-        int size = parens.size();\r
-        parensp[0] = new String[size];\r
-        for (int num = 0; num < size; num++) {\r
-            SubString parsub = getParenSubString(num);\r
-            parensp[0][num] = parsub.toString();\r
-        }\r
-        return result;\r
-    }\r
-    \r
-    /**\r
-     * Analog of REGEXP_PAREN_SUBSTRING in C jsregexp.h.\r
-     * Assumes zero-based; i.e., for $3, i==2\r
-     */\r
-    SubString getParenSubString(int i) {\r
-        if (i >= parens.size())\r
-            return SubString.emptySubString;\r
-        return (SubString) parens.elementAt(i);\r
-    }\r
-\r
-    String          input;         /* input string to match (perl $_, GC root) */\r
-    boolean         multiline;     /* whether input contains newlines (perl $*) */\r
-    Vector          parens;        /* Vector of SubString; last set of parens\r
-                                      matched (perl $1, $2) */\r
-    SubString       lastMatch;     /* last string matched (perl $&) */\r
-    SubString       lastParen;     /* last paren matched (perl $+) */\r
-    SubString       leftContext;   /* input to left of last match (perl $`) */\r
-    SubString       rightContext;  /* input to right of last match (perl $') */\r
-}\r
-\r
-\r
-abstract class GlobData {\r
-    static final int GLOB_MATCH =      1;\r
-    static final int GLOB_REPLACE =    2;\r
-    static final int GLOB_SEARCH =     3;\r
-\r
-    abstract void doGlobal(Context cx, Scriptable scope, int count, \r
-                           RegExpImpl reImpl) \r
-        throws JavaScriptException;\r
-\r
-    byte     mode;      /* input: return index, match object, or void */\r
-    int      optarg;    /* input: index of optional flags argument */\r
-    boolean  global;    /* output: whether regexp was global */\r
-    String   str;       /* output: 'this' parameter object as string */\r
-    NativeRegExp regexp;/* output: regexp parameter object private data */\r
-    Scriptable parent;\r
-}\r
-\r
-\r
-class MatchData extends GlobData {\r
-\r
-    /*\r
-     * Analog of match_glob() in jsstr.c\r
-     */\r
-    void doGlobal(Context cx, Scriptable scope, int count, RegExpImpl reImpl) \r
-        throws JavaScriptException \r
-    {\r
-        MatchData mdata;\r
-        Object v;\r
-\r
-        mdata = this;\r
-        if (arrayobj == null) {\r
-            Scriptable s = ScriptableObject.getTopLevelScope(scope);\r
-            arrayobj = ScriptRuntime.newObject(cx, s, "Array", null);\r
-        }\r
-        SubString matchsub = reImpl.lastMatch;\r
-        String matchstr = matchsub.toString();\r
-        arrayobj.put(count, arrayobj, matchstr);\r
-    }\r
-\r
-    Scriptable arrayobj;\r
-}\r
-\r
-\r
-class ReplaceData extends GlobData {\r
-\r
-    ReplaceData() {\r
-        dollar = -1;\r
-    }\r
-\r
-    /*\r
-     * Analog of replace_glob() in jsstr.c\r
-     */\r
-    void doGlobal(Context cx, Scriptable scope, int count, RegExpImpl reImpl) \r
-        throws JavaScriptException\r
-    {\r
-        ReplaceData rdata = this;\r
-\r
-        SubString lc = reImpl.leftContext;\r
-\r
-        char[] leftArray = lc.charArray;\r
-        int leftIndex = rdata.leftIndex;\r
-        \r
-        int leftlen = reImpl.lastMatch.index - leftIndex;\r
-        rdata.leftIndex = reImpl.lastMatch.index + reImpl.lastMatch.length;\r
-        int replen = findReplen(cx, reImpl);\r
-        int growth = leftlen + replen;\r
-        char[] charArray;\r
-        if (rdata.charArray != null) {\r
-            charArray = new char[rdata.length + growth];\r
-            System.arraycopy(rdata.charArray, 0, charArray, 0, rdata.length);\r
-        } else {\r
-            charArray = new char[growth];\r
-        }\r
-\r
-        rdata.charArray = charArray;\r
-        rdata.length += growth;\r
-        int index = rdata.index;\r
-        rdata.index += growth;\r
-        System.arraycopy(leftArray, leftIndex, charArray, index, leftlen);\r
-        index += leftlen;\r
-        doReplace(cx, reImpl, charArray, index);\r
-    }\r
-\r
-    static SubString dollarStr = new SubString("$");\r
-\r
-    static SubString interpretDollar(Context cx, RegExpImpl res, \r
-                                     char[] da, int dp, int bp, int[] skip)\r
-    {\r
-        char[] ca;\r
-        int cp;\r
-        char dc;\r
-        int num, tmp;\r
-\r
-        /* Allow a real backslash (literal "\\") to escape "$1" etc. */\r
-        if (da[dp] != '$')\r
-            throw new RuntimeException();\r
-        if ((cx.getLanguageVersion() != Context.VERSION_DEFAULT)\r
-                 && (cx.getLanguageVersion() <= Context.VERSION_1_4))\r
-            if (dp > bp && da[dp-1] == '\\')\r
-                return null;\r
-\r
-        /* Interpret all Perl match-induced dollar variables. */\r
-        dc = da[dp+1];\r
-        if (NativeRegExp.isDigit(dc)) {            \r
-            if ((cx.getLanguageVersion() != Context.VERSION_DEFAULT)\r
-                     && (cx.getLanguageVersion() <= Context.VERSION_1_4)) {\r
-                if (dc == '0')\r
-                    return null;\r
-                /* Check for overflow to avoid gobbling arbitrary decimal digits. */\r
-                num = 0;\r
-                ca = da;\r
-                cp = dp;\r
-                while (++cp < ca.length && NativeRegExp.isDigit(dc = ca[cp])) {\r
-                    tmp = 10 * num + NativeRegExp.unDigit(dc);\r
-                    if (tmp < num)\r
-                        break;\r
-                    num = tmp;\r
-                }\r
-            }\r
-            else {  /* ECMA 3, 1-9 or 01-99 */\r
-                num = NativeRegExp.unDigit(dc);\r
-                cp = dp + 2;\r
-                if ((dp + 2) < da.length) {\r
-                    dc = da[dp + 2];\r
-                    if (NativeRegExp.isDigit(dc)) {\r
-                        num = 10 * num + NativeRegExp.unDigit(dc);\r
-                        cp++;\r
-                    }\r
-                }\r
-                if (num == 0) return null;  /* $0 or $00 is not valid */\r
-            }\r
-            /* Adjust num from 1 $n-origin to 0 array-index-origin. */\r
-            num--;\r
-            skip[0] = cp - dp;\r
-            return res.getParenSubString(num);\r
-        }\r
-\r
-        skip[0] = 2;\r
-        switch (dc) {\r
-          case '$':\r
-            return dollarStr;\r
-          case '&':\r
-            return res.lastMatch;\r
-          case '+':\r
-            return res.lastParen;\r
-          case '`':\r
-            if (cx.getLanguageVersion() == Context.VERSION_1_2) {\r
-                /*\r
-                 * JS1.2 imitated the Perl4 bug where left context at each step\r
-                 * in an iterative use of a global regexp started from last match,\r
-                 * not from the start of the target string.  But Perl4 does start\r
-                 * $` at the beginning of the target string when it is used in a\r
-                 * substitution, so we emulate that special case here.\r
-                 */\r
-                res.leftContext.index = 0;\r
-                res.leftContext.length = res.lastMatch.index;\r
-            }\r
-            return res.leftContext;\r
-          case '\'':\r
-            return res.rightContext;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Corresponds to find_replen in jsstr.c. rdata is 'this', and\r
-     * the result parameter sizep is the return value (errors are\r
-     * propagated with exceptions).\r
-     */\r
-    int findReplen(Context cx, RegExpImpl reImpl)\r
-        throws JavaScriptException\r
-    {\r
-        if (lambda != null) {\r
-            // invoke lambda function with args lastMatch, $1, $2, ... $n,\r
-            // leftContext.length, whole string.\r
-            Vector parens = reImpl.parens;\r
-            int parenCount = parens.size();\r
-            Object[] args = new Object[parenCount + 3];\r
-            args[0] = reImpl.lastMatch.toString();\r
-            for (int i=0; i < parenCount; i++) {\r
-                SubString sub = (SubString) parens.elementAt(i);\r
-                args[i+1] = sub.toString();\r
-            }\r
-            args[parenCount+1] = new Integer(reImpl.leftContext.length);\r
-            args[parenCount+2] = str;\r
-            Scriptable parent = lambda.getParentScope();\r
-            Object result = lambda.call(cx, parent, parent, args);\r
-\r
-            this.repstr = ScriptRuntime.toString(result).toCharArray();\r
-            return this.repstr.length;\r
-        }\r
-\r
-        int replen = this.repstr.length;\r
-        if (dollar == -1)\r
-            return replen;\r
-\r
-        int bp = 0;\r
-        for (int dp = dollar; dp < this.repstr.length ; ) {\r
-            char c = this.repstr[dp];\r
-            if (c != '$') {\r
-                dp++;\r
-                continue;\r
-            }\r
-            int[] skip = { 0 };\r
-            SubString sub = interpretDollar(cx, reImpl, this.repstr, dp,\r
-                                            bp, skip);\r
-            if (sub != null) {\r
-                replen += sub.length - skip[0];\r
-                dp += skip[0];\r
-            }\r
-            else\r
-                dp++;\r
-        }\r
-        return replen;\r
-    }\r
-\r
-    /**\r
-     * Analog of do_replace in jsstr.c\r
-     */\r
-    void doReplace(Context cx, RegExpImpl regExpImpl, char[] charArray,\r
-                   int arrayIndex)\r
-    {\r
-        int cp = 0;\r
-        char[] da = repstr;\r
-        int dp = this.dollar;\r
-        int bp = cp;\r
-        if (dp != -1) {\r
-          outer:\r
-            for (;;) {\r
-                int len = dp - cp;\r
-                System.arraycopy(repstr, cp, charArray, arrayIndex,\r
-                                 len);\r
-                arrayIndex += len;\r
-                cp = dp;\r
-                int[] skip = { 0 };\r
-                SubString sub = interpretDollar(cx, regExpImpl, da,\r
-                                                dp, bp, skip);\r
-                if (sub != null) {\r
-                    len = sub.length;\r
-                    if (len > 0) {\r
-                        System.arraycopy(sub.charArray, sub.index, charArray,\r
-                                         arrayIndex, len);\r
-                    }\r
-                    arrayIndex += len;\r
-                    cp += skip[0];\r
-                    dp += skip[0];\r
-                }\r
-                else\r
-                    dp++;\r
-                if (dp >= repstr.length) break;\r
-                while (repstr[dp] != '$') {\r
-                    dp++;\r
-                    if (dp >= repstr.length) break outer;\r
-                }\r
-            }\r
-        }\r
-        if (repstr.length > cp) {\r
-            System.arraycopy(repstr, cp, charArray, arrayIndex,\r
-                             repstr.length - cp);\r
-        }\r
-    }\r
-\r
-    Function    lambda;        /* replacement function object or null */\r
-    char[]      repstr;        /* replacement string */\r
-    int         dollar;        /* -1 or index of first $ in repstr */\r
-    char[]      charArray;     /* result characters, null initially */\r
-    int         length;        /* result length, 0 initially */\r
-    int         index;         /* index in result of next replacement */\r
-    int         leftIndex;     /* leftContext index, always 0 for JS1.2 */\r
-}\r
diff --git a/src/org/mozilla/javascript/regexp/SubString.java b/src/org/mozilla/javascript/regexp/SubString.java
deleted file mode 100644 (file)
index 90e0979..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
- *\r
- * The contents of this file are subject to the Netscape Public\r
- * License Version 1.1 (the "License"); you may not use this file\r
- * except in compliance with the License. You may obtain a copy of\r
- * the License at http://www.mozilla.org/NPL/\r
- *\r
- * Software distributed under the License is distributed on an "AS\r
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr\r
- * implied. See the License for the specific language governing\r
- * rights and limitations under the License.\r
- *\r
- * The Original Code is Rhino code, released\r
- * May 6, 1998.\r
- *\r
- * The Initial Developer of the Original Code is Netscape\r
- * Communications Corporation.  Portions created by Netscape are\r
- * Copyright (C) 1997-1999 Netscape Communications Corporation. All\r
- * Rights Reserved.\r
- *\r
- * Contributor(s): \r
- *\r
- * Alternatively, the contents of this file may be used under the\r
- * terms of the GNU Public License (the "GPL"), in which case the\r
- * provisions of the GPL are applicable instead of those above.\r
- * If you wish to allow use of your version of this file only\r
- * under the terms of the GPL and not to allow others to use your\r
- * version of this file under the NPL, indicate your decision by\r
- * deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL.  If you do not delete\r
- * the provisions above, a recipient may use your version of this\r
- * file under either the NPL or the GPL.\r
- */\r
-\r
-package org.mozilla.javascript.regexp;\r
-\r
-class SubString {\r
-\r
-    public SubString()\r
-    {\r
-    }\r
-    \r
-    public SubString(String str)\r
-    {\r
-        index = 0;\r
-        charArray = str.toCharArray();\r
-        length = str.length();\r
-    }\r
-\r
-    public String toString() {\r
-        return charArray == null\r
-               ? ""\r
-               : new String(charArray, index, length);\r
-    }\r
-\r
-    static final SubString emptySubString = new SubString();\r
-\r
-    char[] charArray;\r
-    int    index;\r
-    int    length;\r
-}\r
-\r
index 1e55cb8..2ab32b9 100644 (file)
@@ -4,8 +4,8 @@ package org.xwt;
 import java.io.*;
 import java.net.*;
 import java.util.*;
+import org.xwt.js.*;
 import org.xwt.util.*;
-import org.mozilla.javascript.*;
 
 /**
  *  <p>
@@ -82,7 +82,7 @@ import org.mozilla.javascript.*;
  *  uses x1,y1,x2,y2 tuples.
  * </p>
  */
-public final class Box extends JSObject {
+public final class Box extends JS.Scope {
 
 
     // Static Data //////////////////////////////////////////////////////////////
@@ -100,7 +100,7 @@ public final class Box extends JSObject {
     static Hash imageToNameMap = new Hash();
 
     /** the empty object, used for get-traps */
-    private static Object[] emptyobj = new Object[] { };
+    private static JS.Array emptyobj = new JS.Array();
 
 
     // Instance Data: Templates ////////////////////////////////////////////////////////
@@ -263,22 +263,18 @@ public final class Box extends JSObject {
     // Instance Data: IndexOf  ////////////////////////////////////////////////////////////
 
     /** The indexof() Function; created lazily */
-    public Function indexof = null;
-    public Function indexof() {
-        if (indexof == null) indexof = new IndexOf();
-        return indexof;
-    }
+    public JS.Function indexof = null;
+    public JS.Function indexof() { if (indexof == null) indexof = new IndexOf(); return indexof; }
 
     /** a trivial private class to serve as the box.indexof function object */
-    private class IndexOf extends JSObject implements Function {
+    private class IndexOf extends JS.Function {
         public IndexOf() { this.setSeal(true); }
-        public Scriptable construct(Context cx, Scriptable scope, java.lang.Object[] args) { return null; }
-        public Object call(Context cx, Scriptable scope, Scriptable thisObj, java.lang.Object[] args) throws JavaScriptException {
-            if (args == null || args.length != 1 || args[0] == null || !(args[0] instanceof Box)) return new Integer(-1);
-            Box b = (Box)args[0];
+        public Object _call(JS.Array args) throws JS.Exn {
+            if (args.length() != 1 || args.elementAt(0) == null || !(args.elementAt(0) instanceof Box)) return new Integer(-1);
+            Box b = (Box)args.elementAt(0);
             if (b.getParent() != Box.this) {
                 if (redirect == null || redirect == Box.this) return new Integer(-1);
-                return Box.this.redirect.indexof().call(cx, scope, thisObj, args);
+                return Box.this.redirect.indexof().call(args);
             }
             return new Integer(b.getIndexInParent());
         }
@@ -464,11 +460,13 @@ public final class Box extends JSObject {
                             if (ret != -1) bytesDownloaded += ret;
                             if (clear && callback != null) {
                                 clear = false;
-                                ThreadMessage.newthread(new JSObject.JSFunction() {
-                                        public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
+                                ThreadMessage.newthread(new JS.Function() {
+                                        public Object _call(JS.Array args_) throws JS.Exn {
                                             try {
-                                                callback.call(cx, null, null, new Object[] {
-                                                    new Double(bytesDownloaded), new Double(contentLength) });
+                                               JS.Array args = new JS.Array();
+                                               args.addElement(new Double(bytesDownloaded));
+                                               args.addElement(new Double(contentLength));
+                                               callback.call(args);
                                             } finally {
                                                 clear = true;
                                             }
@@ -520,8 +518,7 @@ public final class Box extends JSObject {
         } else {
             image = getPicture(s);
             if (image == null) {
-                if (Log.on) Log.log(Box.class, "unable to load image " + s + " at " +
-                                    Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                if (Log.on) Log.log(Box.class, "unable to load image " + s + " at " + JS.getCurrentFunctionSourceName());
                 return;
            }
             if (sizetoimage) syncSizeToImage();
@@ -542,8 +539,7 @@ public final class Box extends JSObject {
             if (border == null) {
                 ImageDecoder id = getImage(s, null);
                 if (id == null) {
-                    if (Log.on) Log.log(this, "unable to load border image " + s + " at " +
-                                    Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                    if (Log.on) Log.log(this, "unable to load border image " + s + " at " + JS.getCurrentFunctionSourceName());
                     return;
                 }
                 int[] data = id.getData();
@@ -588,21 +584,10 @@ public final class Box extends JSObject {
     }
 
     /** returns true if the property has a trap on it */
-    boolean is_trapped(String property) {
-        if (traps == null) {
-            return false;
-        } else {
-            Object gc = traps.get(property);
-            return (gc != null &&
-                    !(gc instanceof org.mozilla.javascript.Undefined) &&
-                    gc != org.mozilla.javascript.Scriptable.NOT_FOUND);
-        }
-    }
+    boolean is_trapped(String property) { return traps != null && traps.get(property) != null; }
     
     /** Adds the node's current actual geometry to the Surface's dirty list */
-    void dirty() {
-        dirty(pos(0), pos(1), size(0), size(1));
-    }
+    void dirty() { dirty(pos(0), pos(1), size(0), size(1)); }
 
     /** Adds the intersection of (x,y,w,h) and the node's current actual geometry to the Surface's dirty list */
     public final void dirty(int x, int y, int w, int h) {
@@ -632,9 +617,9 @@ public final class Box extends JSObject {
 
         if (!wasinside && !isinside) return;
         
-        if (!wasinside && isinside && is_trapped("Enter")) put("Enter", null, this);
-        else if (wasinside && !isinside && is_trapped("Leave")) put("Leave", null, this);
-        else if (wasinside && isinside && (mousex != oldmousex || mousey != oldmousey) && is_trapped("Move")) put("Move", null, this);
+        if (!wasinside && isinside && is_trapped("Enter")) put("Enter", this);
+        else if (wasinside && !isinside && is_trapped("Leave")) put("Leave", this);
+        else if (wasinside && isinside && (mousex != oldmousex || mousey != oldmousey) && is_trapped("Move")) put("Move", this);
 
         if (isinside && cursor != null && surface != null) surface.cursor = cursor;
 
@@ -650,7 +635,7 @@ public final class Box extends JSObject {
 
     /** creates a new box from an anonymous template; <tt>ids</tt> is passed through to Template.apply() */
     Box(Template anonymous, Vec pboxes, Vec ptemplates, Function callback, int numerator, int denominator) {
-        super(true);
+        super(null);
         set(dmax, 0, Integer.MAX_VALUE);
         set(dmax, 1, Integer.MAX_VALUE);
         template = anonymous;
@@ -662,7 +647,7 @@ public final class Box extends JSObject {
     /** creates a new box from an unresolved templatename and an importlist; use "box" for an untemplatized box */
     public Box(String templatename, String[] importlist) { this(templatename, importlist, null); }
     public Box(String templatename, String[] importlist, Function callback) {
-        super(true);
+        super(null);
         set(dmax, 0, Integer.MAX_VALUE);
         set(dmax, 1, Integer.MAX_VALUE);
         this.importlist = importlist;
@@ -756,16 +741,18 @@ public final class Box extends JSObject {
         if (++surface.sizePosChangesSinceLastRender >= 500) {
             if (surface.sizePosChangesSinceLastRender == 500) {
                 if (Log.on) Log.log(this, "Warning, more than 500 SizeChange/PosChange traps triggered since last complete render");
-                if (Log.on) Log.log(this, "    interpreter is at " + Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                if (Log.on) Log.log(this, "    interpreter is at " + JS.getCurrentFunctionSourceName());
+           /*
                 try {
                     Trap t = sizechange ? Trap.getTrap(this, "SizeChange") : Trap.getTrap(this, "PosChange");
                     InterpretedFunction f = (InterpretedFunction)t.f;
                     if (Log.on) Log.log(this, "Current trap is at " + f.getSourceName() + ":" + f.getLineNumbers()[0]);
                 } catch (Throwable t) { }
+           */
             }
         } else {
-            if (sizechange) put("SizeChange", null, Boolean.TRUE);
-            if (poschange) put("PosChange", null, Boolean.TRUE);
+            if (sizechange) put("SizeChange", Boolean.TRUE);
+            if (poschange) put("PosChange", Boolean.TRUE);
             if (sizechange || poschange) {
                 surface.abort = true;
                 return;
@@ -1072,9 +1059,9 @@ public final class Box extends JSObject {
     // Methods to implement org.mozilla.javascript.Scriptable //////////////////////////////////////
 
     /** Returns the i_th child */
-    public Object get(int i, Scriptable start) {
+    public Object get(int i) {
         if (redirect == null) return null;
-        if (redirect != this) return redirect.get(i, start);
+        if (redirect != this) return redirect.get(i);
         return i >= numChildren() ? null : getChild(i);
     }
 
@@ -1084,31 +1071,27 @@ public final class Box extends JSObject {
      *  INVARIANT: after completion, getChild(min(i, numChildren())) == newnode
      *  WARNING: O(n) runtime, unless i == numChildren()
      */
-    public void put(int i, Scriptable start, Object value) {
+    public void put(int i, Object value) {
 
         if (value != null && !(value instanceof Box)) {
-            if (Log.on) Log.log(this, "attempt to set a numerical property on a box to anything other than a box at " +
-                                Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+            if (Log.on) Log.log(this, "attempt to set a numerical property on a box to anything other than a box at " + JS.getCurrentFunctionSourceName());
 
         } else if (redirect == null) {
-            if (Log.on) Log.log(this, "attempt to add/remove children to/from a node with a null redirect at " + 
-                                Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
-
+            if (Log.on) Log.log(this, "attempt to add/remove children to/from a node with a null redirect at " +  JS.getCurrentFunctionSourceName());
         } else if (redirect != this) {
-            Box b = value == null ? (Box)redirect.get(i, null) : (Box)value;
-            redirect.put(i, null, value);
-            put("0", null, b);
+            Box b = value == null ? (Box)redirect.get(i) : (Box)value;
+            redirect.put(i, value);
+            put("0", b);
 
         } else if (value == null) {
             if (i >= 0 && i < numChildren()) {
                 Box b = getChild(i);
                 b.remove();
-                put("0", null, b);
+                put("0", b);
             }
 
         } else if (value instanceof RootProxy) {
-            if (Log.on) Log.log(this, "attempt to reparent a box via its proxy object at " +
-                                Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+            if (Log.on) Log.log(this, "attempt to reparent a box via its proxy object at " + JS.getCurrentFunctionSourceName());
 
         } else {
             Box newnode = (Box)value;
@@ -1116,16 +1099,14 @@ public final class Box extends JSObject {
             // check if box being moved is currently target of a redirect
             for(Box cur = newnode.getParent(); cur != null; cur = cur.getParent())
                 if (cur.redirect == newnode) {
-                    if (Log.on) Log.log(this, "attempt to move a box that is the target of a redirect at "+
-                                        Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                    if (Log.on) Log.log(this, "attempt to move a box that is the target of a redirect at "+ JS.getCurrentFunctionSourceName());
                     return;
                 }
 
             // check for recursive ancestor violation
             for(Box cur = this; cur != null; cur = cur.getParent())
                 if (cur == newnode) {
-                    if (Log.on) Log.log(this, "attempt to make a node a parent of its own ancestor at " + 
-                                        Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                    if (Log.on) Log.log(this, "attempt to make a node a parent of its own ancestor at " + JS.getCurrentFunctionSourceName());
                     return;
                 }
 
@@ -1174,21 +1155,16 @@ public final class Box extends JSObject {
             sync_cmin_to_children();
 
             // note that JavaScript box[0] will invoke put(int i), not put(String s)
-            put("0", null, newnode);
+            put("0", newnode);
         }
     }
     
-    public Object get(String name, Scriptable start) { return get(name, start, false); }
-    public Object get(String name, Scriptable start, boolean ignoretraps) {
-
-        if (name == null || name.equals("")) return null;
+    public Object get(Object name) { return get(name, false); }
+    public Object get(Object name_, boolean ignoretraps) {
+       if (name_ instanceof Number) return get(((Number)name_).intValue());
 
-        // hack since Rhino needs to be able to grab these functions to create new objects
-        if (name.equals("Object")) return JSObject.defaultObjects.get("Object", null);
-        if (name.equals("Array")) return JSObject.defaultObjects.get("Array", null);
-        if (name.equals("Function")) return JSObject.defaultObjects.get("Function", null);
-        if (name.equals("TypeError")) return JSObject.defaultObjects.get("TypeError", null);
-        if (name.equals("ConversionError")) return JSObject.defaultObjects.get("ConversionError", null);
+       String name = (String)name_;
+        if (name.equals("")) return null;
 
         // See if we're reading back the function value of a trap
         if (name.charAt(0) == '_') {
@@ -1206,55 +1182,41 @@ public final class Box extends JSObject {
         SpecialBoxProperty gph = (SpecialBoxProperty)SpecialBoxProperty.specialBoxProperties.get(name);
         if (gph != null) return gph.get(this);
 
-        Object ret = super.get(name, start);
+        Object ret = super.get(name);
         if (name.startsWith("$") && ret == null)
             if (Log.on) Log.log(this, "WARNING: attempt to access " + name + ", but no child with id=\"" + name.substring(1) + "\" found; " +
-                                Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                                JS.getFileAndLine());
         return ret;
     }
 
-    /** indicate that we don't want JSObject trying to handle these */
-    public boolean has(String name, Scriptable start) {
-        if (name.equals("")) return false;
-        if (traps != null && traps.get(name) != null) return true;
-        if (name.charAt(0) == '_') return true;
-        if (SpecialBoxProperty.specialBoxProperties.get(name) != null) return true;
-        if (name.equals("Function") || name.equals("Array") || name.equals("Object") ||
-            name.equals("TypeError") || name.equals("ConversionError")) return true;
-        return super.has(name, start);
-    }
-
-    public Object[] getIds() {
+    public Object[] keys() {
         Object[] ret = new Object[numChildren()];
-        for(int i=0; i<ret.length; i++) ret[i] = get(i, null);
+        for(int i=0; i<ret.length; i++) ret[i] = get(i);
         return ret;
     }
 
-    public void put(String name, Scriptable start, Object value) { put(name, start, value, false, null); }
-    public void put(String name, Scriptable start, Object value, boolean ignoretraps) { put(name, start, value, ignoretraps, null); }
-
     /**
      *  Scriptable.put()
      *  @param ignoretraps if set, no traps will be triggered (set when 'cascade' reaches the bottom of the trap stack)
      *  @param rp if this put is being performed via a root proxy, rp is the root proxy.
      */
-    public void put(String name, Scriptable start, Object value, boolean ignoretraps, RootProxy rp) {
-        if (name == null) return;
+    public void put(Object name, Object value) { put(name, value, false, null); }
+    public void put(Object name, Object value, boolean ignoretraps) { put(name, value, ignoretraps, null); }
+    public void put(Object name_, Object value, boolean ignoretraps, RootProxy rp) {
+       if (name_ instanceof Number) { put(((Number)name_).intValue(), value); return; }
+       String name = (String)name_;
         if (name.startsWith("xwt_")) {
-            if (Log.on) Log.log(this, "attempt to set reserved property " + name + " at " +
-                                Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+            if (Log.on) Log.log(this, "attempt to set reserved property " + name + " at " + JS.getFileAndLine());
             return;
-        }
+       }
 
         if (!ignoretraps && traps != null) {
             Trap t = (Trap)traps.get(name);
             if (t != null) {
-                Object[] arg = (Object[])singleObjects.remove(false);
-                if (arg == null) arg = new Object[] { value };
-                else arg[0] = value;
+                JS.Array arg = new JS.Array();
+               arg.addElement(value);
                 t.perform(arg);
-                arg[0] = null;
-                singleObjects.append(arg);
+                arg.setElementAt(null, 0);
                 return;
             }
         }
@@ -1270,8 +1232,7 @@ public final class Box extends JSObject {
 
         if (name.charAt(0) == '_') {
             if (value != null && !(value instanceof Function)) {
-                if (Log.on) Log.log(this, "attempt to put a non-function value to " + name + " at " + 
-                                    Context.enter().interpreterSourceFile + ":" + Context.enter().interpreterLine);
+                if (Log.on) Log.log(this, "attempt to put a non-function value to " + name + " at " + JS.getFileAndLine());
             } else if (name.charAt(1) == '_') {
                 name = name.substring(2).intern();
                 Trap t = Trap.getTrap(this, name);
@@ -1286,12 +1247,7 @@ public final class Box extends JSObject {
             return;
         }
 
-        if (ignoretraps) {
-            // traps always cascade to the global property, not the local one
-            putGlobally(name, start, value);
-        } else {
-            super.put(name, start, value);
-        }
+       super.put(name, value);
 
         // a bit of a hack, since titlebar is the only 'special' property stored in JSObject
         if (getParent() == null && surface != null) {
@@ -1304,9 +1260,6 @@ public final class Box extends JSObject {
         }
     }
 
-    /** the <tt>delete</tt> keyword is not valid in XWT scripts */
-    public void delete(int i) { }
-
 
     // Tree Manipulation /////////////////////////////////////////////////////////////////////
 
@@ -1370,7 +1323,7 @@ public final class Box extends JSObject {
         setSurface(null);
 
         // note that JavaScript box[0] will invoke put(int i), not put(String s)
-        if (oldparent != null) oldparent.put("0", null, this);
+        if (oldparent != null) oldparent.put("0", this);
     }
 
     /** returns our next sibling (parent[ourindex + 1]) */
@@ -1450,35 +1403,17 @@ public final class Box extends JSObject {
     // Root Proxy ///////////////////////////////////////////////////////////////////////////////
 
     RootProxy myproxy = null;
-    public Scriptable getRootProxy() {
+    public JS getRootProxy() {
         if (myproxy == null) myproxy = new RootProxy(this);
         return myproxy;
     }
 
-    private static class RootProxy implements Scriptable {
-
+    private static class RootProxy extends JS {
         Box box;
         RootProxy(Box b) { this.box = b; }
-
-        public void delete(String name) { box.delete(name); }
-        public Scriptable getParentScope() { return box.getParentScope(); }
-        public void setParentScope(Scriptable p) { box.setParentScope(p); }
-        public boolean hasInstance(Scriptable value) { return box.hasInstance(value); }
-        public Scriptable getPrototype() { return box.getPrototype(); }
-        public void setPrototype(Scriptable p) { box.setPrototype(p); }
-        public void delete(int i) { box.delete(i); }
-        public String getClassName() { return box.getClassName(); }
-        public Object getDefaultValue(Class hint) { return box.getDefaultValue(hint); }
-
-        public void put(int i, Scriptable start, Object value) { if (value != null) box.put(i, start, value); }
-        public Object get(String name, Scriptable start) { return box.get(name, start); }
-        public Object get(int i, Scriptable start) { return null; }
-
-        public void put(String name, Scriptable start, Object value) { box.put(name, start, value, false, this); }
-        public boolean has(String name, Scriptable start) { return box.has(name, start); }
-        public boolean has(int i, Scriptable start) { return box.has(i, start); }
-        public Object[] getIds() { return box.getIds(); }
-
+        public Object get(Object name) { return box.get(name); }
+        public void put(Object name, Object value) { box.put(name, value, false, this); }
+        public Object[] keys() { return box.keys(); }
     }