GraalVM 中的 PoliglotMap 是什么?

What is a PoliglotMap in GraalVM?

我正在 Java11 项目中使用 org.graalvm.polyglot 脚本引擎来评估 JavaScript。

要评估的脚本 returns 一个包含两个条目的 JavaScript 数组。

...
var result={};
result.isValid=false;
result.errorMessage = new Array();
result.errorMessage[0]='Somehing go wrong!';
result.errorMessage[1]='Somehingelse go wrong!';
....

在我的 java 代码中,我尝试计算结果对象:

Value resultValue = context.getBindings(languageId).getMember("result");

在我的 Eclipse 调试器中,我可以看到我收到了一个包含预期值的 PolyglotMap:

我可以遍历该映射以使用如下代码获取值:

...
   try {
            mapResult = resultValue.as(Map.class);
        } catch (ClassCastException | IllegalStateException | PolyglotException e) {
            logger.warning("Unable to convert result object");
            return null;
        }

        Iterator it = mapResult.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry) it.next();
            String itemName = pair.getKey().toString();
            Object itemObject = pair.getValue();
...

通过这种方式,我可以提取布尔值 'isValid'。但是对于对象'errorMessage'我很挣扎。

在 Eclipse 调试器中再次检查对象,它看起来像这样:

如果我测试这个对象,它是一个 instanceOf Map。但是我无法从此对象中获取任何值。

任何人都可以帮助我理解这个对象到底代表什么以及我如何提取这两个值 'Someting go wrong!''Sometingelse go wrong!' 吗?

当我遍历第二张地图时,它似乎是空的 - 即使调试器向我显示了正确的值。

我不是 100% 确定为什么 as(Map.class) 会这样,可能值得在 github 上创建一个问题来弄清楚:github.com/oracle/graal

但是,如果您访问值 using the API 而不转换为 Map,它将按您预期的那样工作:

var errorMessage = resultValue.getMember("errorMessage");
errorMessage.hasArrayElements(); // true
var _0th = errorMessage.getArrayElement(0); 
var _1th = errorMessage.getArrayElement(1); 

你也可以将polyglotMap转成Value再做:

val errorMessage = context.asValue(itemObject);
errorMessage.hasArrayElements(); // true
errorMessage.getArrayElement(0);

PolyglotMap当然有getmethod。 Value javadoc 说:

Map.class is supported if the value has Value.hasHashEntries() hash entries}, members or array elements. The returned map can be safely cast to Map. For value with members the key type is String. For value with array elements the key type is Long.

你可以尝试用长键来获取它们吗? 可能我遗漏了一些明显的东西,所以无论如何最好在 GitHub.

上提出问题