Skip to content

Commit 00475b9

Browse files
committed
Support LuaTable arguments in @LuaFunction
1 parent 018ce7c commit 00475b9

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectLuaTable.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,14 @@ public Collection<Object> values() {
6161
public Set<Entry<Object, Object>> entrySet() {
6262
return map.entrySet();
6363
}
64+
65+
@Override
66+
public boolean equals(Object o) {
67+
return this == o || o instanceof Map<?, ?> otherMap && map.equals(otherMap);
68+
}
69+
70+
@Override
71+
public int hashCode() {
72+
return map.hashCode();
73+
}
6474
}

projects/core/src/main/java/dan200/computercraft/core/asm/Generator.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ static void addArgType(Map<Class<?>, ArgMethods> types, Class<?> type, String na
7373
addArgType(argMethodMap, Map.class, "Table");
7474
addArgType(argMethodMap, String.class, "String");
7575
addArgType(argMethodMap, ByteBuffer.class, "Bytes");
76+
argMethodMap.put(LuaTable.class, new ArgMethods(
77+
// i -> new ObjectLuaTable(getTable(i))
78+
MethodHandles.filterReturnValue(
79+
LOOKUP.findVirtual(IArguments.class, "getTable", MethodType.methodType(Map.class, int.class)),
80+
LOOKUP.findConstructor(ObjectLuaTable.class, MethodType.methodType(void.class, Map.class))
81+
.asType(MethodType.methodType(LuaTable.class, Map.class))
82+
),
83+
// i -> optTable(i).map(ObjectLuaTable::new)
84+
MethodHandles.filterReturnValue(
85+
LOOKUP.findVirtual(IArguments.class, "optTable", MethodType.methodType(Optional.class, int.class)),
86+
MethodHandles.insertArguments(
87+
LOOKUP.findVirtual(Optional.class, "map", MethodType.methodType(Optional.class, Function.class)),
88+
1, (Function<Map<?, ?>, LuaTable<?, ?>>) ObjectLuaTable::new
89+
)
90+
)
91+
));
7692
argMethods = Map.copyOf(argMethodMap);
7793

7894
ARG_TABLE_UNSAFE = ArgMethods.of(LuaTable.class, "TableUnsafe");
@@ -335,10 +351,9 @@ private static MethodHandle setReturn(MethodHandle handle, Class<?> retTy) {
335351
}
336352

337353
private static @Nullable ArgMethods getArgMethods(Class<?> type, boolean unsafe) {
338-
var getter = argMethods.get(type);
339-
if (getter != null) return getter;
340354
if (type == LuaTable.class && unsafe) return ARG_TABLE_UNSAFE;
341-
return null;
355+
356+
return argMethods.get(type);
342357
}
343358

344359
/**

projects/core/src/test/java/dan200/computercraft/core/asm/GeneratorTest.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import dan200.computercraft.core.methods.LuaMethod;
1111
import dan200.computercraft.core.methods.NamedMethod;
1212
import org.hamcrest.Matcher;
13+
import org.jspecify.annotations.Nullable;
1314
import org.junit.jupiter.api.Test;
1415
import org.objectweb.asm.ClassReader;
1516
import org.objectweb.asm.ClassVisitor;
@@ -123,6 +124,17 @@ public void testEnum() throws LuaException {
123124
assertThrows(LuaException.class, () -> apply(methods, new EnumMethods(), "getEnum", "not as side"));
124125
}
125126

127+
@Test
128+
public void testLuaTable() throws LuaException {
129+
var methods = GENERATOR.getMethods(TableMethods.class);
130+
assertThat(methods, containsInAnyOrder(named("getTable"), named("optTable")));
131+
132+
assertThat(apply(methods, new TableMethods(), "getTable", Map.of("x", "y")), one(is(Map.of("x", "y"))));
133+
assertThat(apply(methods, new TableMethods(), "optTable", Map.of("x", "y")), one(is(Map.of("x", "y"))));
134+
assertThat(apply(methods, new TableMethods(), "optTable"), one(nullValue()));
135+
assertThrows(LuaException.class, () -> apply(methods, new TableMethods(), "getTable", "not a table"));
136+
}
137+
126138
@Test
127139
public void testMainThread() throws LuaException {
128140
var methods = GENERATOR.getMethods(MainThread.class);
@@ -277,6 +289,18 @@ public final String optEnum(Optional<ComputerSide> side) {
277289
}
278290
}
279291

292+
public static class TableMethods {
293+
@LuaFunction
294+
public final LuaTable<?, ?> getTable(LuaTable<?, ?> table) {
295+
return table;
296+
}
297+
298+
@LuaFunction
299+
public final @Nullable LuaTable<?, ?> optTable(Optional<LuaTable<?, ?>> table) {
300+
return table.orElse(null);
301+
}
302+
}
303+
280304
public static class MainThread {
281305
@LuaFunction(mainThread = true)
282306
public final void go() {
@@ -288,10 +312,6 @@ public static class Unsafe {
288312
public final void withUnsafe(LuaTable<?, ?> table) {
289313
}
290314

291-
@LuaFunction
292-
public final void withoutUnsafe(LuaTable<?, ?> table) {
293-
}
294-
295315
@LuaFunction(unsafe = true, mainThread = true)
296316
public final void invalid(LuaTable<?, ?> table) {
297317
}

0 commit comments

Comments
 (0)