从宿主语言注入成员以作为访客语言类型到达访客语言

edo*_*Dev 2 graalvm

这个问题与以下内容有些相关: GraalVM - Using Polyglot Value without a context

在我的应用程序中,以客户语言运行的代码片段不需要知道注入的参数(通过绑定成员)是 Java 参数。相反,对于用客语开发的人来说,论点应该看起来只是客语本身的另一个论点。

例如,我想要一个从我的 Java 主机语言注入到 JS 来宾脚本的数组,以这种方式:

Value guestLanguageBindings = context.getBindings(scriptData.getLanguage().toString());

guestLanguageBindings.putMember(argumentName, argumentValue);
Run Code Online (Sandbox Code Playgroud)

作为 JS 数组“到达”来宾语言,而不是像现在正在发生的 java.util.ArrayList。

目前,我通过将每个非原始类型(我注意到 String、int 等作为 JS“类型”到达 JS)转换为 JSON 并转换回来宾语言来解决这个问题。

这有效,但我想知道是否有更合适的方法来做到这一点,或者确实使用绑定是正确的方法?

谢谢!

Chr*_*mer 5

这有效,但我想知道是否有更合适的方法来做到这一点,或者确实使用绑定是正确的方法?

正如您所注意到的,当您将 Java 对象放入多语言语言时,它们对用户来说看起来像 Java 对象,而不像 JavaScript 对象。为了使它们模仿访客语言对象,您可以使用 Polyglot 代理 API。

JS 对象示例(由 HashMap 支持):

try (Context context = Context.create("js")) {
    Map<String, Object> backingMap = new HashMap<>();
    backingMap.put("foo", "bar");
    context.getBindings("js").putMember("hostObject", ProxyObject.fromMap(backingMap));
    assert "bar".equals(context.eval("js", "hostObject.foo").asString());
    backingMap.put("foo", "baz");
    assert "baz".equals(context.eval("js", "hostObject.foo").asString());
}
Run Code Online (Sandbox Code Playgroud)

JS 数组示例(由 Java 数组支持):

try (Context context = Context.create("js")) {
    Object[] backingArray = new Object[42];
    backingArray[0] = 42;
    context.getBindings("js").putMember("hostObject", ProxyArray.fromArray(backingArray));
    assert 42 == context.eval("js", "hostObject[0]").asInt();
    backingArray[0] = 43;
    assert 43 == context.eval("js", "hostObject[0]").asInt();
}
Run Code Online (Sandbox Code Playgroud)

函数示例(由 Lambda 支持):

try (Context context = Context.create("js")) {
    ProxyExecutable executable = (arguments) -> arguments[0];
    context.getBindings("js").putMember("hostObject",executable);
    assert 42 == context.eval("js", "hostObject(42)").asInt();
    assert 43 == context.eval("js", "hostObject(43)").asInt();
}
Run Code Online (Sandbox Code Playgroud)

您也可以直接实现 ProxyObject 和 ProxyArray 以自定义行为,例如,如果您想提供只读对象或数组。

这是另一个代理示例:http : //www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies

代理 Javadoc:http : //www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/package-summary.html