diff --git a/js/rhino/src/org/mozilla/javascript/NativeArray.java b/js/rhino/src/org/mozilla/javascript/NativeArray.java index 47331244457..559089ad440 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeArray.java +++ b/js/rhino/src/org/mozilla/javascript/NativeArray.java @@ -310,6 +310,8 @@ public class NativeArray extends IdScriptableObject public synchronized Object get(int index, Scriptable start) { + if (isGetterOrSetter(null, index, false)) + return super.get(index, start); if (dense != null && 0 <= index && index < dense.length) return dense[index]; return super.get(index, start); @@ -317,6 +319,8 @@ public class NativeArray extends IdScriptableObject public synchronized boolean has(int index, Scriptable start) { + if (isGetterOrSetter(null, index, false)) + return super.has(index, start); if (dense != null && 0 <= index && index < dense.length) return dense[index] != NOT_FOUND; return super.has(index, start); @@ -372,6 +376,8 @@ public class NativeArray extends IdScriptableObject public synchronized void put(int index, Scriptable start, Object value) { + if (isGetterOrSetter(null, index, true)) + super.put(index, start, value); if (start == this && !isSealed() && dense != null && 0 <= index) { if (index < dense.length) { dense[index] = value; @@ -401,6 +407,8 @@ public class NativeArray extends IdScriptableObject public synchronized void delete(int index) { + if (isGetterOrSetter(null, index, true)) + super.delete(index); if (!isSealed() && dense != null && 0 <= index && index < dense.length) { dense[index] = NOT_FOUND; @@ -485,6 +493,21 @@ public class NativeArray extends IdScriptableObject public long jsGet_length() { return getLength(); } + + /** + * Change the value of the internal flag that determines whether all + * storage is handed by a dense backing array rather than an associative + * store. + * @param denseOnly new value for denseOnly flag + * @throws IllegalArgumentException if an attempt is made to enable + * denseOnly after it was disabled; NativeArray code is not written + * to handle switching back to a dense representation + */ + void setDenseOnly(boolean denseOnly) { + if (denseOnly && !this.denseOnly) + throw new IllegalArgumentException(); + this.denseOnly = denseOnly; + } private synchronized void setLength(Object val) { /* XXX do we satisfy this? @@ -1630,7 +1653,7 @@ public class NativeArray extends IdScriptableObject // #/generated# return id; } - + private static final int Id_constructor = 1, Id_toString = 2, diff --git a/js/rhino/src/org/mozilla/javascript/NativeObject.java b/js/rhino/src/org/mozilla/javascript/NativeObject.java index 0d461e7b0e4..19aff634c3a 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeObject.java +++ b/js/rhino/src/org/mozilla/javascript/NativeObject.java @@ -215,6 +215,8 @@ public class NativeObject extends IdScriptableObject Callable getterOrSetter = (Callable)args[1]; boolean isSetter = (id == Id___defineSetter__); so.setGetterOrSetter(name, index, getterOrSetter, isSetter); + if (so instanceof NativeArray) + ((NativeArray)so).setDenseOnly(false); } return Undefined.instance; diff --git a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java index 0a0ec212a42..4fa68469dc8 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptableObject.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptableObject.java @@ -582,6 +582,22 @@ public abstract class ScriptableObject implements Scriptable, Serializable, return Undefined.instance; } + /** + * Returns whether a property is a getter or a setter + * @param name property name + * @param index property index + * @param setter true to check for a setter, false for a getter + * @return whether the property is a getter or a setter + */ + protected boolean isGetterOrSetter(String name, int index, boolean setter) { + Slot slot = getSlot(name, index, SLOT_QUERY); + if (slot instanceof GetterSlot) { + if (setter && ((GetterSlot)slot).setter != null) return true; + if (!setter && ((GetterSlot)slot).getter != null) return true; + } + return false; + } + void addLazilyInitializedValue(String name, int index, LazilyLoadedCtor init, int attributes) { @@ -1963,9 +1979,9 @@ public abstract class ScriptableObject implements Scriptable, Serializable, } return nativeGetter.invoke(getterThis, args); } else { - Callable f = (Callable)getterObj; + Function f = (Function)getterObj; Context cx = Context.getContext(); - return f.call(cx, ScriptRuntime.getTopCallScope(cx), start, + return f.call(cx, f.getParentScope(), start, ScriptRuntime.emptyArgs); } } @@ -2046,8 +2062,8 @@ public abstract class ScriptableObject implements Scriptable, Serializable, } nativeSetter.invoke(setterThis, args); } else { - Callable f = (Callable)setterObj; - f.call(cx, ScriptRuntime.getTopCallScope(cx), start, + Function f = (Function)setterObj; + f.call(cx, f.getParentScope(), start, new Object[] { value }); } return true;