diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java index 4808b553280..da8a9181c04 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Context.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Context.java @@ -2187,7 +2187,8 @@ public class Context { // for Objects, Arrays to tag themselves as being printed out, // so they don't print themselves out recursively. - Hashtable iterating; + // Use ObjToIntMap instead of java.util.HashSet for JDK 1.1 compatibility + ObjToIntMap iterating; Object interpreterSecurityDomain; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java index 2c15ece845f..d7a18b9f55d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeArray.java @@ -461,11 +461,7 @@ public class NativeArray extends IdScriptable { long length = (long)getLengthProperty(thisObj); - StringBuffer result = new StringBuffer(); - - if (cx.iterating == null) - cx.iterating = new Hashtable(31); - boolean iterating = cx.iterating.get(thisObj) == Boolean.TRUE; + StringBuffer result = new StringBuffer(256); // whether to return '4,unquoted,5' or '[4, "quoted", 5]' String separator; @@ -480,33 +476,40 @@ public class NativeArray extends IdScriptable { boolean haslast = false; long i = 0; - if (!iterating) { - for (i = 0; i < length; i++) { - if (i > 0) result.append(separator); - Object elem = getElem(thisObj, i); - if (elem == null || elem == Undefined.instance) { - haslast = false; - continue; - } - haslast = true; + boolean toplevel, iterating; + if (cx.iterating == null) { + toplevel = true; + iterating = false; + cx.iterating = new ObjToIntMap(31); + }else { + toplevel = false; + iterating = cx.iterating.has(thisObj); + } - if (elem instanceof String) { - String s = (String)elem; - if (toSource) { - result.append('\"'); - result.append(ScriptRuntime.escapeString(s)); - result.append('\"'); - } else { - result.append(s); + // Make sure cx.iterating is set to null when done + // so we don't leak memory + try { + if (!iterating) { + cx.iterating.put(thisObj, 0); // stop recursion. + for (i = 0; i < length; i++) { + if (i > 0) result.append(separator); + Object elem = getElem(thisObj, i); + if (elem == null || elem == Undefined.instance) { + haslast = false; + continue; } - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. */ - try { - // stop recursion. - cx.iterating.put(thisObj, Boolean.TRUE); + haslast = true; + + if (elem instanceof String) { + String s = (String)elem; + if (toSource) { + result.append('\"'); + result.append(ScriptRuntime.escapeString(s)); + result.append('\"'); + } else { + result.append(s); + } + } else { if (toLocale && elem != Undefined.instance && elem != null) { @@ -518,11 +521,13 @@ public class NativeArray extends IdScriptable { ScriptRuntime.emptyArgs); } result.append(ScriptRuntime.toString(elem)); - } finally { - cx.iterating.remove(thisObj); } } } + }finally { + if (toplevel) { + cx.iterating = null; + } } if (toSource) { diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java b/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java index 42c8f394b09..0d1b769b85d 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NativeObject.java @@ -142,48 +142,51 @@ public class NativeObject extends IdScriptable { private static String toSource(Context cx, Scriptable thisObj) { - Scriptable m = thisObj; + StringBuffer result = new StringBuffer(256); + result.append('{'); - if (cx.iterating == null) - cx.iterating = new Hashtable(31); + boolean toplevel, iterating; + if (cx.iterating == null) { + toplevel = true; + iterating = false; + cx.iterating = new ObjToIntMap(31); + }else { + toplevel = false; + iterating = cx.iterating.has(thisObj); + } - if (cx.iterating.get(m) == Boolean.TRUE) { - return "{}"; // stop recursion - } else { - StringBuffer result = new StringBuffer("{"); - Object[] ids = m.getIds(); - - for(int i=0; i < ids.length; i++) { - if (i > 0) - result.append(", "); - - Object id = ids[i]; - String idString = ScriptRuntime.toString(id); - Object p = (id instanceof String) - ? m.get((String) id, m) - : m.get(((Number) id).intValue(), m); - if (p instanceof String) { - result.append(idString + ":\"" - + ScriptRuntime - .escapeString(ScriptRuntime.toString(p)) - + "\""); - } else { - /* wrap changes to cx.iterating in a try/finally - * so that the reference always gets removed, and - * we don't leak memory. Good place for weak - * references, if we had them. - */ - try { - cx.iterating.put(m, Boolean.TRUE); // stop recursion. - result.append(idString + ":" + ScriptRuntime.toString(p)); - } finally { - cx.iterating.remove(m); + // Make sure cx.iterating is set to null when done + // so we don't leak memory + try { + if (!iterating) { + cx.iterating.put(thisObj, 0); // stop recursion. + Object[] ids = thisObj.getIds(); + for(int i=0; i < ids.length; i++) { + if (i > 0) + result.append(", "); + Object id = ids[i]; + result.append(id); + result.append(':'); + Object p = (id instanceof String) + ? thisObj.get((String) id, thisObj) + : thisObj.get(((Integer) id).intValue(), thisObj); + if (p instanceof String) { + result.append('\"'); + result.append(ScriptRuntime.escapeString((String)p)); + result.append('\"'); + }else { + result.append(ScriptRuntime.toString(p)); } } } - result.append('}'); - return result.toString(); + }finally { + if (toplevel) { + cx.iterating = null; + } } + + result.append('}'); + return result.toString(); } private static Object jsFunction_valueOf(Scriptable thisObj) {