8142924: ES6 symbols created with Symbol.for should deserialize to canonical instances
Reviewed-by: hannesw, lagergren, sundar
This commit is contained in:
parent
196fe549ba
commit
e67cae2407
@ -26,6 +26,7 @@
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import java.io.Serializable;
|
||||
import jdk.nashorn.internal.objects.NativeSymbol;
|
||||
|
||||
/**
|
||||
* This class represents a unique, non-String Object property key as defined in ECMAScript 6.
|
||||
@ -56,4 +57,29 @@ public final class Symbol implements Serializable {
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private Object writeReplace() {
|
||||
// If this symbol is a globally registered one, replace it with a
|
||||
// GlobalSymbol in serialized stream.
|
||||
return NativeSymbol.keyFor(null, this) == name ? new GlobalSymbol(name) : this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a globally registered (with NativeSymbol._for) symbol in the
|
||||
* serialized stream. Upon deserialization, it resolves to the globally
|
||||
* registered symbol.
|
||||
*/
|
||||
private static class GlobalSymbol implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String name;
|
||||
|
||||
GlobalSymbol(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return NativeSymbol._for(null, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package jdk.nashorn.internal.runtime.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import jdk.nashorn.internal.objects.NativeSymbol;
|
||||
import jdk.nashorn.internal.runtime.Symbol;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @bug 8142924
|
||||
* @summary ES6 symbols created with Symbol.for should deserialize to canonical instances
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public class JDK_8142924_Test {
|
||||
@Test
|
||||
public static void testNonGlobal() throws Exception {
|
||||
final String name = "testNonGlobal";
|
||||
final Symbol symbol1 = (Symbol)NativeSymbol.constructor(false, null, name);
|
||||
final Symbol symbol2 = serializeRoundTrip(symbol1);
|
||||
Assert.assertNotSame(symbol1, symbol2);
|
||||
Assert.assertEquals(symbol2.getName(), name);
|
||||
Assert.assertNotSame(symbol1, NativeSymbol._for(null, name));
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void testGlobal() throws Exception {
|
||||
final String name = "testGlobal";
|
||||
final Symbol symbol1 = (Symbol)NativeSymbol._for(null, name);
|
||||
final Symbol symbol2 = serializeRoundTrip(symbol1);
|
||||
Assert.assertSame(symbol1, symbol2);
|
||||
}
|
||||
|
||||
private static Symbol serializeRoundTrip(final Symbol symbol) throws Exception {
|
||||
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
final ObjectOutputStream out = new ObjectOutputStream(bout);
|
||||
out.writeObject(symbol);
|
||||
out.close();
|
||||
return (Symbol) new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray())).readObject();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user