fix: small issues

This commit is contained in:
TopchetoEU 2023-09-07 16:35:49 +03:00
parent 29d3f378a5
commit 38656bd654
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
9 changed files with 18 additions and 526 deletions

7
Metadata.java Normal file
View File

@ -0,0 +1,7 @@
package me.topchetoeu.jscript;
public class Metadata {
public static final String VERSION = "0.0.1-alpha";
public static final String AUTHOR = "TopchetoEU";
public static final String NAME = "java-jscript";
}

View File

@ -46,7 +46,7 @@ async function compileJava() {
const args = ['-d', 'dst/classes', 'Metadata.java'];
for await (const path of find('src', undefined, v => v.endsWith('.java') && !v.endsWith('Metadata.java'))) args.push(path);
await run('javac', ...args);
await run(conf.javahome + '/javac', ...args);
await fs.rm('Metadata.java');
}

View File

@ -1,4 +1,3 @@
/** @internal */
define("values/object", () => {
var Object = env.global.Object = function(arg: any) {
if (arg === undefined || arg === null) return {};

View File

@ -1,5 +1,6 @@
{
"version": "0.0.1-alpha",
"name": "java-jscript",
"author": "TopchetoEU"
"author": "TopchetoEU",
"javahome": "/usr/lib/jvm/java-8-openjdk-amd64/bin"
}

View File

@ -0,0 +1,7 @@
package me.topchetoeu.jscript.filesystem;
import java.util.HashMap;
public class FilesystemRegister {
private HashMap<String, Filesystem> filesystems = new HashMap<>();
}

View File

@ -1,86 +0,0 @@
package me.topchetoeu.jscript.polyfills;
import java.util.LinkedHashMap;
import java.util.stream.Collectors;
import me.topchetoeu.jscript.engine.CallContext;
import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.interop.Native;
import me.topchetoeu.jscript.interop.NativeGetter;
public class Map {
private LinkedHashMap<Object, Object> objs = new LinkedHashMap<>();
@Native
public Object get(Object key) {
return objs.get(key);
}
@Native
public Map set(Object key, Object val) {
objs.put(key, val);
return this;
}
@Native
public boolean delete(Object key) {
if (objs.containsKey(key)) {
objs.remove(key);
return true;
}
else return false;
}
@Native
public boolean has(Object key) {
return objs.containsKey(key);
}
@Native
public void clear() {
objs.clear();
}
@Native
public void forEach(CallContext ctx, FunctionValue func, Object thisArg) throws InterruptedException {
for (var el : objs.entrySet().stream().collect(Collectors.toList())) {
func.call(ctx, thisArg, el.getValue(), el.getKey(), this);
}
}
@Native
public Object entries(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs
.entrySet()
.stream()
.map(v -> new ArrayValue(ctx, v.getKey(), v.getValue()))
.collect(Collectors.toList())
);
}
@Native
public Object keys(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs.keySet().stream().collect(Collectors.toList()));
}
@Native
public Object values(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs.values().stream().collect(Collectors.toList()));
}
@NativeGetter("size")
public int size() {
return objs.size();
}
@Native
public Map(CallContext ctx, Object iterable) throws InterruptedException {
if (Values.isPrimitive(iterable)) return;
for (var val : Values.toJavaIterable(ctx, iterable)) {
var first = Values.getMember(ctx, val, 0);
var second = Values.getMember(ctx, val, 1);
set(first, second);
}
}
public Map() { }
}

View File

