| 103 | } |
| 104 | |
| 105 | private static Object walk( |
| 106 | Context cx, VarScope scope, Callable reviver, Scriptable holder, Object name) { |
| 107 | final Object property; |
| 108 | if (name instanceof Number) { |
| 109 | property = holder.get(((Number) name).intValue(), holder); |
| 110 | } else { |
| 111 | property = holder.get(((String) name), holder); |
| 112 | } |
| 113 | |
| 114 | if (property instanceof Scriptable) { |
| 115 | Scriptable val = ((Scriptable) property); |
| 116 | if (val instanceof NativeArray) { |
| 117 | long len = ((NativeArray) val).getLength(); |
| 118 | for (long i = 0; i < len; i++) { |
| 119 | // indices greater than MAX_INT are represented as strings |
| 120 | if (i > Integer.MAX_VALUE) { |
| 121 | String id = Long.toString(i); |
| 122 | Object newElement = walk(cx, scope, reviver, val, id); |
| 123 | if (newElement == Undefined.instance) { |
| 124 | val.delete(id); |
| 125 | } else { |
| 126 | val.put(id, val, newElement); |
| 127 | } |
| 128 | } else { |
| 129 | int idx = (int) i; |
| 130 | Object newElement = walk(cx, scope, reviver, val, Integer.valueOf(idx)); |
| 131 | if (newElement == Undefined.instance) { |
| 132 | val.delete(idx); |
| 133 | } else { |
| 134 | val.put(idx, val, newElement); |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | } else { |
| 139 | Object[] keys = val.getIds(); |
| 140 | for (Object p : keys) { |
| 141 | Object newElement = walk(cx, scope, reviver, val, p); |
| 142 | if (newElement == Undefined.instance) { |
| 143 | if (p instanceof Number) val.delete(((Number) p).intValue()); |
| 144 | else val.delete((String) p); |
| 145 | } else { |
| 146 | if (p instanceof Number) val.put(((Number) p).intValue(), val, newElement); |
| 147 | else val.put((String) p, val, newElement); |
| 148 | } |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | return reviver.call(cx, scope, holder, new Object[] {name, property}); |
| 154 | } |
| 155 | |
| 156 | private static String repeat(char c, int count) { |
| 157 | char[] chars = new char[count]; |