1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-25 10:57:57 +00:00

Don't share singleton collections

CC tries to preserve sharing of objects when crossing the Lua/Java
boundary. For instance, if you queue (or send over a modem)
`{ tbl, tbl }`, then the returned table will have `x[1] == x[2]`.

However, this sharing causes issues with Java singletons. If some code
uses a singleton collection (such as List.of()) in multiple places, then
the same Lua table will be used in all those locations. It's incredibly
easy to accidentally, especially when using using Stream.toList.

For now, we special case these collections and don't de-duplicate them.
I'm not wild about this (it's a bit of a hack!), but I think it's
probably the easiest solution for now.

Fixes #1940
This commit is contained in:
Jonathan Coates
2024-08-18 10:20:54 +01:00
parent cdfa866760
commit cdcd82679c
6 changed files with 110 additions and 20 deletions

View File

@@ -8,9 +8,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.*;
/**
* The result of invoking a Lua method.
@@ -55,6 +53,12 @@ public final class MethodResult {
* <p>
* In order to provide a custom object with methods, one may return a {@link IDynamicLuaObject}, or an arbitrary
* class with {@link LuaFunction} annotations. Anything else will be converted to {@code nil}.
* <p>
* Shared objects in a {@link MethodResult} will preserve their sharing when converted to Lua values. For instance,
* {@code Map<?, ?> m = new HashMap(); return MethodResult.of(m, m); } will return two values {@code a}, {@code b}
* where {@code a == b}. The one exception to this is Java's singleton collections ({@link List#of()},
* {@link Set#of()} and {@link Map#of()}), which are always converted to new table. This is not true for other
* singleton collections, such as those provided by {@link Collections} or Guava.
*
* @param value The value to return to the calling Lua function.
* @return A method result which returns immediately with the given value.