зеркало из https://github.com/mozilla/pjs.git
Fixing the bug 157196: custom serialization of ScriptableObject not to save deleted/empty slot.
This commit is contained in:
Родитель
b9861f3df6
Коммит
05d4e426a8
|
@ -1355,8 +1355,10 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
*
|
*
|
||||||
* @since 1.4R3
|
* @since 1.4R3
|
||||||
*/
|
*/
|
||||||
public void sealObject() {
|
public synchronized void sealObject() {
|
||||||
count = -1;
|
if (count >= 0) {
|
||||||
|
count = -1 - count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1369,7 +1371,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
* @since 1.4R3
|
* @since 1.4R3
|
||||||
*/
|
*/
|
||||||
public boolean isSealed() {
|
public boolean isSealed() {
|
||||||
return count == -1;
|
return count < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1565,9 +1567,10 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
Object fun = getProperty(obj, methodName);
|
Object fun = getProperty(obj, methodName);
|
||||||
if (fun == NOT_FOUND)
|
if (fun == NOT_FOUND)
|
||||||
fun = methodName;
|
fun = methodName;
|
||||||
return ScriptRuntime.call(cx, fun, obj, args, getTopLevelScope(obj));
|
return ScriptRuntime.call(cx, fun, obj, args,
|
||||||
|
getTopLevelScope(obj));
|
||||||
} finally {
|
} finally {
|
||||||
Context.exit();
|
Context.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1597,7 +1600,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
synchronized void addPropertyAttribute(int attribute) {
|
synchronized void addPropertyAttribute(int attribute) {
|
||||||
if (slots == null)
|
if (slots == null)
|
||||||
return;
|
return;
|
||||||
for (int i=0; i < slots.length; i++) {
|
for (int i = 0; i < slots.length; i++) {
|
||||||
Slot slot = slots[i];
|
Slot slot = slots[i];
|
||||||
if (slot == null || slot == REMOVED)
|
if (slot == null || slot == REMOVED)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1684,7 +1687,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
* caused the table to grow while this thread was searching.
|
* caused the table to grow while this thread was searching.
|
||||||
*/
|
*/
|
||||||
private synchronized Slot addSlot(String id, int index, Slot newSlot) {
|
private synchronized Slot addSlot(String id, int index, Slot newSlot) {
|
||||||
if (count == -1)
|
if (count < 0)
|
||||||
throw Context.reportRuntimeError0("msg.add.sealed");
|
throw Context.reportRuntimeError0("msg.add.sealed");
|
||||||
|
|
||||||
if (slots == null) { slots = new Slot[5]; }
|
if (slots == null) { slots = new Slot[5]; }
|
||||||
|
@ -1732,7 +1735,7 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
* deletes are not common.
|
* deletes are not common.
|
||||||
*/
|
*/
|
||||||
private synchronized void removeSlot(String name, int index) {
|
private synchronized void removeSlot(String name, int index) {
|
||||||
if (count == -1)
|
if (count < 0)
|
||||||
throw Context.reportRuntimeError0("msg.remove.sealed");
|
throw Context.reportRuntimeError0("msg.remove.sealed");
|
||||||
getSlot(name, index, true);
|
getSlot(name, index, true);
|
||||||
}
|
}
|
||||||
|
@ -1800,11 +1803,53 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void writeObject(ObjectOutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.defaultWriteObject();
|
||||||
|
int N = count;
|
||||||
|
if (N < 0) {
|
||||||
|
N = -1 - count;
|
||||||
|
}
|
||||||
|
Slot[] s = slots;
|
||||||
|
if (s == null) {
|
||||||
|
if (N != 0) Context.codeBug();
|
||||||
|
out.writeInt(0);
|
||||||
|
} else {
|
||||||
|
out.writeInt(s.length);
|
||||||
|
for (int i = 0; N != 0; ++i) {
|
||||||
|
Slot slot = s[i];
|
||||||
|
if (slot != null && slot != REMOVED) {
|
||||||
|
--N;
|
||||||
|
out.writeObject(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void readObject(ObjectInputStream in)
|
private void readObject(ObjectInputStream in)
|
||||||
throws IOException, ClassNotFoundException
|
throws IOException, ClassNotFoundException
|
||||||
{
|
{
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
lastAccess = REMOVED;
|
lastAccess = REMOVED;
|
||||||
|
|
||||||
|
int capacity = in.readInt();
|
||||||
|
if (capacity != 0) {
|
||||||
|
slots = new Slot[capacity];
|
||||||
|
int N = count;
|
||||||
|
boolean wasSealed = false;
|
||||||
|
if (N < 0) {
|
||||||
|
N = -1 - N; wasSealed = true;
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (int i = 0; i != N; ++i) {
|
||||||
|
Slot s = (Slot)in.readObject();
|
||||||
|
addSlotImpl(s.stringKey, s.intKey, s);
|
||||||
|
}
|
||||||
|
if (wasSealed) {
|
||||||
|
count = - 1 - count;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1821,22 +1866,35 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
|
||||||
private static final Slot REMOVED = new Slot();
|
private static final Slot REMOVED = new Slot();
|
||||||
private static Hashtable exclusionList = null;
|
private static Hashtable exclusionList = null;
|
||||||
|
|
||||||
private Slot[] slots;
|
private transient Slot[] slots;
|
||||||
|
// If count >= 0, it gives number of keys or if count < 0,
|
||||||
|
// it indicates sealed object where -1 - count gives number of keys
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
// cache; may be removed for smaller memory footprint
|
// cache; may be removed for smaller memory footprint
|
||||||
transient private Slot lastAccess = REMOVED;
|
private transient Slot lastAccess = REMOVED;
|
||||||
|
|
||||||
private static class Slot implements Serializable {
|
private static class Slot implements Serializable {
|
||||||
static final int HAS_GETTER = 0x01;
|
static final int HAS_GETTER = 0x01;
|
||||||
static final int HAS_SETTER = 0x02;
|
static final int HAS_SETTER = 0x02;
|
||||||
|
|
||||||
|
private void readObject(ObjectInputStream in)
|
||||||
|
throws IOException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
in.defaultReadObject();
|
||||||
|
if (stringKey != null) {
|
||||||
|
intKey = stringKey.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final long serialVersionUID = -2158009919774350004L;
|
||||||
|
|
||||||
int intKey;
|
int intKey;
|
||||||
String stringKey;
|
String stringKey;
|
||||||
Object value;
|
Object value;
|
||||||
short attributes;
|
short attributes;
|
||||||
byte flags;
|
byte flags;
|
||||||
byte wasDeleted;
|
transient byte wasDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class GetterSlot extends Slot implements Serializable {
|
static class GetterSlot extends Slot implements Serializable {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче