Compare commits

..

6 Commits

12 changed files with 70 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
project_group = me.topchetoeu project_group = me.topchetoeu
project_name = jscript project_name = jscript
project_version = 0.9.40-beta project_version = 0.9.41-beta
main_class = me.topchetoeu.jscript.utils.JScriptRepl main_class = me.topchetoeu.jscript.utils.JScriptRepl

View File

@@ -51,7 +51,7 @@ public class FilesystemLib {
try { try {
if (fs.stat(path).type != EntryType.FILE) { if (fs.stat(path).type != EntryType.FILE) {
throw new FilesystemException(ErrorReason.DOESNT_EXIST, "Not a file").setAction(ActionType.OPEN); throw new FilesystemException(ErrorReason.DOESNT_EXIST, "Not a file").setAction(ActionType.OPEN).setPath(path);
} }
return new FileLib(fs.open(path, _mode)); return new FileLib(fs.open(path, _mode));

View File

@@ -1,16 +1,24 @@
package me.topchetoeu.jscript.lib; package me.topchetoeu.jscript.lib;
import me.topchetoeu.jscript.common.Filename;
import me.topchetoeu.jscript.runtime.Compiler;
import me.topchetoeu.jscript.runtime.Context;
import me.topchetoeu.jscript.runtime.scope.ValueVariable;
import me.topchetoeu.jscript.runtime.values.ArrayValue; import me.topchetoeu.jscript.runtime.values.ArrayValue;
import me.topchetoeu.jscript.runtime.values.CodeFunction; import me.topchetoeu.jscript.runtime.values.CodeFunction;
import me.topchetoeu.jscript.runtime.values.FunctionValue; import me.topchetoeu.jscript.runtime.values.FunctionValue;
import me.topchetoeu.jscript.runtime.values.NativeFunction; import me.topchetoeu.jscript.runtime.values.NativeFunction;
import me.topchetoeu.jscript.runtime.values.Values;
import me.topchetoeu.jscript.utils.interop.Arguments; import me.topchetoeu.jscript.utils.interop.Arguments;
import me.topchetoeu.jscript.utils.interop.Expose; import me.topchetoeu.jscript.utils.interop.Expose;
import me.topchetoeu.jscript.utils.interop.ExposeConstructor;
import me.topchetoeu.jscript.utils.interop.ExposeTarget; import me.topchetoeu.jscript.utils.interop.ExposeTarget;
import me.topchetoeu.jscript.utils.interop.WrapperName; import me.topchetoeu.jscript.utils.interop.WrapperName;
@WrapperName("Function") @WrapperName("Function")
public class FunctionLib { public class FunctionLib {
private static int i;
@Expose public static Object __apply(Arguments args) { @Expose public static Object __apply(Arguments args) {
return args.self(FunctionValue.class).call(args.ctx, args.get(0), args.convert(1, ArrayValue.class).toArray()); return args.self(FunctionValue.class).call(args.ctx, args.get(0), args.convert(1, ArrayValue.class).toArray());
} }
@@ -51,4 +59,25 @@ public class FunctionLib {
public static FunctionValue __generator(Arguments args) { public static FunctionValue __generator(Arguments args) {
return new GeneratorFunctionLib(args.convert(0, CodeFunction.class)); return new GeneratorFunctionLib(args.convert(0, CodeFunction.class));
} }
@ExposeConstructor
public static Object __constructor(Arguments args) {
var compiler = Compiler.get(args);
var parts = args.convert(String.class);
if (parts.length == 0) parts = new String[] { "" };
var src = "return function(";
for (var i = 0; i < parts.length - 1; i++) {
if (i != 0) src += ",";
src += parts[i];
}
src += "){" + parts[parts.length - 1] + "}";
var body = compiler.compile(new Filename("jscript", "func/" + i++), src);
var func = new CodeFunction(Context.clean(args.ctx), "", body, new ValueVariable[0]);
return Values.call(args, func, null);
}
} }

View File

@@ -92,7 +92,7 @@ public class Context implements Extensions {
return new Context(ext); return new Context(ext);
} }
public static Extensions clean(Extensions ext) { public static Extensions clean(Extensions ext) {
if (ext instanceof Context) return ((Context)ext).extensions; if (ext instanceof Context) return clean(((Context)ext).extensions);
else return ext; else return ext;
} }
} }

View File

@@ -20,7 +20,7 @@ public class GlobalScope {
return Values.hasMember(ext, obj, name, false); return Values.hasMember(ext, obj, name, false);
} }
public GlobalScope globalChild() { public GlobalScope child() {
var obj = new ObjectValue(); var obj = new ObjectValue();
Values.setPrototype(null, obj, this.obj); Values.setPrototype(null, obj, this.obj);
return new GlobalScope(obj); return new GlobalScope(obj);

View File

@@ -7,7 +7,28 @@ import me.topchetoeu.jscript.runtime.Key;
import me.topchetoeu.jscript.utils.interop.NativeWrapperProvider; import me.topchetoeu.jscript.utils.interop.NativeWrapperProvider;
public class NativeWrapper extends ObjectValue { public class NativeWrapper extends ObjectValue {
private static final Key<WeakHashMap<Object, NativeWrapper>> WRAPPERS = new Key<>(); private static class MapKey {
public final Object key;
@Override
public int hashCode() {
return System.identityHashCode(key);
}
@Override
public boolean equals(Object obj) {
if (this == null || obj == null) return this == null && obj == null;
if (!(obj instanceof MapKey)) return false;
var other = (MapKey)obj;
return other.key == key;
}
public MapKey(Object key) {
this.key = key;
}
}
private static final Key<WeakHashMap<MapKey, NativeWrapper>> WRAPPERS = new Key<>();
private static final Object NATIVE_PROTO = new Object(); private static final Object NATIVE_PROTO = new Object();
public final Object wrapped; public final Object wrapped;
@@ -48,10 +69,12 @@ public class NativeWrapper extends ObjectValue {
exts.add(WRAPPERS, wrappers); exts.add(WRAPPERS, wrappers);
} }
if (wrappers.containsKey(wrapped)) return wrappers.get(wrapped); var key = new MapKey(wrapped);
if (wrappers.containsKey(key)) return wrappers.get(key);
var res = new NativeWrapper(wrapped); var res = new NativeWrapper(wrapped);
wrappers.put(wrapped, res); wrappers.put(key, res);
return res; return res;
} }

View File

@@ -89,7 +89,6 @@ public class JScriptRepl {
private static void initEnv() { private static void initEnv() {
environment = Internals.apply(environment); environment = Internals.apply(environment);
var wp = NativeWrapperProvider.get(environment);
var glob = GlobalScope.get(environment); var glob = GlobalScope.get(environment);
glob.define(null, false, new NativeFunction("exit", args -> { glob.define(null, false, new NativeFunction("exit", args -> {

View File

@@ -32,7 +32,7 @@ public abstract class BaseFile<T> implements File {
@Override public synchronized long seek(long offset, int pos) { @Override public synchronized long seek(long offset, int pos) {
try { try {
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED); if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
if (!mode.writable) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for seeking."); if (mode == Mode.NONE) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for seeking.");
return onSeek(offset, pos); return onSeek(offset, pos);
} }
catch (FilesystemException e) { throw e.setAction(ActionType.SEEK); } catch (FilesystemException e) { throw e.setAction(ActionType.SEEK); }

View File

@@ -54,16 +54,12 @@ public class FilesystemException extends RuntimeException {
@Override public String getMessage() { @Override public String getMessage() {
var parts = new ArrayList<String>(10); var parts = new ArrayList<String>(10);
path = String.join(" ", parts).trim();
if (path.isEmpty()) path = null;
parts.clear();
parts.add(action == null ? "An action performed upon " : action.readable(reason.usePast)); parts.add(action == null ? "An action performed upon " : action.readable(reason.usePast));
if (entry == EntryType.FILE) parts.add("file"); if (entry == EntryType.FILE) parts.add("file");
if (entry == EntryType.FOLDER) parts.add("folder"); if (entry == EntryType.FOLDER) parts.add("folder");
if (path != null) parts.add(path); if (path != null && !path.isBlank()) parts.add(path.trim());
parts.add(reason.readable); parts.add(reason.readable);

View File

@@ -1,5 +1,6 @@
package me.topchetoeu.jscript.utils.filesystem; package me.topchetoeu.jscript.utils.filesystem;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -35,7 +36,8 @@ public class PhysicalFilesystem implements Filesystem {
)); ));
else return handles.put(new PhysicalFile(path, perms)); else return handles.put(new PhysicalFile(path, perms));
} }
catch (IOException e) { throw new FilesystemException(ErrorReason.DOESNT_EXIST); } catch (FileNotFoundException e) { throw new FilesystemException(ErrorReason.DOESNT_EXIST); }
catch (IOException e) { throw new FilesystemException(ErrorReason.NO_PERMISSION); }
} }
catch (FilesystemException e) { throw e.setAction(ActionType.OPEN).setPath(_path); } catch (FilesystemException e) { throw e.setAction(ActionType.OPEN).setPath(_path); }
} }
@@ -68,12 +70,7 @@ public class PhysicalFilesystem implements Filesystem {
if (!Files.exists(path)) return new FileStat(Mode.NONE, EntryType.NONE); if (!Files.exists(path)) return new FileStat(Mode.NONE, EntryType.NONE);
var perms = Mode.NONE; var perms = Mode.of(Files.isReadable(path), Files.isWritable(path));
if (Files.isReadable(path)) {
if (Files.isWritable(path)) perms = Mode.READ_WRITE;
else perms = Mode.READ;
}
if (perms == Mode.NONE) return new FileStat(Mode.NONE, EntryType.NONE); if (perms == Mode.NONE) return new FileStat(Mode.NONE, EntryType.NONE);

View File

@@ -293,7 +293,7 @@ public class NativeWrapperProvider implements Copyable {
new NativeFunction(getName(appliers), args -> { throw EngineException.ofError("This constructor is not invokable."); }) : new NativeFunction(getName(appliers), args -> { throw EngineException.ofError("This constructor is not invokable."); }) :
create(getName(appliers), constr); create(getName(appliers), constr);
if (constr == null && !apply(res, ExposeTarget.CONSTRUCTOR, appliers)) return null; if (!apply(res, ExposeTarget.CONSTRUCTOR, appliers) && constr == null) return null;
return res; return res;
} }

View File

@@ -6,6 +6,7 @@ import me.topchetoeu.jscript.common.Filename;
import me.topchetoeu.jscript.runtime.Context; import me.topchetoeu.jscript.runtime.Context;
import me.topchetoeu.jscript.runtime.Extensions; import me.topchetoeu.jscript.runtime.Extensions;
import me.topchetoeu.jscript.runtime.Key; import me.topchetoeu.jscript.runtime.Key;
import me.topchetoeu.jscript.runtime.scope.GlobalScope;
import me.topchetoeu.jscript.utils.filesystem.Filesystem; import me.topchetoeu.jscript.utils.filesystem.Filesystem;
import me.topchetoeu.jscript.utils.filesystem.Mode; import me.topchetoeu.jscript.utils.filesystem.Mode;
@@ -25,8 +26,10 @@ public interface ModuleRepo {
if (modules.containsKey(name)) return modules.get(name); if (modules.containsKey(name)) return modules.get(name);
var env = ctx.extensions.child(); var env = Context.clean(ctx.extensions).child();
env.add(CWD, fs.normalize(name, "..")); env.add(CWD, fs.normalize(name, ".."));
var glob = env.get(GlobalScope.KEY);
env.add(GlobalScope.KEY, glob.child());
var mod = new SourceModule(filename, src, env); var mod = new SourceModule(filename, src, env);
modules.put(name, mod); modules.put(name, mod);