Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,15 @@ private long[] invokeBuiltin(Instance instance, long[] args) {
}

if (clazz == HostRef.class) {
argsList.add(javaRefs.get(value.intValue()));
if (value.isArray()) {
var refs = new ArrayList<>();
for (JsonNode elem : value) {
refs.add(javaRefs.get(elem.intValue()));
}
argsList.add(refs);
} else {
argsList.add(javaRefs.get(value.intValue()));
}
} else {
argsList.add(mapper.treeToValue(value, clazz));
}
Expand Down
41 changes: 41 additions & 0 deletions core/src/test/java/io/roastedroot/quickjs4j/core/EngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,47 @@ public void callJavaFunctionsUsingJavaRefs() {
expectedUser.name, expectedUser.surname, expectedUser.age));
}

@SuppressWarnings("unchecked")
@Test
public void hostRefArray() {
var received = new AtomicReference<>();
var builtins =
Builtins.builder("from_java")
.add(
new HostFunction(
"create",
List.of(Integer.class, Integer.class),
HostRef.class,
(args) -> {
var x = (Integer) args.get(0);
var y = (Integer) args.get(1);
return new Point(x, y);
}))
.add(
new HostFunction(
"check_refs",
List.of(HostRef.class),
Void.class,
(args) -> {
received.set(args.get(0));
return null;
}))
.build();

var engine = Engine.builder().addBuiltins(builtins).build();

compileAndExec(
engine,
"const p1 = from_java.create(10, 20);\n"
+ "const p2 = from_java.create(30, 40);\n"
+ "from_java.check_refs([p1, p2]);\n");

var refs = (List<Object>) received.get();
assertEquals(2, refs.size());
assertEquals(new Point(10, 20), refs.get(0));
assertEquals(new Point(30, 40), refs.get(1));
}

@Test
public void useBundledJS() throws Exception {
var myCow =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package chicory.test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand Down Expand Up @@ -51,6 +52,19 @@ public void myRefCheck(@HostRefParam String value) {
refInvoked = true;
assertEquals("a pure java string", value);
}

@ReturnsHostRef
@HostFunction("my_java_ref_create")
public String createRef(String value) {
return value;
}

public String[] receivedRefs;

@HostFunction("my_java_ref_check_array")
public void myRefCheckArray(@HostRefParam String... values) {
receivedRefs = values;
}
}

class JsTest {
Expand Down Expand Up @@ -113,6 +127,18 @@ public void useJavaRefs() {
assertTrue(helloJs.isRefInvoked());
}

@Test
public void useJavaRefArray() {
var helloJs = new JsTest();

helloJs.exec(
"var r1 = from_java.my_java_ref_create('hello');\n"
+ "var r2 = from_java.my_java_ref_create('world');\n"
+ "from_java.my_java_ref_check_array([r1, r2]);");

assertArrayEquals(new String[] {"hello", "world"}, helloJs.javaApi.receivedRefs);
}

@Test
public void useInvokables() {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.github.javaparser.ast.expr.ArrayCreationExpr;
import com.github.javaparser.ast.expr.ArrayInitializerExpr;
import com.github.javaparser.ast.expr.CastExpr;
import com.github.javaparser.ast.expr.EnclosedExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.IntegerLiteralExpr;
Expand Down Expand Up @@ -42,6 +43,8 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.TypeKind;
import javax.tools.StandardLocation;

public final class BuiltinsProcessor extends Quickjs4jAbstractProcessor {
Expand Down Expand Up @@ -219,12 +222,37 @@ private Expression processHostFunction(
break;
default:
var typeLiteral = parameter.asType().toString();
var type = parseType(parameter.asType().toString());
arguments.add(new CastExpr(type, argExpr(paramTypes.size())));
var argIndex = paramTypes.size();
if (annotatedWith(parameter, HostRefParam.class)) {
var javaRefType = "io.roastedroot.quickjs4j.core.HostRef";
paramTypes.add(new FieldAccessExpr(new NameExpr(javaRefType), "class"));
if (parameter.asType().getKind() == TypeKind.ARRAY) {
var componentType =
((ArrayType) parameter.asType()).getComponentType().toString();
var castToList =
new EnclosedExpr(
new CastExpr(
parseType("java.util.List"),
argExpr(argIndex)));
var emptyArray =
new ArrayCreationExpr(
parseType(componentType),
NodeList.nodeList(
new ArrayCreationLevel()
.setDimension(
new IntegerLiteralExpr("0"))),
null);
var toArrayCall =
new MethodCallExpr(
castToList, "toArray", NodeList.nodeList(emptyArray));
arguments.add(new CastExpr(parseType(typeLiteral), toArrayCall));
} else {
var type = parseType(typeLiteral);
arguments.add(new CastExpr(type, argExpr(argIndex)));
}
} else {
var type = parseType(typeLiteral);
arguments.add(new CastExpr(type, argExpr(argIndex)));
paramTypes.add(new FieldAccessExpr(new NameExpr(typeLiteral), "class"));
}
}
Expand Down
Loading