зеркало из https://github.com/mozilla/pjs.git
Fix bug 414098 - Support for __define[GS]etter__ on array indexes
Patch from Matthieu Riou
This commit is contained in:
Родитель
7535fa175e
Коммит
a4164076c6
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче