mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-06-30 09:24:34 -05:00
[WIP] Switch to GraalJS Engine (#793)
* Switch to GraalJS Engine * Update Polygot
This commit is contained in:
@@ -36,8 +36,8 @@ dependencies {
|
||||
// AndroidX annotations
|
||||
compileOnly(libs.android.annotations)
|
||||
|
||||
// substitute for duktape-android
|
||||
implementation(libs.bundles.rhino)
|
||||
// substitute for duktape-android/quickjs
|
||||
implementation(libs.bundles.polyglot)
|
||||
|
||||
// Kotlin wrapper around Java Preferences, makes certain things easier
|
||||
implementation(libs.bundles.settings)
|
||||
|
||||
@@ -1,69 +1,98 @@
|
||||
package app.cash.quickjs;
|
||||
|
||||
import org.mozilla.javascript.ConsString;
|
||||
import org.mozilla.javascript.NativeArray;
|
||||
import org.graalvm.polyglot.*;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import java.io.Closeable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class QuickJs implements Closeable {
|
||||
private ScriptEngine engine;
|
||||
private Context context;
|
||||
|
||||
public static QuickJs create() {
|
||||
return new QuickJs(new ScriptEngineManager());
|
||||
return new QuickJs();
|
||||
}
|
||||
|
||||
public QuickJs(ScriptEngineManager manager) {
|
||||
this.engine = manager.getEngineByName("rhino");
|
||||
public QuickJs() {
|
||||
this.context = Context
|
||||
.newBuilder("js")
|
||||
.allowHostAccess(HostAccess.ALL)
|
||||
.allowPolyglotAccess(PolyglotAccess.NONE)
|
||||
.allowHostClassLoading(false)
|
||||
.build();
|
||||
context.enter();
|
||||
}
|
||||
|
||||
public Object evaluate(String script, String fileName) {
|
||||
public Object evaluate(String script, String ignoredFileName) {
|
||||
return this.evaluate(script);
|
||||
}
|
||||
|
||||
public Object evaluate(String script) {
|
||||
try {
|
||||
Object value = engine.eval(script);
|
||||
Value value = context.eval("js", script);
|
||||
return translateType(value);
|
||||
} catch (Exception exception) {
|
||||
throw new QuickJsException(exception.getMessage(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
private Object translateType(Object obj) {
|
||||
if (obj instanceof NativeArray) {
|
||||
NativeArray array = (NativeArray) obj;
|
||||
long length = array.getLength();
|
||||
Object[] objects = new Object[(int) length];
|
||||
for (int i = 0; i < (int) length; i++) {
|
||||
objects[i] = translateType(array.get(i));
|
||||
private Object translateType(Value obj) {
|
||||
if (obj.isBoolean()) {
|
||||
return obj.asBoolean();
|
||||
} else if (obj.hasArrayElements()) {
|
||||
if (obj.getArraySize() == 0) {
|
||||
return new int[0];
|
||||
} else {
|
||||
Value element = obj.getArrayElement(0);
|
||||
if (element.isBoolean()) {
|
||||
return obj.as(boolean[].class);
|
||||
} else if (element.isNumber()) {
|
||||
if (element.fitsInInt()) {
|
||||
return obj.as(int[].class);
|
||||
} else if (element.fitsInBigInteger()) {
|
||||
return Arrays.stream(obj.as(BigInteger[].class)).map(BigInteger::longValue).toArray();
|
||||
} else {
|
||||
return obj.as(double[].class);
|
||||
}
|
||||
} else if (element.isHostObject()) {
|
||||
return obj.as(Object[].class);
|
||||
} else if (element.isString()) {
|
||||
return obj.as(String[].class);
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
if (obj instanceof ConsString) {
|
||||
ConsString consString = (ConsString) obj;
|
||||
return consString.toString();
|
||||
}
|
||||
if (obj instanceof Long) {
|
||||
Long value = (Long) obj;
|
||||
return value.intValue();
|
||||
} else if (obj.isNumber()) {
|
||||
if (obj.fitsInInt()) {
|
||||
return obj.asInt();
|
||||
} else if (obj.fitsInBigInteger()) {
|
||||
return obj.asBigInteger().longValue();
|
||||
} else {
|
||||
return obj.asDouble();
|
||||
}
|
||||
} else if (obj.isHostObject()) {
|
||||
return obj.asHostObject();
|
||||
} else if (obj.isString()) {
|
||||
return obj.asString();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public byte[] compile(String sourceCode, String fileName) {
|
||||
public byte[] compile(String sourceCode, String ignoredFileName) {
|
||||
return sourceCode.getBytes();
|
||||
}
|
||||
|
||||
|
||||
public Object execute(byte[] bytecode) {
|
||||
return this.evaluate(new String(bytecode));
|
||||
}
|
||||
|
||||
public <T> void set(String name, Class<T> ignoredType, T object) {
|
||||
context.getBindings("js").putMember(name, object);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.engine = null;
|
||||
this.context.leave();
|
||||
this.context.close();
|
||||
this.context = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user