@ -1,360 +0,0 @@
package me.topchetoeu.jscript.polyfills;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import me.topchetoeu.jscript.engine.CallContext;
import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.engine.values.NativeFunction;
import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Native;
public class Promise {
private static class Handle {
public final CallContext ctx;
public final FunctionValue fulfilled;
public final FunctionValue rejected;
public Handle(CallContext ctx, FunctionValue fulfilled, FunctionValue rejected) {
this.ctx = ctx;
this.fulfilled = fulfilled;
this.rejected = rejected;
}
}
@Native("resolve")
public static Promise ofResolved(CallContext ctx, Object val) {
if (Values.isWrapper(val, Promise.class)) return Values.wrapper(val, Promise.class);
var res = new Promise();
res.fulfill(ctx, val);
return res;
}
public static Promise ofResolved(Object val) {
if (Values.isWrapper(val, Promise.class)) return Values.wrapper(val, Promise.class);
var res = new Promise();
res.fulfill(val);
return res;
}
@Native("reject")
public static Promise ofRejected(CallContext ctx, Object val) {
var res = new Promise();
res.reject(ctx, val);
return res;
}
public static Promise ofRejected(Object val) {
var res = new Promise();
res.fulfill(val);
return res;
}
@Native
public static Promise any(CallContext ctx, Object _promises) {
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = Values.array(_promises);
if (promises.size() == 0) return ofResolved(new ArrayValue());
var n = new int[] { promises.size() };
var res = new Promise();
var errors = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
var index = i;
var val = promises.get(i);
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
ctx,
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
new NativeFunction(null, (e, th, args) -> {
errors.set(ctx, index, args[0]);
n[0]--;
if (n[0] <= 0) res.reject(e, errors);
return null;
})
);
else {
res.fulfill(ctx, val);
break;
}
}
return res;
}
@Native
public static Promise race(CallContext ctx, Object _promises) {
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = Values.array(_promises);
if (promises.size() == 0) return ofResolved(new ArrayValue());
var res = new Promise();
for (var i = 0; i < promises.size(); i++) {
var val = promises.get(i);
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
ctx,
new NativeFunction(null, (e, th, args) -> { res.fulfill(e, args[0]); return null; }),
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
);
else {
res.fulfill(val);
break;
}
}
return res;
}
@Native
public static Promise all(CallContext ctx, Object _promises) {
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = Values.array(_promises);
if (promises.size() == 0) return ofResolved(new ArrayValue());
var n = new int[] { promises.size() };
var res = new Promise();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
var index = i;
var val = promises.get(i);
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
ctx,
new NativeFunction(null, (e, th, args) -> {
result.set(ctx, index, args[0]);
n[0]--;
if (n[0] <= 0) res.fulfill(e, result);
return null;
}),
new NativeFunction(null, (e, th, args) -> { res.reject(e, args[0]); return null; })
);
else {
result.set(ctx, i, val);
break;
}
}
if (n[0] <= 0) res.fulfill(ctx, result);
return res;
}
@Native
public static Promise allSettled(CallContext ctx, Object _promises) {
if (!Values.isArray(_promises)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = Values.array(_promises);
if (promises.size() == 0) return ofResolved(new ArrayValue());
var n = new int[] { promises.size() };
var res = new Promise();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
var index = i;
var val = promises.get(i);
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(
ctx,
new NativeFunction(null, (e, th, args) -> {
result.set(ctx, index, new ObjectValue(ctx, Map.of(
"status", "fulfilled",
"value", args[0]
)));
n[0]--;
if (n[0] <= 0) res.fulfill(e, result);
return null;
}),
new NativeFunction(null, (e, th, args) -> {
result.set(ctx, index, new ObjectValue(ctx, Map.of(
"status", "rejected",
"reason", args[0]
)));
n[0]--;
if (n[0] <= 0) res.fulfill(e, result);
return null;
})
);
else {
result.set(ctx, i, new ObjectValue(ctx, Map.of(
"status", "fulfilled",
"value", val
)));
n[0]--;
}
}
if (n[0] <= 0) res.fulfill(ctx, result);
return res;
}
private List<Handle> handles = new ArrayList<>();
private static final int STATE_PENDING = 0;
private static final int STATE_FULFILLED = 1;
private static final int STATE_REJECTED = 2;
private int state = STATE_PENDING;
private Object val;
/**
* Thread safe - call from any thread
*/
public void fulfill(Object val) {
if (Values.isWrapper(val, Promise.class)) throw new IllegalArgumentException("A promise may not be a fulfil value.");
if (state != STATE_PENDING) return;
this.state = STATE_FULFILLED;
this.val = val;
for (var el : handles) el.ctx.engine().pushMsg(true, el.fulfilled, el.ctx.data(), null, val);
handles = null;
}
/**
* Thread safe - call from any thread
*/
public void fulfill(CallContext ctx, Object val) {
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(ctx,
new NativeFunction(null, (e, th, args) -> {
this.fulfill(e, args[0]);
return null;
}),
new NativeFunction(null, (e, th, args) -> {
this.reject(e, args[0]);
return null;
})
);
else this.fulfill(val);
}
/**
* Thread safe - call from any thread
*/
public void reject(Object val) {
if (Values.isWrapper(val, Promise.class)) throw new IllegalArgumentException("A promise may not be a reject value.");
if (state != STATE_PENDING) return;
this.state = STATE_REJECTED;
this.val = val;
for (var el : handles) el.ctx.engine().pushMsg(true, el.rejected, el.ctx.data(), null, val);
handles = null;
}
/**
* Thread safe - call from any thread
*/
public void reject(CallContext ctx, Object val) {
if (Values.isWrapper(val, Promise.class)) Values.wrapper(val, Promise.class).then(ctx,
new NativeFunction(null, (e, th, args) -> {
this.reject(e, args[0]);
return null;
}),
new NativeFunction(null, (e, th, args) -> {
this.reject(e, args[0]);
return null;
})
);
else this.reject(val);
}
private void handle(CallContext ctx, FunctionValue fulfill, FunctionValue reject) {
if (state == STATE_FULFILLED) ctx.engine().pushMsg(true, fulfill, ctx.data(), null, val);
else if (state == STATE_REJECTED) ctx.engine().pushMsg(true, reject, ctx.data(), null, val);
else handles.add(new Handle(ctx, fulfill, reject));
}
/**
* Thread safe - you can call this from anywhere
* HOWEVER, it's strongly recommended to use this only in javascript
*/
@Native
public Promise then(CallContext ctx, Object onFulfill, Object onReject) {
if (!(onFulfill instanceof FunctionValue)) onFulfill = null;
if (!(onReject instanceof FunctionValue)) onReject = null;
var res = new Promise();
var fulfill = (FunctionValue)onFulfill;
var reject = (FunctionValue)onReject;
handle(ctx,
new NativeFunction(null, (e, th, args) -> {
if (fulfill == null) res.fulfill(e, args[0]);
else {
try { res.fulfill(e, fulfill.call(e, null, args[0])); }
catch (EngineException err) { res.reject(e, err.value); }
}
return null;
}),
new NativeFunction(null, (e, th, args) -> {
if (reject == null) res.reject(e, args[0]);
else {
try { res.fulfill(e, reject.call(e, null, args[0])); }
catch (EngineException err) { res.reject(e, err.value); }
}
return null;
})
);
return res;
}
/**
* Thread safe - you can call this from anywhere
* HOWEVER, it's strongly recommended to use this only in javascript
*/
@Native("catch")
public Promise _catch(CallContext ctx, Object onReject) {
return then(ctx, null, onReject);
}
/**
* Thread safe - you can call this from anywhere
* HOWEVER, it's strongly recommended to use this only in javascript
*/
@Native("finally")
public Promise _finally(CallContext ctx, Object handle) {
return then(ctx,
new NativeFunction(null, (e, th, args) -> {
if (handle instanceof FunctionValue) ((FunctionValue)handle).call(ctx);
return args[0];
}),
new NativeFunction(null, (e, th, args) -> {
if (handle instanceof FunctionValue) ((FunctionValue)handle).call(ctx);
throw new EngineException(args[0]);
})
);
}
/**
* NOT THREAD SAFE - must be called from the engine executor thread
*/
@Native
public Promise(CallContext ctx, FunctionValue func) throws InterruptedException {
if (!(func instanceof FunctionValue)) throw EngineException.ofType("A function must be passed to the promise constructor.");
try {
func.call(
ctx, null,
new NativeFunction(null, (e, th, args) -> {
fulfill(e, args.length > 0 ? args[0] : null);
return null;
}),
new NativeFunction(null, (e, th, args) -> {
reject(e, args.length > 0 ? args[0] : null);
return null;
})
);
}
catch (EngineException e) {
reject(ctx, e.value);
}
}
@Override @Native
public String toString() {
if (state == STATE_PENDING) return "Promise (pending)";
else if (state == STATE_FULFILLED) return "Promise (fulfilled)";
else return "Promise (rejected)";
}
private Promise(int state, Object val) {
this.state = state;
this.val = val;
}
public Promise() {
this(STATE_PENDING, null);
}
}

