簡體   English   中英

JSR-223:如何將可變參數宿主函數綁定到ScriptEngine

[英]JSR-223: How to bind a variadic host function to ScriptEngine

我正在嘗試通過Java VM下的JSR-223 ScriptEngine運行Javascript來調用用戶提供的代碼,並將其傳遞給“承諾樣式”回調:即,一個不接受任何參數(成功完成且沒有值)的函數; 單個參數(對於沒有值或錯誤對象的成功完成,為null ); 或兩個參數(成功完成時為null ,一個值)。

我為此使用GaalVM,並將回調函數放入Javascript綁定對象中。 像這樣:

var engine = new ScriptEngineManager().getEngineByName("graal.js");
var binding = engine.getBindings(ScriptContext.ENGINE_SCOPE);
binding.put("exports", engine.eval("new Object()"));
engine.eval(userCode, binding);
binding.put("data", data);
binding.put("callback", callback);
engine.eval("exports.handler(data, callback)", binding);

問題是我無法弄清楚應將什么作為"callback"綁定:

我嘗試了簡單的方法:

BiFunction<Object, Object, Object> callback = (err, value) -> { /* ... */ };

在這種情況下,使用兩個參數調用回調可以很好地工作,但是使用一個參數(或不使用參數)時,我會收到錯誤消息:

org.graalvm.polyglot.PolyglotException: TypeError: EXECUTE on 
  JavaObject[my.package.JavascriptRun$$Lambda$771/0x0000000840844040@4cf04c6a 
  (my.package.JavascriptRun$$Lambda$771/0x0000000840844040)] failed due to: 
  Arity error - expected: 2 actual: 1

我試着像這樣獲取一個Object數組:

Function<Object[], Object> callback = (args) -> { /* ... */ };

這導致GraalVM向我扔了這個:

org.graalvm.polyglot.PolyglotException: TypeError: EXECUTE on
   JavaObject[my.package.JavascriptRun$$Lambda$771/0x0000000840844040@855ef90 
  (my.package.JavascriptRun$$Lambda$771/0x0000000840844040)] failed due to:
  java.lang.ClassCastException: class com.oracle.truffle.polyglot.PolyglotMap
  cannot be cast to class [Ljava.lang.Object; 
  (com.oracle.truffle.polyglot.PolyglotMap is in unnamed module of loader 'app';
   [Ljava.lang.Object; is in module java.base of loader 'bootstrap')

我目前正在使用Javascript進行手動多次調度-基本上定義了多個回調宿主函數,然后在Javascript中檢查參數數量並相應地進行調度:

engine.eval("exports.handler(data, function() { "+
  "switch(arguments.length) { "+
  "case 0: return callback0(); "+
  "case 1: return callback1(arguments[0]); "+
  "default: return callback2(arguments[0],arguments[1]); "+
  "} })");

但這對我來說似乎是個壞主意。

MyCallback callback = (arguments) -> { /*...*/ };

哪里

@FunctionalInterface
public static interface MyCallback {
    Object call(Object... arguments);
}

我想它將為您服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM