Skip to content

Commit

Permalink
Fix sonar findings
Browse files Browse the repository at this point in the history
  • Loading branch information
kaklakariada committed Oct 6, 2024
1 parent 6813cdf commit a55eba8
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 22 deletions.
4 changes: 0 additions & 4 deletions src/main/java/org/itsallcode/luava/LowLevelLua.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ LuaTable table(final int idx) {
return new LuaTable(state, stack, arena, idx);
}

public LuaFunction globalFunction(final String name) {
return new LuaFunction(this, name);
}

private void assertType(final int idx, final LuaType expectedType) {
final LuaType type = stack().getType(idx);
if (type != expectedType) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/itsallcode/luava/LuaFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public LuaFunction resultTypes(final Class<?>... resultTypes) {
}

public List<Object> call() {
LOG.finest(() -> "Calling Lua function '" + name + "' with " + argumentValues.size() + " arguments and "
+ resultTypes.size() + " return values");
lua.getGlobal(name);
pushArguments();
lua.pcall(this.argumentValues.size(), this.resultTypes.size(), DEFAULT_MESSAGE_HANDLER);
Expand Down
30 changes: 15 additions & 15 deletions src/main/java/org/itsallcode/luava/LuaInterpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.lang.foreign.MemorySegment;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.function.IntSupplier;

import org.itsallcode.luava.ffi.lua_CFunction;
Expand Down Expand Up @@ -56,7 +55,7 @@ public LuaTable getGlobalTable(final String name) {
}

public LuaFunction getGlobalFunction(final String name) {
return lua.globalFunction(name);
return new LuaFunction(this.lua, name);
}

public void setGlobalString(final String name, final String value) {
Expand All @@ -80,20 +79,21 @@ public void setGlobalBoolean(final String name, final boolean value) {
}

public void setGlobalFunction(final String name, final Object object, final Method method) {
setGlobalFunction(name, () -> {
final Object[] args = Arrays.stream(method.getParameterTypes()).map(type -> stack().popObject(type))
.toArray();
try {
final Object result = method.invoke(object, args);
if (method.getReturnType() != Void.class) {
stack().pushObject(result);
return 1;
}
return 0;
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Failed to call Java method " + method + ": " + e.getMessage(), e);
setGlobalFunction(name, () -> invokeMethod(object, method));
}

private int invokeMethod(final Object object, final Method method) {
final Object[] args = stack().getValues(method.getParameterTypes());
try {
final Object result = method.invoke(object, args);
if (method.getReturnType() != Void.class) {
stack().pushObject(result);
return 1;
}
});
return 0;
} catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Failed to call Java method " + method + ": " + e.getMessage(), e);
}
}

private void setGlobalFunction(final String name, final IntSupplier fn) {
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/org/itsallcode/luava/LuaStack.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.logging.Logger;
import java.util.stream.IntStream;

import org.itsallcode.luava.ffi.Lua;
import org.itsallcode.luava.ffi.lua_CFunction;

class LuaStack {
private static final Logger LOG = Logger.getLogger(LuaStack.class.getName());
private final MemorySegment state;
private final Arena arena;

Expand Down Expand Up @@ -216,7 +220,10 @@ public Object popObject(final Class<?> expectedType) {
}

public Object toObject(final Class<?> expectedType) {
final int idx = -1;
return toObject(-1, expectedType);
}

private Object toObject(final int idx, final Class<?> expectedType) {
final LuaType type = getType(idx);
if (type == LuaType.NIL) {
return null;
Expand All @@ -235,4 +242,20 @@ public Object toObject(final Class<?> expectedType) {
}
throw new UnsupportedOperationException("Unsupported Lua type " + expectedType + " / " + type);
}

/**
* Get the top elements from the stack without removing them.
*
* @param types object types
* @return values
*/
public Object[] getValues(final Class<?>[] types) {
final Object[] values = IntStream.range(0, types.length)
.mapToObj(i -> toObject(i - types.length, types[i]))
.toArray();
LOG.finest(
() -> "Got " + values.length + " values for types " + Arrays.toString(types) + ": "
+ Arrays.toString(values) + ", " + printStack());
return values;
}
}
29 changes: 27 additions & 2 deletions src/test/java/org/itsallcode/luava/LuaInterpreterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.LongConsumer;
import java.util.function.LongUnaryOperator;
import java.util.function.*;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -135,6 +134,31 @@ void callJavaMethodFromLua(@Mock final LongUnaryOperator mock) throws NoSuchMeth
final List<Object> result = lua.getGlobalFunction("call_java").argumentValues(42).resultTypes(Long.class)
.call();
assertThat(result, equalTo(List.of(85L)));
assertStackSize(0);
}

@Test
void callJavaMethodWithTwoArgsFromLua(@Mock final LongBinaryOperator mock)
throws NoSuchMethodException, SecurityException {
lua.exec("function call_java(arg) return java_function(arg, 1) + 1 end");
when(mock.applyAsLong(42L, 1)).thenReturn(84L);
final Method method = mock.getClass().getMethod("applyAsLong", long.class, long.class);
lua.setGlobalFunction("java_function", mock, method);
final List<Object> result = lua.getGlobalFunction("call_java").argumentValues(42).resultTypes(Long.class)
.call();
assertThat(result, equalTo(List.of(85L)));
assertStackSize(0);
}

@Test
void callJavaMethodWithoutArgsFromLua(@Mock final Runnable mock) throws NoSuchMethodException, SecurityException {
lua.exec("function call_java() java_function() end");
final Method method = mock.getClass().getMethod("run");
lua.setGlobalFunction("java_function", mock, method);
final List<Object> result = lua.getGlobalFunction("call_java").call();
verify(mock).run();
assertThat(result, empty());
assertStackSize(0);
}

@Test
Expand All @@ -146,6 +170,7 @@ void callVoidJavaMethodFromLua(@Mock final LongConsumer mock) throws NoSuchMetho
.call();
assertThat(result, empty());
verify(mock).accept(43);
assertStackSize(0);
}

@Test
Expand Down

0 comments on commit a55eba8

Please sign in to comment.