View File

@ -1,76 +0,0 @@
package me.topchetoeu.jscript.polyfills;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
import me.topchetoeu.jscript.engine.CallContext;
import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.FunctionValue;
import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Native;
import me.topchetoeu.jscript.interop.NativeGetter;
public class Set {
private LinkedHashSet<Object> objs = new LinkedHashSet<>();
@Native
public Set add(Object key) {
objs.add(key);
return this;
}
@Native
public boolean delete(Object key) {
return objs.remove(key);
}
@Native
public boolean has(Object key) {
return objs.contains(key);
}
@Native
public void clear() {
objs.clear();
}
@Native
public void forEach(CallContext ctx, Object func, Object thisArg) throws InterruptedException {
if (!(func instanceof FunctionValue)) throw EngineException.ofType("func must be a function.");
for (var el : objs.stream().collect(Collectors.toList())) {
((FunctionValue)func).call(ctx, thisArg, el, el, this);
}
}
@Native
public ObjectValue entries(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs
.stream()
.map(v -> new ArrayValue(ctx, v, v))
.collect(Collectors.toList())
);
}
@Native
public ObjectValue keys(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs);
}
@Native
public ObjectValue values(CallContext ctx) throws InterruptedException {
return Values.fromJavaIterable(ctx, objs);
}
@NativeGetter("size")
public int size() {
return objs.size();
}
@Native
public Set(CallContext ctx, Object iterable) throws InterruptedException {
if (Values.isPrimitive(iterable)) return;
for (var val : Values.toJavaIterable(ctx, iterable)) {
add(val);
}
}
public Set() { }
}