fix: some more libs fixes

This commit is contained in:
TopchetoEU 2024-01-04 13:58:04 +02:00
parent e575b3287e
commit 71f735b812
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
15 changed files with 310 additions and 276 deletions

View File

@ -1,6 +1,7 @@
package me.topchetoeu.jscript.lib;
import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose;
import me.topchetoeu.jscript.interop.ExposeConstructor;
@ -13,6 +14,10 @@ public class BooleanLib {
public final boolean value;
@Override public String toString() {
return value + "";
}
public BooleanLib(boolean val) {
this.value = val;
}
@ -26,6 +31,7 @@ public class BooleanLib {
return args.self(Boolean.class) ? "true" : "false";
}
@Expose public static boolean __valueOf(Arguments args) {
if (Values.isWrapper(args.self, BooleanLib.class)) return Values.wrapper(args.self, BooleanLib.class).value;
return args.self(Boolean.class);
}
}

View File

@ -238,6 +238,10 @@ public class DateLib {
return normal.getTime().toString();
}
@Override public String toString() {
return __toString();
}
public DateLib(long timestamp) {
normal = Calendar.getInstance();
utc = Calendar.getInstance();

View File

@ -8,6 +8,7 @@ import me.topchetoeu.jscript.exceptions.ConvertException;
import me.topchetoeu.jscript.interop.WrapperName;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose;
import me.topchetoeu.jscript.interop.ExposeConstructor;
import me.topchetoeu.jscript.interop.ExposeField;
@WrapperName("Error")
@ -36,7 +37,7 @@ public class ErrorLib {
else return "[Invalid error]";
}
@Expose public static ObjectValue __constructor(Arguments args) {
@ExposeConstructor public static ObjectValue __constructor(Arguments args) {
var target = new ObjectValue();
var message = args.getString(0, "");

View File

@ -18,13 +18,17 @@ import me.topchetoeu.jscript.filesystem.FilesystemException.FSCode;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose;
import me.topchetoeu.jscript.interop.ExposeField;
import me.topchetoeu.jscript.interop.ExposeTarget;
import me.topchetoeu.jscript.interop.WrapperName;
@WrapperName("Filesystem")
public class FilesystemLib {
@ExposeField public static final int __SEEK_SET = 0;
@ExposeField public static final int __SEEK_CUR = 1;
@ExposeField public static final int __SEEK_END = 2;
@ExposeField(target = ExposeTarget.STATIC)
public static final int __SEEK_SET = 0;
@ExposeField(target = ExposeTarget.STATIC)
public static final int __SEEK_CUR = 1;
@ExposeField(target = ExposeTarget.STATIC)
public static final int __SEEK_END = 2;
private static Filesystem fs(Context ctx) {
var fs = Filesystem.get(ctx);
@ -32,11 +36,13 @@ public class FilesystemLib {
throw EngineException.ofError("Current environment doesn't have a file system.");
}
@Expose public static String __normalize(Arguments args) {
@Expose(target = ExposeTarget.STATIC)
public static String __normalize(Arguments args) {
return fs(args.ctx).normalize(args.convert(String.class));
}
@Expose public static PromiseLib __open(Arguments args) {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __open(Arguments args) {
return PromiseLib.await(args.ctx, () -> {
var fs = fs(args.ctx);
var path = fs.normalize(args.getString(0));
@ -53,7 +59,8 @@ public class FilesystemLib {
catch (FilesystemException e) { throw e.toEngineException(); }
});
}
@Expose public static ObjectValue __ls(Arguments args) {
@Expose(target = ExposeTarget.STATIC)
public static ObjectValue __ls(Arguments args) {
return Values.toJSAsyncIterator(args.ctx, new Iterator<>() {
private boolean failed, done;
@ -108,7 +115,8 @@ public class FilesystemLib {
}
});
}
@Expose public static PromiseLib __mkdir(Arguments args) throws IOException {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __mkdir(Arguments args) throws IOException {
return PromiseLib.await(args.ctx, () -> {
try {
fs(args.ctx).create(args.getString(0), EntryType.FOLDER);
@ -118,7 +126,8 @@ public class FilesystemLib {
});
}
@Expose public static PromiseLib __mkfile(Arguments args) throws IOException {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __mkfile(Arguments args) throws IOException {
return PromiseLib.await(args.ctx, () -> {
try {
fs(args.ctx).create(args.getString(0), EntryType.FILE);
@ -127,7 +136,8 @@ public class FilesystemLib {
catch (FilesystemException e) { throw e.toEngineException(); }
});
}
@Expose public static PromiseLib __rm(Arguments args) throws IOException {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __rm(Arguments args) throws IOException {
return PromiseLib.await(args.ctx, () -> {
try {
var fs = fs(args.ctx);
@ -157,7 +167,8 @@ public class FilesystemLib {
catch (FilesystemException e) { throw e.toEngineException(); }
});
}
@Expose public static PromiseLib __stat(Arguments args) throws IOException {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __stat(Arguments args) throws IOException {
return PromiseLib.await(args.ctx, () -> {
try {
var fs = fs(args.ctx);
@ -172,7 +183,8 @@ public class FilesystemLib {
catch (FilesystemException e) { throw e.toEngineException(); }
});
}
@Expose public static PromiseLib __exists(Arguments args) throws IOException {
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __exists(Arguments args) throws IOException {
return PromiseLib.await(args.ctx, () -> {
try { fs(args.ctx).stat(args.getString(0)); return true; }
catch (FilesystemException e) { return false; }

View File

@ -19,6 +19,6 @@ public class JSONLib {
}
@Expose(target = ExposeTarget.STATIC)
public static String __stringify(Arguments args) {
return me.topchetoeu.jscript.json.JSON.stringify(JSON.fromJs(args.ctx, args.get(0)));
return JSON.stringify(JSON.fromJs(args.ctx, args.get(0)));
}
}

View File

@ -37,7 +37,7 @@ public class MapLib {
}
@Expose public ObjectValue __entries(Arguments args) {
return ArrayValue.of(args.ctx, map
return Values.toJSIterator(args.ctx, map
.entrySet()
.stream()
.map(v -> new ArrayValue(args.ctx, v.getKey(), v.getValue()))
@ -45,10 +45,10 @@ public class MapLib {
);
}
@Expose public ObjectValue __keys(Arguments args) {
return ArrayValue.of(args.ctx, map.keySet());
return Values.toJSIterator(args.ctx, map.keySet());
}
@Expose public ObjectValue __values(Arguments args) {
return ArrayValue.of(args.ctx, map.values());
return Values.toJSIterator(args.ctx, map.values());
}
@Expose public Object __get(Arguments args) {

View File

@ -31,6 +31,12 @@ public class NumberLib {
public final double value;
@Override public String toString() { return value + ""; }
public NumberLib(double val) {
this.value = val;
}
@Expose(target = ExposeTarget.STATIC)
public static boolean __isFinite(Arguments args) { return Double.isFinite(args.getDouble(0)); }
@Expose(target = ExposeTarget.STATIC)
@ -59,11 +65,7 @@ public class NumberLib {
return Values.toString(args.ctx, args.getDouble(0));
}
@Expose public static double __valueOf(Arguments args) {
if (args.self instanceof NumberLib) return args.self(NumberLib.class).value;
if (Values.isWrapper(args.self, NumberLib.class)) return Values.wrapper(args.self, NumberLib.class).value;
else return Values.toNumber(args.ctx, args.self);
}
public NumberLib(double val) {
this.value = val;
}
}

View File

@ -80,8 +80,8 @@ public class ObjectLib {
var obj = args.convert(0, ObjectValue.class);
var attrib = args.convert(1, ObjectValue.class);
for (var key : Values.getMembers(null, obj, false, false)) {
obj.defineProperty(args.ctx, key, attrib.getMember(args.ctx, key));
for (var key : Values.getMembers(null, attrib, false, false)) {
__defineProperty(new Arguments(args.ctx, null, obj, key, attrib.getMember(args.ctx, key)));
}
return obj;
@ -89,7 +89,7 @@ public class ObjectLib {
@Expose(target = ExposeTarget.STATIC)
public static ArrayValue __keys(Arguments args) {
var obj = args.convert(0, ObjectValue.class);
var obj = args.get(0);
var all = args.getBoolean(1);
var res = new ArrayValue();
@ -102,7 +102,7 @@ public class ObjectLib {
@Expose(target = ExposeTarget.STATIC)
public static ArrayValue __entries(Arguments args) {
var res = new ArrayValue();
var obj = args.convert(0, ObjectValue.class);
var obj = args.get(0);
var all = args.getBoolean(1);
for (var key : Values.getMembers(args.ctx, obj, true, false)) {
@ -114,11 +114,11 @@ public class ObjectLib {
@Expose(target = ExposeTarget.STATIC)
public static ArrayValue __values(Arguments args) {
var res = new ArrayValue();
var obj = args.convert(0, ObjectValue.class);
var obj = args.get(0);
var all = args.getBoolean(1);
for (var key : Values.getMembers(args.ctx, obj, true, false)) {
if (all || key instanceof String) res.set(args.ctx, res.size(), Values.getMember(args.ctx, obj, key));
if (all || !(key instanceof Symbol)) res.set(args.ctx, res.size(), Values.getMember(args.ctx, obj, key));
}
return res;
@ -139,9 +139,9 @@ public class ObjectLib {
}
@Expose(target = ExposeTarget.STATIC)
public static ArrayValue __getOwnPropertyNames(Arguments args) {
public static ArrayValue __getOwnPropertyNames(Arguments args) {
var res = new ArrayValue();
var obj = args.convert(0, ObjectValue.class);
var obj = args.get(0);
var all = args.getBoolean(1);
for (var key : Values.getMembers(args.ctx, obj, true, true)) {
@ -152,7 +152,7 @@ public class ObjectLib {
}
@Expose(target = ExposeTarget.STATIC)
public static ArrayValue __getOwnPropertySymbols(Arguments args) {
var obj = args.convert(0, ObjectValue.class);
var obj = args.get(0);
var res = new ArrayValue();
for (var key : Values.getMembers(args.ctx, obj, true, true)) {
@ -208,17 +208,20 @@ public class ObjectLib {
@Expose(target = ExposeTarget.STATIC)
public static boolean __isExtensible(Arguments args) {
var obj = args.get(0);
return obj instanceof ObjectValue && ((ObjectValue)obj).extensible();
if (!(obj instanceof ObjectValue)) return false;
return ((ObjectValue)obj).extensible();
}
@Expose(target = ExposeTarget.STATIC)
public static boolean __isSealed(Arguments args) {
var obj = args.get(0);
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
var _obj = (ObjectValue)obj;
for (var key : _obj.keys(true)) {
if (_obj.memberConfigurable(key)) return false;
}
if (!(obj instanceof ObjectValue)) return true;
var _obj = (ObjectValue)obj;
if (_obj.extensible()) return false;
for (var key : _obj.keys(true)) {
if (_obj.memberConfigurable(key)) return false;
}
return true;
@ -227,12 +230,14 @@ public class ObjectLib {
public static boolean __isFrozen(Arguments args) {
var obj = args.get(0);
if (obj instanceof ObjectValue && ((ObjectValue)obj).extensible()) {
var _obj = (ObjectValue)obj;
for (var key : _obj.keys(true)) {
if (_obj.memberConfigurable(key)) return false;
if (_obj.memberWritable(key)) return false;
}
if (!(obj instanceof ObjectValue)) return true;
var _obj = (ObjectValue)obj;
if (_obj.extensible()) return false;
for (var key : _obj.keys(true)) {
if (_obj.memberConfigurable(key)) return false;
if (_obj.memberWritable(key)) return false;
}
return true;

View File

@ -41,207 +41,6 @@ public class PromiseLib {
private static final int STATE_FULFILLED = 1;
private static final int STATE_REJECTED = 2;
@Expose(value = "resolve", target = ExposeTarget.STATIC)
public static PromiseLib __ofResolved(Arguments args) {
return ofResolved(args.ctx, args.get(0));
}
@Expose(value = "reject", target = ExposeTarget.STATIC)
public static PromiseLib __ofRejected(Arguments args) {
return ofRejected(args.ctx, new EngineException(args.get(0)).setCtx(args.ctx));
}
@Expose(target = ExposeTarget.STATIC)
private static PromiseLib __any(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
if (promises.size() == 0) return ofRejected(args.ctx, EngineException.ofError("No promises passed to 'Promise.any'.").setCtx(args.ctx));
var n = new int[] { promises.size() };
var res = new PromiseLib();
var errors = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
var index = i;
var val = promises.get(i);
if (res.state != STATE_PENDING) break;
handle(args.ctx, val, new Handle() {
public void onFulfil(Object val) { res.fulfill(args.ctx, val); }
public void onReject(EngineException err) {
errors.set(args.ctx, index, err.value);
n[0]--;
if (n[0] <= 0) res.reject(args.ctx, new EngineException(errors).setCtx(args.ctx));
}
});
}
return res;
}
@Expose(target = ExposeTarget.STATIC)
private static PromiseLib __race(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var res = new PromiseLib();
for (var i = 0; i < promises.size(); i++) {
var val = promises.get(i);
if (res.state != STATE_PENDING) break;
handle(args.ctx, val, new Handle() {
@Override public void onFulfil(Object val) { res.fulfill(args.ctx, val); }
@Override public void onReject(EngineException err) { res.reject(args.ctx, err); }
});
}
return res;
}
@Expose(target = ExposeTarget.STATIC)
private static PromiseLib __all(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var n = new int[] { promises.size() };
var res = new PromiseLib();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
if (res.state != STATE_PENDING) break;
var index = i;
var val = promises.get(i);
handle(args.ctx, val, new Handle() {
@Override public void onFulfil(Object val) {
result.set(args.ctx, index, val);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, result);
}
@Override public void onReject(EngineException err) {
res.reject(args.ctx, err);
}
});
}
if (n[0] <= 0) res.fulfill(args.ctx, result);
return res;
}
@Expose(target = ExposeTarget.STATIC)
private static PromiseLib __allSettled(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var n = new int[] { promises.size() };
var res = new PromiseLib();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
if (res.state != STATE_PENDING) break;
var index = i;
handle(args.ctx, promises.get(i), new Handle() {
@Override public void onFulfil(Object val) {
var desc = new ObjectValue();
desc.defineProperty(args.ctx, "status", "fulfilled");
desc.defineProperty(args.ctx, "value", val);
result.set(args.ctx, index, desc);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, res);
}
@Override public void onReject(EngineException err) {
var desc = new ObjectValue();
desc.defineProperty(args.ctx, "status", "reject");
desc.defineProperty(args.ctx, "value", err.value);
result.set(args.ctx, index, desc);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, res);
}
});
}
if (n[0] <= 0) res.fulfill(args.ctx, result);
return res;
}
@Expose
private static Object __then(Arguments args) {
var onFulfill = args.get(0) instanceof FunctionValue ? args.convert(0, FunctionValue.class) : null;
var onReject = args.get(1) instanceof FunctionValue ? args.convert(1, FunctionValue.class) : null;
var res = new PromiseLib();
handle(args.ctx, args.self, new Handle() {
@Override public void onFulfil(Object val) {
try { res.fulfill(args.ctx, onFulfill.call(args.ctx, null, val)); }
catch (EngineException e) { res.reject(args.ctx, e); }
}
@Override public void onReject(EngineException err) {
try { res.fulfill(args.ctx, onReject.call(args.ctx, null, err.value)); }
catch (EngineException e) { res.reject(args.ctx, e); }
}
}.defer(args.ctx.engine));
return res;
}
@Expose
private static Object __catch(Arguments args) {
return __then(new Arguments(args.ctx, args.self, null, args.get(0)));
}
@Expose
private static Object __finally(Arguments args) {
var func = args.get(0) instanceof FunctionValue ? args.convert(0, FunctionValue.class) : null;
var res = new PromiseLib();
handle(args.ctx, args.self, new Handle() {
@Override public void onFulfil(Object val) {
try {
func.call(args.ctx);
res.fulfill(args.ctx, val);
}
catch (EngineException e) { res.reject(args.ctx, e); }
}
@Override public void onReject(EngineException err) {
try {
func.call(args.ctx);
res.reject(args.ctx, err);
}
catch (EngineException e) { res.reject(args.ctx, e); }
}
}.defer(args.ctx.engine));
return res;
}
@ExposeConstructor
private static PromiseLib __constructor(Arguments args) {
var func = args.convert(0, FunctionValue.class);
var res = new PromiseLib();
try {
func.call(
args.ctx, null,
new NativeFunction(null, _args -> {
res.fulfill(_args.ctx, _args.get(0));
return null;
}),
new NativeFunction(null, _args -> {
res.reject(_args.ctx, new EngineException(_args.get(0)).setCtx(_args.ctx));
return null;
})
);
}
catch (EngineException e) {
res.reject(args.ctx, e);
}
return res;
}
private List<Handle> handles = new ArrayList<>();
private int state = STATE_PENDING;
@ -262,7 +61,7 @@ public class PromiseLib {
}
if (state == STATE_REJECTED && !handled) {
Values.printError(new EngineException(val).setCtx(ctx.environment, ctx.engine), "(in promise)");
Values.printError(((EngineException)val).setCtx(ctx.environment, ctx.engine), "(in promise)");
}
handles = null;
@ -383,4 +182,205 @@ public class PromiseLib {
res.reject(ctx, value);
return res;
}
@Expose(value = "resolve", target = ExposeTarget.STATIC)
public static PromiseLib __ofResolved(Arguments args) {
return ofResolved(args.ctx, args.get(0));
}
@Expose(value = "reject", target = ExposeTarget.STATIC)
public static PromiseLib __ofRejected(Arguments args) {
return ofRejected(args.ctx, new EngineException(args.get(0)).setCtx(args.ctx));
}
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __any(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
if (promises.size() == 0) return ofRejected(args.ctx, EngineException.ofError("No promises passed to 'Promise.any'.").setCtx(args.ctx));
var n = new int[] { promises.size() };
var res = new PromiseLib();
var errors = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
var index = i;
var val = promises.get(i);
if (res.state != STATE_PENDING) break;
handle(args.ctx, val, new Handle() {
public void onFulfil(Object val) { res.fulfill(args.ctx, val); }
public void onReject(EngineException err) {
errors.set(args.ctx, index, err.value);
n[0]--;
if (n[0] <= 0) res.reject(args.ctx, new EngineException(errors).setCtx(args.ctx));
}
});
}
return res;
}
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __race(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var res = new PromiseLib();
for (var i = 0; i < promises.size(); i++) {
var val = promises.get(i);
if (res.state != STATE_PENDING) break;
handle(args.ctx, val, new Handle() {
@Override public void onFulfil(Object val) { res.fulfill(args.ctx, val); }
@Override public void onReject(EngineException err) { res.reject(args.ctx, err); }
});
}
return res;
}
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __all(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var n = new int[] { promises.size() };
var res = new PromiseLib();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
if (res.state != STATE_PENDING) break;
var index = i;
var val = promises.get(i);
handle(args.ctx, val, new Handle() {
@Override public void onFulfil(Object val) {
result.set(args.ctx, index, val);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, result);
}
@Override public void onReject(EngineException err) {
res.reject(args.ctx, err);
}
});
}
if (n[0] <= 0) res.fulfill(args.ctx, result);
return res;
}
@Expose(target = ExposeTarget.STATIC)
public static PromiseLib __allSettled(Arguments args) {
if (!(args.get(0) instanceof ArrayValue)) throw EngineException.ofType("Expected argument for any to be an array.");
var promises = args.convert(0, ArrayValue.class);
var n = new int[] { promises.size() };
var res = new PromiseLib();
var result = new ArrayValue();
for (var i = 0; i < promises.size(); i++) {
if (res.state != STATE_PENDING) break;
var index = i;
handle(args.ctx, promises.get(i), new Handle() {
@Override public void onFulfil(Object val) {
var desc = new ObjectValue();
desc.defineProperty(args.ctx, "status", "fulfilled");
desc.defineProperty(args.ctx, "value", val);
result.set(args.ctx, index, desc);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, res);
}
@Override public void onReject(EngineException err) {
var desc = new ObjectValue();
desc.defineProperty(args.ctx, "status", "reject");
desc.defineProperty(args.ctx, "value", err.value);
result.set(args.ctx, index, desc);
n[0]--;
if (n[0] <= 0) res.fulfill(args.ctx, res);
}
});
}
if (n[0] <= 0) res.fulfill(args.ctx, result);
return res;
}
@Expose
public static Object __then(Arguments args) {
var onFulfill = args.get(0) instanceof FunctionValue ? args.convert(0, FunctionValue.class) : null;
var onReject = args.get(1) instanceof FunctionValue ? args.convert(1, FunctionValue.class) : null;
var res = new PromiseLib();
handle(args.ctx, args.self, new Handle() {
@Override public void onFulfil(Object val) {
try { res.fulfill(args.ctx, onFulfill.call(args.ctx, null, val)); }
catch (EngineException e) { res.reject(args.ctx, e); }
}
@Override public void onReject(EngineException err) {
try { res.fulfill(args.ctx, onReject.call(args.ctx, null, err.value)); }
catch (EngineException e) { res.reject(args.ctx, e); }
}
}.defer(args.ctx.engine));
return res;
}
@Expose
public static Object __catch(Arguments args) {
return __then(new Arguments(args.ctx, args.self, null, args.get(0)));
}
@Expose
public static Object __finally(Arguments args) {
var func = args.get(0) instanceof FunctionValue ? args.convert(0, FunctionValue.class) : null;
var res = new PromiseLib();
handle(args.ctx, args.self, new Handle() {
@Override public void onFulfil(Object val) {
try {
func.call(args.ctx);
res.fulfill(args.ctx, val);
}
catch (EngineException e) { res.reject(args.ctx, e); }
}
@Override public void onReject(EngineException err) {
try {
func.call(args.ctx);
res.reject(args.ctx, err);
}
catch (EngineException e) { res.reject(args.ctx, e); }
}
}.defer(args.ctx.engine));
return res;
}
@ExposeConstructor
public static PromiseLib __constructor(Arguments args) {
var func = args.convert(0, FunctionValue.class);
var res = new PromiseLib();
try {
func.call(
args.ctx, null,
new NativeFunction(null, _args -> {
res.fulfill(_args.ctx, _args.get(0));
return null;
}),
new NativeFunction(null, _args -> {
res.reject(_args.ctx, new EngineException(_args.get(0)).setCtx(_args.ctx));
return null;
})
);
}
catch (EngineException e) {
res.reject(args.ctx, e);
}
return res;
}
}

View File

@ -6,15 +6,12 @@ import me.topchetoeu.jscript.interop.WrapperName;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.ExposeConstructor;
import me.topchetoeu.jscript.interop.ExposeField;
import me.topchetoeu.jscript.interop.ExposeTarget;
@WrapperName("RangeError")
public class RangeErrorLib extends ErrorLib {
@ExposeField(target = ExposeTarget.STATIC)
public static final String __name = "RangeError";
@ExposeField public static final String __name = "RangeError";
@ExposeConstructor
public static ObjectValue constructor(Arguments args) {
@ExposeConstructor public static ObjectValue constructor(Arguments args) {
var target = ErrorLib.__constructor(args);
target.setPrototype(PlaceholderProto.RANGE_ERROR);
return target;

View File

@ -24,13 +24,13 @@ public class SetLib {
}
@Expose public ObjectValue __entries(Arguments args) {
return ArrayValue.of(args.ctx, set.stream().map(v -> new ArrayValue(args.ctx, v, v)).collect(Collectors.toList()));
return Values.toJSIterator(args.ctx, set.stream().map(v -> new ArrayValue(args.ctx, v, v)).collect(Collectors.toList()));
}
@Expose public ObjectValue __keys(Arguments args) {
return ArrayValue.of(args.ctx, set);
return Values.toJSIterator(args.ctx, set);
}
@Expose public ObjectValue __values(Arguments args) {
return ArrayValue.of(args.ctx, set);
return Values.toJSIterator(args.ctx, set);
}
@Expose public Object __add(Arguments args) {

View File

@ -21,9 +21,15 @@ import me.topchetoeu.jscript.interop.WrapperName;
public class StringLib {
public final String value;
@Override public String toString() { return value; }
public StringLib(String val) {
this.value = val;
}
private static String passThis(Arguments args, String funcName) {
var val = args.self;
if (val instanceof StringLib) return ((StringLib)val).value;
if (Values.isWrapper(val, StringLib.class)) return Values.wrapper(val, StringLib.class).value;
else if (val instanceof String) return (String)val;
else throw EngineException.ofType(String.format("'%s' may only be called upon object and primitve strings.", funcName));
}
@ -43,16 +49,22 @@ public class StringLib {
@Expose public static String __substring(Arguments args) {
var val = passThis(args, "substring");
var start = normalizeI(args.getInt(0), val.length(), true);
var end = normalizeI(args.getInt(1, val.length()), val.length(), true);
var start = Math.max(0, Math.min(val.length(), args.getInt(0)));
var end = Math.max(0, Math.min(val.length(), args.getInt(1, val.length())));
if (end < start) {
var tmp = end;
end = start;
start = tmp;
}
return val.substring(start, end);
}
@Expose public static String __substr(Arguments args) {
var val = passThis(args, "substr");
var start = normalizeI(args.getInt(0), val.length(), true);
int len = normalizeI(args.getInt(0), val.length() - start, true);
return val.substring(start, start + len);
int end = normalizeI(args.getInt(1, val.length() - start) + start, val.length(), true);
return val.substring(start, end);
}
@Expose public static String __toLowerCase(Arguments args) {
@ -206,6 +218,7 @@ public class StringLib {
var pattern = Pattern.quote(Values.toString(args.ctx, term));
if (lim == null) parts = val.split(pattern);
else if ((double)lim < 1) return new ArrayValue();
else if (sensible) parts = val.split(pattern, (int)(double)lim);
else {
var limit = (int)(double)lim;
@ -232,8 +245,11 @@ public class StringLib {
}
@Expose public static String __slice(Arguments args) {
passThis(args, "slice");
return __substring(args);
var self = passThis(args, "slice");
var start = normalizeI(args.getInt(0), self.length(), false);
var end = normalizeI(args.getInt(1, self.length()), self.length(), false);
return __substring(new Arguments(args.ctx, self, start, end));
}
@Expose public static String __concat(Arguments args) {
@ -254,7 +270,7 @@ public class StringLib {
}
@ExposeConstructor public static Object __constructor(Arguments args) {
var val = args.getString(0);
var val = args.getString(0, "");
if (args.self instanceof ObjectValue) return new StringLib(val);
else return val;
}
@ -272,8 +288,4 @@ public class StringLib {
for (var i = 0; i < val.length; i++) arr[i] = (char)val[i];
return new String(arr);
}
public StringLib(String val) {
this.value = val;
}
}

View File

@ -5,6 +5,7 @@ import java.util.Map;
import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Symbol;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.Expose;
@ -40,7 +41,7 @@ public class SymbolLib {
private static Symbol passThis(Arguments args, String funcName) {
var val = args.self;
if (val instanceof SymbolLib) return ((SymbolLib)val).value;
if (Values.isWrapper(val, SymbolLib.class)) return Values.wrapper(val, SymbolLib.class).value;
else if (val instanceof Symbol) return (Symbol)val;
else throw EngineException.ofType(String.format("'%s' may only be called upon object and primitve symbols.", funcName));
}
@ -75,6 +76,6 @@ public class SymbolLib {
}
@Expose(target = ExposeTarget.STATIC)
public static String __keyFor(Arguments args) {
return passThis(args.slice(-1), "keyFor").value;
return passThis(new Arguments(args.ctx, args.get(0)), "keyFor").value;
}
}

View File

@ -6,15 +6,12 @@ import me.topchetoeu.jscript.interop.WrapperName;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.ExposeConstructor;
import me.topchetoeu.jscript.interop.ExposeField;
import me.topchetoeu.jscript.interop.ExposeTarget;
@WrapperName("SyntaxError")
public class SyntaxErrorLib extends ErrorLib {
@ExposeField(target = ExposeTarget.STATIC)
public static final String __name = "SyntaxError";
@ExposeField public static final String __name = "SyntaxError";
@ExposeConstructor
public static ObjectValue __constructor(Arguments args) {
@ExposeConstructor public static ObjectValue __constructor(Arguments args) {
var target = ErrorLib.__constructor(args);
target.setPrototype(PlaceholderProto.SYNTAX_ERROR);
return target;

View File

@ -6,15 +6,12 @@ import me.topchetoeu.jscript.interop.WrapperName;
import me.topchetoeu.jscript.interop.Arguments;
import me.topchetoeu.jscript.interop.ExposeConstructor;
import me.topchetoeu.jscript.interop.ExposeField;
import me.topchetoeu.jscript.interop.ExposeTarget;
@WrapperName("TypeError")
public class TypeErrorLib extends ErrorLib {
@ExposeField(target = ExposeTarget.STATIC)
public static final String __name = "TypeError";
@ExposeField public static final String __name = "TypeError";
@ExposeConstructor
public static ObjectValue __constructor(Arguments args) {
@ExposeConstructor public static ObjectValue __constructor(Arguments args) {
var target = ErrorLib.__constructor(args);
target.setPrototype(PlaceholderProto.TYPE_ERROR);
return target;