refactor: fully separate event loop from context
This commit is contained in:
parent
52489ad3a8
commit
49dd725669
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.common;
|
||||||
|
|
||||||
public class FunctionBody {
|
public class FunctionBody {
|
||||||
public final FunctionBody[] children;
|
public final FunctionBody[] children;
|
@ -1,11 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.common;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
||||||
|
|
||||||
public class Instruction {
|
public class Instruction {
|
@ -1,7 +1,9 @@
|
|||||||
package me.topchetoeu.jscript.common;
|
package me.topchetoeu.jscript.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Location implements Comparable<Location> {
|
public class Location implements Comparable<Location> {
|
||||||
public static final Location INTERNAL = new Location(0, 0, new Filename("jscript", "native"));
|
public static final Location INTERNAL = new Location(-1, -1, new Filename("jscript", "native"));
|
||||||
private int line;
|
private int line;
|
||||||
private int start;
|
private int start;
|
||||||
private Filename filename;
|
private Filename filename;
|
||||||
@ -12,7 +14,13 @@ public class Location implements Comparable<Location> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return filename.toString() + ":" + line + ":" + start;
|
var res = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (filename != null) res.add(filename.toString());
|
||||||
|
if (line >= 0) res.add(line + "");
|
||||||
|
if (start >= 0) res.add(start + "");
|
||||||
|
|
||||||
|
return String.join(":", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location add(int n, boolean clone) {
|
public Location add(int n, boolean clone) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.common;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -13,11 +13,6 @@ public class Reading {
|
|||||||
return reader.readLine();
|
return reader.readLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the given stream to a string
|
|
||||||
* @param in
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String streamToString(InputStream in) {
|
public static String streamToString(InputStream in) {
|
||||||
try {
|
try {
|
||||||
return new String(in.readAllBytes());
|
return new String(in.readAllBytes());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.compilation.mapping;
|
package me.topchetoeu.jscript.common.mapping;
|
||||||
|
|
||||||
public enum ConvertType {
|
public enum ConvertType {
|
||||||
Exact,
|
Exact,
|
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.compilation.mapping;
|
package me.topchetoeu.jscript.common.mapping;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -9,8 +9,9 @@ import java.util.TreeMap;
|
|||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
||||||
|
import me.topchetoeu.jscript.utils.mapping.SourceMap;
|
||||||
|
|
||||||
public class FunctionMap {
|
public class FunctionMap {
|
||||||
public static class FunctionMapBuilder {
|
public static class FunctionMapBuilder {
|
||||||
@ -22,10 +23,12 @@ public class FunctionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FunctionMapBuilder setDebug(Location loc, BreakpointType type) {
|
public FunctionMapBuilder setDebug(Location loc, BreakpointType type) {
|
||||||
|
if (loc == null || type == null || type == BreakpointType.NONE) return this;
|
||||||
breakpoints.put(loc, type);
|
breakpoints.put(loc, type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public FunctionMapBuilder setLocation(int i, Location loc) {
|
public FunctionMapBuilder setLocation(int i, Location loc) {
|
||||||
|
if (loc == null || i < 0) return this;
|
||||||
sourceMap.put(i, loc);
|
sourceMap.put(i, loc);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -36,9 +39,11 @@ public class FunctionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Location first() {
|
public Location first() {
|
||||||
|
if (sourceMap.size() == 0) return null;
|
||||||
return sourceMap.firstEntry().getValue();
|
return sourceMap.firstEntry().getValue();
|
||||||
}
|
}
|
||||||
public Location last() {
|
public Location last() {
|
||||||
|
if (sourceMap.size() == 0) return null;
|
||||||
return sourceMap.lastEntry().getValue();
|
return sourceMap.lastEntry().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +73,9 @@ public class FunctionMap {
|
|||||||
public Location toLocation(int pc, boolean approxiamte) {
|
public Location toLocation(int pc, boolean approxiamte) {
|
||||||
var res = pcToLoc.get(pc);
|
var res = pcToLoc.get(pc);
|
||||||
if (!approxiamte || res != null) return res;
|
if (!approxiamte || res != null) return res;
|
||||||
return pcToLoc.headMap(pc, true).lastEntry().getValue();
|
var entry = pcToLoc.headMap(pc, true).lastEntry();
|
||||||
|
if (entry == null) return null;
|
||||||
|
else return entry.getValue();
|
||||||
}
|
}
|
||||||
public Location toLocation(int pc) {
|
public Location toLocation(int pc) {
|
||||||
return toLocation(pc, false);
|
return toLocation(pc, false);
|
||||||
@ -85,9 +92,11 @@ public class FunctionMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Location start() {
|
public Location start() {
|
||||||
|
if (pcToLoc.size() == 0) return null;
|
||||||
return pcToLoc.firstEntry().getValue();
|
return pcToLoc.firstEntry().getValue();
|
||||||
}
|
}
|
||||||
public Location end() {
|
public Location end() {
|
||||||
|
if (pcToLoc.size() == 0) return null;
|
||||||
return pcToLoc.lastEntry().getValue();
|
return pcToLoc.lastEntry().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +135,9 @@ public class FunctionMap {
|
|||||||
|
|
||||||
if (b != null) pcToLoc.remove(b);
|
if (b != null) pcToLoc.remove(b);
|
||||||
if (a != null) locToPc.remove(a);
|
if (a != null) locToPc.remove(a);
|
||||||
|
|
||||||
|
pcToLoc.put(pc, loc);
|
||||||
|
locToPc.put(loc, pc);
|
||||||
}
|
}
|
||||||
for (var el : breakpoints.entrySet()) {
|
for (var el : breakpoints.entrySet()) {
|
||||||
if (el.getValue() == null || el.getValue() == BreakpointType.NONE) continue;
|
if (el.getValue() == null || el.getValue() == BreakpointType.NONE) continue;
|
@ -1,7 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
|
||||||
public abstract class AssignableStatement extends Statement {
|
public abstract class AssignableStatement extends Statement {
|
||||||
public abstract Statement toAssign(Statement val, Operation operation);
|
public abstract Statement toAssign(Statement val, Operation operation);
|
||||||
|
@ -4,10 +4,12 @@ import java.util.List;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.mapping.FunctionMap;
|
import me.topchetoeu.jscript.common.mapping.FunctionMap;
|
||||||
import me.topchetoeu.jscript.compilation.mapping.FunctionMap.FunctionMapBuilder;
|
import me.topchetoeu.jscript.common.mapping.FunctionMap.FunctionMapBuilder;
|
||||||
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
||||||
|
|
||||||
public class CompileResult {
|
public class CompileResult {
|
||||||
@ -59,6 +61,9 @@ public class CompileResult {
|
|||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunctionMap map() {
|
||||||
|
return map.build(scope);
|
||||||
|
}
|
||||||
public FunctionBody body() {
|
public FunctionBody body() {
|
||||||
var builtChildren = new FunctionBody[children.size()];
|
var builtChildren = new FunctionBody[children.size()];
|
||||||
|
|
||||||
@ -67,10 +72,6 @@ public class CompileResult {
|
|||||||
return new FunctionBody(scope.localsCount(), length, instructions.toArray(Instruction[]::new), builtChildren);
|
return new FunctionBody(scope.localsCount(), length, instructions.toArray(Instruction[]::new), builtChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionMap map() {
|
|
||||||
return map.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompileResult(LocalScopeRecord scope) {
|
public CompileResult(LocalScopeRecord scope) {
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,9 @@ package me.topchetoeu.jscript.compilation;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
||||||
|
|
||||||
public class CompoundStatement extends Statement {
|
public class CompoundStatement extends Statement {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
|
|
||||||
public abstract class Statement {
|
public abstract class Statement {
|
||||||
private Location _loc;
|
private Location _loc;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
||||||
|
|
||||||
public class ThrowSyntaxStatement extends Statement {
|
public class ThrowSyntaxStatement extends Statement {
|
||||||
|
@ -2,8 +2,9 @@ package me.topchetoeu.jscript.compilation;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
import me.topchetoeu.jscript.compilation.values.FunctionStatement;
|
||||||
|
|
||||||
public class VariableDeclareStatement extends Statement {
|
public class VariableDeclareStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class BreakStatement extends Statement {
|
public class BreakStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ContinueStatement extends Statement {
|
public class ContinueStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class DebugStatement extends Statement {
|
public class DebugStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class DeleteStatement extends Statement {
|
public class DeleteStatement extends Statement {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
|
|
||||||
public class DoWhileStatement extends Statement {
|
public class DoWhileStatement extends Statement {
|
||||||
public final Statement condition, body;
|
public final Statement condition, body;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class ForInStatement extends Statement {
|
public class ForInStatement extends Statement {
|
||||||
public final String varName;
|
public final String varName;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
|
|
||||||
public class ForStatement extends Statement {
|
public class ForStatement extends Statement {
|
||||||
public final Statement declaration, assignment, condition, body;
|
public final Statement declaration, assignment, condition, body;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
|
|
||||||
public class IfStatement extends Statement {
|
public class IfStatement extends Statement {
|
||||||
public final Statement condition, body, elseBody;
|
public final Statement condition, body, elseBody;
|
||||||
@ -31,7 +31,7 @@ public class IfStatement extends Statement {
|
|||||||
elseBody.compile(target, pollute, breakpoint);
|
elseBody.compile(target, pollute, breakpoint);
|
||||||
int end = target.size();
|
int end = target.size();
|
||||||
|
|
||||||
target.set(start, Instruction.jmpIfNot(mid - start - 1));
|
target.set(start, Instruction.jmpIfNot(mid - start + 1));
|
||||||
target.set(mid, Instruction.jmp(end - mid));
|
target.set(mid, Instruction.jmp(end - mid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ReturnStatement extends Statement {
|
public class ReturnStatement extends Statement {
|
||||||
|
@ -2,13 +2,13 @@ package me.topchetoeu.jscript.compilation.control;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.Type;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.Type;
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class SwitchStatement extends Statement {
|
public class SwitchStatement extends Statement {
|
||||||
public static class SwitchCase {
|
public static class SwitchCase {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ThrowStatement extends Statement {
|
public class ThrowStatement extends Statement {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
|
|
||||||
public class TryStatement extends Statement {
|
public class TryStatement extends Statement {
|
||||||
public final Statement tryBody;
|
public final Statement tryBody;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.Type;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.Type;
|
|
||||||
|
|
||||||
public class WhileStatement extends Statement {
|
public class WhileStatement extends Statement {
|
||||||
public final Statement condition, body;
|
public final Statement condition, body;
|
||||||
|
@ -3,7 +3,7 @@ package me.topchetoeu.jscript.compilation.parsing;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
|
||||||
public enum Operator {
|
public enum Operator {
|
||||||
MULTIPLY("*", Operation.MULTIPLY, 13),
|
MULTIPLY("*", Operation.MULTIPLY, 13),
|
||||||
|
@ -8,14 +8,15 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.compilation.*;
|
import me.topchetoeu.jscript.compilation.*;
|
||||||
import me.topchetoeu.jscript.compilation.VariableDeclareStatement.Pair;
|
import me.topchetoeu.jscript.compilation.VariableDeclareStatement.Pair;
|
||||||
import me.topchetoeu.jscript.compilation.control.*;
|
import me.topchetoeu.jscript.compilation.control.*;
|
||||||
import me.topchetoeu.jscript.compilation.control.SwitchStatement.SwitchCase;
|
import me.topchetoeu.jscript.compilation.control.SwitchStatement.SwitchCase;
|
||||||
import me.topchetoeu.jscript.compilation.parsing.ParseRes.State;
|
import me.topchetoeu.jscript.compilation.parsing.ParseRes.State;
|
||||||
import me.topchetoeu.jscript.compilation.values.*;
|
import me.topchetoeu.jscript.compilation.values.*;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
|
||||||
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
||||||
|
|
||||||
@ -400,6 +401,10 @@ public class Parsing {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean inBounds(List<Token> tokens, int i) {
|
||||||
|
return i >= 0 && i < tokens.size();
|
||||||
|
}
|
||||||
|
|
||||||
private static String parseString(Location loc, String literal) {
|
private static String parseString(Location loc, String literal) {
|
||||||
var res = new StringBuilder();
|
var res = new StringBuilder();
|
||||||
|
|
||||||
@ -605,49 +610,41 @@ public class Parsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ParseRes<String> parseIdentifier(List<Token> tokens, int i) {
|
public static ParseRes<String> parseIdentifier(List<Token> tokens, int i) {
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isIdentifier()) {
|
if (tokens.get(i).isIdentifier()) {
|
||||||
return ParseRes.res(tokens.get(i).identifier(), 1);
|
return ParseRes.res(tokens.get(i).identifier(), 1);
|
||||||
}
|
}
|
||||||
else return ParseRes.failed();
|
else return ParseRes.failed();
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static ParseRes<Operator> parseOperator(List<Token> tokens, int i) {
|
public static ParseRes<Operator> parseOperator(List<Token> tokens, int i) {
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isOperator()) {
|
if (tokens.get(i).isOperator()) {
|
||||||
return ParseRes.res(tokens.get(i).operator(), 1);
|
return ParseRes.res(tokens.get(i).operator(), 1);
|
||||||
}
|
}
|
||||||
else return ParseRes.failed();
|
else return ParseRes.failed();
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIdentifier(List<Token> tokens, int i, String lit) {
|
public static boolean isIdentifier(List<Token> tokens, int i, String lit) {
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isIdentifier(lit)) {
|
if (tokens.get(i).isIdentifier(lit)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static boolean isOperator(List<Token> tokens, int i, Operator op) {
|
public static boolean isOperator(List<Token> tokens, int i, Operator op) {
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isOperator(op)) {
|
if (tokens.get(i).isOperator(op)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static boolean isStatementEnd(List<Token> tokens, int i) {
|
public static boolean isStatementEnd(List<Token> tokens, int i) {
|
||||||
if (isOperator(tokens, i, Operator.SEMICOLON)) return true;
|
if (isOperator(tokens, i, Operator.SEMICOLON)) return true;
|
||||||
@ -662,32 +659,27 @@ public class Parsing {
|
|||||||
|
|
||||||
public static ParseRes<ConstantStatement> parseString(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<ConstantStatement> parseString(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isString()) {
|
if (tokens.get(i).isString()) {
|
||||||
return ParseRes.res(new ConstantStatement(loc, tokens.get(i).string()), 1);
|
return ParseRes.res(new ConstantStatement(loc, tokens.get(i).string()), 1);
|
||||||
}
|
}
|
||||||
else return ParseRes.failed();
|
else return ParseRes.failed();
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static ParseRes<ConstantStatement> parseNumber(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<ConstantStatement> parseNumber(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isNumber()) {
|
if (tokens.get(i).isNumber()) {
|
||||||
return ParseRes.res(new ConstantStatement(loc, tokens.get(i).number()), 1);
|
return ParseRes.res(new ConstantStatement(loc, tokens.get(i).number()), 1);
|
||||||
}
|
}
|
||||||
else return ParseRes.failed();
|
else return ParseRes.failed();
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public static ParseRes<RegexStatement> parseRegex(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<RegexStatement> parseRegex(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
if (tokens.get(i).isRegex()) {
|
if (tokens.get(i).isRegex()) {
|
||||||
var val = tokens.get(i).regex();
|
var val = tokens.get(i).regex();
|
||||||
var index = val.lastIndexOf('/');
|
var index = val.lastIndexOf('/');
|
||||||
@ -697,9 +689,7 @@ public class Parsing {
|
|||||||
}
|
}
|
||||||
else return ParseRes.failed();
|
else return ParseRes.failed();
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ParseRes<ArrayStatement> parseArray(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<ArrayStatement> parseArray(Filename filename, List<Token> tokens, int i) {
|
||||||
@ -776,15 +766,13 @@ public class Parsing {
|
|||||||
public static ParseRes<String> parsePropName(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<String> parsePropName(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
|
|
||||||
try {
|
if (inBounds(tokens, i)) {
|
||||||
var token = tokens.get(i);
|
var token = tokens.get(i);
|
||||||
|
|
||||||
if (token.isNumber() || token.isIdentifier() || token.isString()) return ParseRes.res(token.rawValue, 1);
|
if (token.isNumber() || token.isIdentifier() || token.isString()) return ParseRes.res(token.rawValue, 1);
|
||||||
else return ParseRes.error(loc, "Expected identifier, string or number literal.");
|
else return ParseRes.error(loc, "Expected identifier, string or number literal.");
|
||||||
}
|
}
|
||||||
catch (IndexOutOfBoundsException e) {
|
else return ParseRes.failed();
|
||||||
return ParseRes.failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public static ParseRes<ObjProp> parseObjectProp(Filename filename, List<Token> tokens, int i) {
|
public static ParseRes<ObjProp> parseObjectProp(Filename filename, List<Token> tokens, int i) {
|
||||||
var loc = getLoc(filename, tokens, i);
|
var loc = getLoc(filename, tokens, i);
|
||||||
@ -1900,7 +1888,6 @@ public class Parsing {
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
public static CompileResult compile(Filename filename, String raw) {
|
public static CompileResult compile(Filename filename, String raw) {
|
||||||
try { return compile(parse(filename, raw)); }
|
return compile(parse(filename, raw));
|
||||||
catch (SyntaxException e) { return compile(new ThrowSyntaxStatement(e)); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ArrayStatement extends Statement {
|
public class ArrayStatement extends Statement {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
|
|
||||||
public class CallStatement extends Statement {
|
public class CallStatement extends Statement {
|
||||||
public final Statement func;
|
public final Statement func;
|
||||||
@ -24,8 +24,8 @@ public class CallStatement extends Statement {
|
|||||||
|
|
||||||
for (var arg : args) arg.compile(target, true);
|
for (var arg : args) arg.compile(target, true);
|
||||||
|
|
||||||
if (isNew) target.add(Instruction.callNew(args.length));
|
if (isNew) target.add(Instruction.callNew(args.length)).setLocationAndDebug(loc(), type);
|
||||||
else target.add(Instruction.call(args.length)).setDebug(loc(), type);
|
else target.add(Instruction.call(args.length)).setLocationAndDebug(loc(), type);
|
||||||
|
|
||||||
if (!pollute) target.add(Instruction.discard());
|
if (!pollute) target.add(Instruction.discard());
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class ChangeStatement extends Statement {
|
public class ChangeStatement extends Statement {
|
||||||
public final AssignableStatement value;
|
public final AssignableStatement value;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ConstantStatement extends Statement {
|
public class ConstantStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class DiscardStatement extends Statement {
|
public class DiscardStatement extends Statement {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.Type;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.Type;
|
|
||||||
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
|
||||||
|
|
||||||
public class FunctionStatement extends Statement {
|
public class FunctionStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class GlobalThisStatement extends Statement {
|
public class GlobalThisStatement extends Statement {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class IndexAssignStatement extends Statement {
|
public class IndexAssignStatement extends Statement {
|
||||||
public final Statement object;
|
public final Statement object;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.BreakpointType;
|
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class IndexStatement extends AssignableStatement {
|
public class IndexStatement extends AssignableStatement {
|
||||||
public final Statement object;
|
public final Statement object;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class LazyAndStatement extends Statement {
|
public class LazyAndStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class LazyOrStatement extends Statement {
|
public class LazyOrStatement extends Statement {
|
||||||
|
@ -3,9 +3,9 @@ package me.topchetoeu.jscript.compilation.values;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class ObjectStatement extends Statement {
|
public class ObjectStatement extends Statement {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class OperationStatement extends Statement {
|
public class OperationStatement extends Statement {
|
||||||
public final Statement[] args;
|
public final Statement[] args;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class RegexStatement extends Statement {
|
public class RegexStatement extends Statement {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class TypeofStatement extends Statement {
|
public class TypeofStatement extends Statement {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class VariableAssignStatement extends Statement {
|
public class VariableAssignStatement extends Statement {
|
||||||
public final String name;
|
public final String name;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
|
||||||
public class VariableIndexStatement extends Statement {
|
public class VariableIndexStatement extends Statement {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
import me.topchetoeu.jscript.compilation.CompileResult;
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
|
|
||||||
public class VariableStatement extends AssignableStatement {
|
public class VariableStatement extends AssignableStatement {
|
||||||
public final String name;
|
public final String name;
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.core;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
import me.topchetoeu.jscript.compilation.FunctionBody;
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
|
||||||
public interface Compiler {
|
public interface Compiler {
|
||||||
|
public Key<Compiler> KEY = new Key<>();
|
||||||
|
|
||||||
public FunctionBody compile(Filename filename, String source);
|
public FunctionBody compile(Filename filename, String source);
|
||||||
|
|
||||||
|
public static Compiler get(Extensions ext) {
|
||||||
|
return ext.get(KEY, (filename, src) -> {
|
||||||
|
throw EngineException.ofError("No compiler attached to engine.");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,90 +1,66 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.core;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
import me.topchetoeu.jscript.core.debug.DebugContext;
|
import me.topchetoeu.jscript.core.debug.DebugContext;
|
||||||
|
import me.topchetoeu.jscript.core.values.CodeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
import me.topchetoeu.jscript.lib.EnvironmentLib;
|
import me.topchetoeu.jscript.core.scope.ValueVariable;
|
||||||
|
|
||||||
public class Context implements Extensions {
|
public class Context implements Extensions {
|
||||||
public static final Context NULL = new Context(null);
|
public static final Context NULL = new Context();
|
||||||
|
|
||||||
public final Context parent;
|
public final Context parent;
|
||||||
public final Environment environment;
|
public final Environment environment;
|
||||||
public final Frame frame;
|
public final Frame frame;
|
||||||
public final Engine engine;
|
// public final Engine engine;
|
||||||
public final int stackSize;
|
public final int stackSize;
|
||||||
|
|
||||||
@Override public <T> void add(Symbol key, T obj) {
|
@Override public <T> void add(Key<T> key, T obj) {
|
||||||
if (environment != null) environment.add(key, obj);
|
if (environment != null) environment.add(key, obj);
|
||||||
else if (engine != null) engine.add(key, obj);
|
// else if (engine != null) engine.add(key, obj);
|
||||||
}
|
}
|
||||||
@Override public <T> T get(Symbol key) {
|
@Override public <T> T get(Key<T> key) {
|
||||||
if (environment != null && environment.has(key)) return environment.get(key);
|
if (environment != null && environment.has(key)) return environment.get(key);
|
||||||
else if (engine != null && engine.has(key)) return engine.get(key);
|
// else if (engine != null && engine.has(key)) return engine.get(key);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@Override public boolean has(Symbol key) {
|
@Override public boolean has(Key<?> key) {
|
||||||
return
|
return
|
||||||
environment != null && environment.has(key) ||
|
environment != null && environment.has(key);
|
||||||
engine != null && engine.has(key);
|
// engine != null && engine.has(key);
|
||||||
}
|
}
|
||||||
@Override public boolean remove(Symbol key) {
|
@Override public boolean remove(Key<?> key) {
|
||||||
var res = false;
|
var res = false;
|
||||||
|
|
||||||
if (environment != null) res |= environment.remove(key);
|
if (environment != null) res |= environment.remove(key);
|
||||||
else if (engine != null) res |= engine.remove(key);
|
// else if (engine != null) res |= engine.remove(key);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@Override public Iterable<Symbol> keys() {
|
@Override public Iterable<Key<?>> keys() {
|
||||||
if (engine == null && environment == null) return List.of();
|
return environment.keys();
|
||||||
if (engine == null) return environment.keys();
|
|
||||||
if (environment == null) return engine.keys();
|
|
||||||
|
|
||||||
return () -> Stream.concat(
|
// if (engine == null && environment == null) return List.of();
|
||||||
StreamSupport.stream(engine.keys().spliterator(), false),
|
// if (engine == null) return environment.keys();
|
||||||
StreamSupport.stream(environment.keys().spliterator(), false)
|
// if (environment == null) return engine.keys();
|
||||||
).distinct().iterator();
|
|
||||||
|
// return () -> Stream.concat(
|
||||||
|
// StreamSupport.stream(engine.keys().spliterator(), false),
|
||||||
|
// StreamSupport.stream(environment.keys().spliterator(), false)
|
||||||
|
// ).distinct().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionValue compile(Filename filename, String raw) {
|
public FunctionValue compile(Filename filename, String raw) {
|
||||||
var env = environment;
|
|
||||||
var result = Environment.compileFunc(this).call(this, null, raw, filename.toString(), new EnvironmentLib(env));
|
|
||||||
|
|
||||||
DebugContext.get(this).onSource(filename, raw);
|
DebugContext.get(this).onSource(filename, raw);
|
||||||
return (FunctionValue)result;
|
var result = new CodeFunction(environment, filename.toString(), Compiler.get(this).compile(filename, raw), new ValueVariable[0]);
|
||||||
|
return result;
|
||||||
// var rawMapChain = ((ArrayValue)Values.getMember(this, result, "mapChain")).toArray();
|
|
||||||
// var breakpoints = new TreeSet<>(
|
|
||||||
// Arrays.stream(((ArrayValue)Values.getMember(this, result, "breakpoints")).toArray())
|
|
||||||
// .map(v -> Location.parse(Values.toString(this, v)))
|
|
||||||
// .collect(Collectors.toList())
|
|
||||||
// );
|
|
||||||
// var maps = new SourceMap[rawMapChain.length];
|
|
||||||
|
|
||||||
// for (var i = 0; i < maps.length; i++) maps[i] = SourceMap.parse(Values.toString(this, (String)rawMapChain[i]));
|
|
||||||
|
|
||||||
// var map = SourceMap.chain(maps);
|
|
||||||
|
|
||||||
// if (map != null) {
|
|
||||||
// var newBreakpoints = new TreeSet<Location>();
|
|
||||||
// for (var bp : breakpoints) {
|
|
||||||
// bp = map.toCompiled(bp);
|
|
||||||
// if (bp != null) newBreakpoints.add(bp);
|
|
||||||
// }
|
|
||||||
// breakpoints = newBreakpoints;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context pushFrame(Frame frame) {
|
public Context pushFrame(Frame frame) {
|
||||||
var res = new Context(this, frame.function.environment, frame, engine, stackSize + 1);
|
var res = new Context(this, frame.function.environment, frame, stackSize + 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,11 +87,10 @@ public class Context implements Extensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Context(Context parent, Environment environment, Frame frame, Engine engine, int stackSize) {
|
private Context(Context parent, Environment environment, Frame frame, int stackSize) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.engine = engine;
|
|
||||||
this.stackSize = stackSize;
|
this.stackSize = stackSize;
|
||||||
|
|
||||||
if (hasNotNull(Environment.MAX_STACK_COUNT) && stackSize > (int)get(Environment.MAX_STACK_COUNT)) {
|
if (hasNotNull(Environment.MAX_STACK_COUNT) && stackSize > (int)get(Environment.MAX_STACK_COUNT)) {
|
||||||
@ -123,10 +98,10 @@ public class Context implements Extensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context(Engine engine) {
|
public Context() {
|
||||||
this(null, null, null, engine, 0);
|
this(null, null, null, 0);
|
||||||
}
|
}
|
||||||
public Context(Engine engine, Environment env) {
|
public Context(Environment env) {
|
||||||
this(null, env, null, engine, 0);
|
this(null, env, null, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,54 +1,92 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.core;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
|
import me.topchetoeu.jscript.common.ResultRunnable;
|
||||||
import me.topchetoeu.jscript.common.events.DataNotifier;
|
import me.topchetoeu.jscript.common.events.DataNotifier;
|
||||||
import me.topchetoeu.jscript.compilation.FunctionBody;
|
import me.topchetoeu.jscript.core.exceptions.InterruptException;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
|
||||||
|
|
||||||
public class Engine extends EventLoop implements Extensions {
|
public class Engine implements EventLoop {
|
||||||
public static final HashMap<Integer, FunctionBody> functions = new HashMap<>();
|
private static class Task<T> implements Comparable<Task<?>> {
|
||||||
|
public final ResultRunnable<?> runnable;
|
||||||
|
public final DataNotifier<T> notifier = new DataNotifier<>();
|
||||||
|
public final boolean micro;
|
||||||
|
|
||||||
private final Environment env = new Environment();
|
public Task(ResultRunnable<T> runnable, boolean micro) {
|
||||||
|
this.runnable = runnable;
|
||||||
|
this.micro = micro;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void add(Symbol key, T obj) {
|
public int compareTo(Task<?> other) {
|
||||||
this.env.add(key, obj);
|
return Integer.compare(this.micro ? 0 : 1, other.micro ? 0 : 1);
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public <T> T get(Symbol key) {
|
|
||||||
return this.env.get(key);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean has(Symbol key) {
|
|
||||||
return this.env.has(key);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean remove(Symbol key) {
|
|
||||||
return this.env.remove(key);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public Iterable<Symbol> keys() {
|
|
||||||
return env.keys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Engine copy() {
|
private PriorityBlockingQueue<Task<?>> tasks = new PriorityBlockingQueue<>();
|
||||||
var res = new Engine();
|
private Thread thread;
|
||||||
res.env.addAll(env);
|
|
||||||
return res;
|
@Override
|
||||||
|
public <T> DataNotifier<T> pushMsg(ResultRunnable<T> runnable, boolean micro) {
|
||||||
|
var msg = new Task<T>(runnable, micro);
|
||||||
|
tasks.add(msg);
|
||||||
|
return msg.notifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void run(boolean untilEmpty) {
|
||||||
|
while (!untilEmpty || !tasks.isEmpty()) {
|
||||||
|
try {
|
||||||
|
var task = tasks.take();
|
||||||
|
|
||||||
|
try {
|
||||||
|
((Task<Object>)task).notifier.next(task.runnable.run());
|
||||||
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
if (e instanceof InterruptException) throw e;
|
||||||
|
task.notifier.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InterruptedException | InterruptException e) {
|
||||||
|
for (var msg : tasks) msg.notifier.error(new InterruptException(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Thread thread() {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
public Thread start() {
|
||||||
|
if (thread == null) {
|
||||||
|
thread = new Thread(() -> run(false), "Event loop #" + hashCode());
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
public void stop() {
|
||||||
|
if (thread != null) thread.interrupt();
|
||||||
|
thread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inLoopThread() {
|
||||||
|
return Thread.currentThread() == thread;
|
||||||
|
}
|
||||||
|
public boolean isRunning() {
|
||||||
|
return this.thread != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataNotifier<Object> pushMsg(boolean micro, Environment env, FunctionValue func, Object thisArg, Object ...args) {
|
public DataNotifier<Object> pushMsg(boolean micro, Environment env, FunctionValue func, Object thisArg, Object ...args) {
|
||||||
return pushMsg(() -> {
|
return pushMsg(() -> {
|
||||||
return func.call(new Context(this, env), thisArg, args);
|
return func.call(new Context(env), thisArg, args);
|
||||||
}, micro);
|
}, micro);
|
||||||
}
|
}
|
||||||
public DataNotifier<Object> pushMsg(boolean micro, Environment env, Filename filename, String raw, Object thisArg, Object ...args) {
|
public DataNotifier<Object> pushMsg(boolean micro, Environment env, Filename filename, String raw, Object thisArg, Object ...args) {
|
||||||
return pushMsg(() -> {
|
return pushMsg(() -> {
|
||||||
var ctx = new Context(this, env);
|
var ctx = new Context(env);
|
||||||
return ctx.compile(filename, raw).call(new Context(this, env), thisArg, args);
|
return ctx.compile(filename, raw).call(new Context(env), thisArg, args);
|
||||||
}, micro);
|
}, micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,77 +5,57 @@ import java.util.HashMap;
|
|||||||
import me.topchetoeu.jscript.core.scope.GlobalScope;
|
import me.topchetoeu.jscript.core.scope.GlobalScope;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.NativeFunction;
|
import me.topchetoeu.jscript.core.values.NativeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
import me.topchetoeu.jscript.core.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
import me.topchetoeu.jscript.utils.interop.NativeWrapperProvider;
|
import me.topchetoeu.jscript.utils.interop.NativeWrapperProvider;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class Environment implements Extensions {
|
public class Environment implements Extensions {
|
||||||
|
public static final Key<Compiler> COMPILE_FUNC = new Key<>();
|
||||||
|
|
||||||
public static final HashMap<String, Symbol> symbols = new HashMap<>();
|
public static final Key<FunctionValue> REGEX_CONSTR = new Key<>();
|
||||||
|
public static final Key<Integer> MAX_STACK_COUNT = new Key<>();
|
||||||
|
public static final Key<Boolean> HIDE_STACK = new Key<>();
|
||||||
|
|
||||||
public static final Symbol COMPILE_FUNC = Symbol.get("Environment.compile");
|
public static final Key<ObjectValue> OBJECT_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> FUNCTION_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> ARRAY_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> BOOL_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> NUMBER_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> STRING_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> SYMBOL_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> ERROR_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> SYNTAX_ERR_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> TYPE_ERR_PROTO = new Key<>();
|
||||||
|
public static final Key<ObjectValue> RANGE_ERR_PROTO = new Key<>();
|
||||||
|
|
||||||
public static final Symbol REGEX_CONSTR = Symbol.get("Environment.regexConstructor");
|
private HashMap<Key<?>, Object> data = new HashMap<>();
|
||||||
public static final Symbol STACK = Symbol.get("Environment.stack");
|
|
||||||
public static final Symbol MAX_STACK_COUNT = Symbol.get("Environment.maxStackCount");
|
|
||||||
public static final Symbol HIDE_STACK = Symbol.get("Environment.hideStack");
|
|
||||||
|
|
||||||
public static final Symbol OBJECT_PROTO = Symbol.get("Environment.objectPrototype");
|
|
||||||
public static final Symbol FUNCTION_PROTO = Symbol.get("Environment.functionPrototype");
|
|
||||||
public static final Symbol ARRAY_PROTO = Symbol.get("Environment.arrayPrototype");
|
|
||||||
public static final Symbol BOOL_PROTO = Symbol.get("Environment.boolPrototype");
|
|
||||||
public static final Symbol NUMBER_PROTO = Symbol.get("Environment.numberPrototype");
|
|
||||||
public static final Symbol STRING_PROTO = Symbol.get("Environment.stringPrototype");
|
|
||||||
public static final Symbol SYMBOL_PROTO = Symbol.get("Environment.symbolPrototype");
|
|
||||||
public static final Symbol ERROR_PROTO = Symbol.get("Environment.errorPrototype");
|
|
||||||
public static final Symbol SYNTAX_ERR_PROTO = Symbol.get("Environment.syntaxErrorPrototype");
|
|
||||||
public static final Symbol TYPE_ERR_PROTO = Symbol.get("Environment.typeErrorPrototype");
|
|
||||||
public static final Symbol RANGE_ERR_PROTO = Symbol.get("Environment.rangeErrorPrototype");
|
|
||||||
|
|
||||||
private HashMap<Symbol, Object> data = new HashMap<>();
|
|
||||||
|
|
||||||
public GlobalScope global;
|
public GlobalScope global;
|
||||||
public WrapperProvider wrappers;
|
public WrapperProvider wrappers;
|
||||||
|
|
||||||
@Override public <T> void add(Symbol key, T obj) {
|
@Override public <T> void add(Key<T> key, T obj) {
|
||||||
data.put(key, obj);
|
data.put(key, obj);
|
||||||
}
|
}
|
||||||
@Override public <T> T get(Symbol key) {
|
@Override public <T> T get(Key<T> key) {
|
||||||
return (T)data.get(key);
|
return (T)data.get(key);
|
||||||
}
|
}
|
||||||
@Override public boolean remove(Symbol key) {
|
@Override public boolean remove(Key<?> key) {
|
||||||
if (data.containsKey(key)) {
|
if (data.containsKey(key)) {
|
||||||
data.remove(key);
|
data.remove(key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@Override public boolean has(Symbol key) {
|
@Override public boolean has(Key<?> key) {
|
||||||
return data.containsKey(key);
|
return data.containsKey(key);
|
||||||
}
|
}
|
||||||
@Override public Iterable<Symbol> keys() {
|
@Override public Iterable<Key<?>> keys() {
|
||||||
return data.keySet();
|
return data.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FunctionValue compileFunc(Extensions ext) {
|
|
||||||
return ext.init(COMPILE_FUNC, new NativeFunction("compile", args -> {
|
|
||||||
// var source = args.getString(0);
|
|
||||||
// var filename = args.getString(1);
|
|
||||||
|
|
||||||
// var target = Parsing.compile(Filename.parse(filename), source);
|
|
||||||
// var res = new ObjectValue();
|
|
||||||
|
|
||||||
// res.defineProperty(args.ctx, "function", target.body());
|
|
||||||
// res.defineProperty(args.ctx, "map", target.map());
|
|
||||||
|
|
||||||
// return res;
|
|
||||||
|
|
||||||
throw EngineException.ofError("No compiler attached to engine.");
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
public static FunctionValue regexConstructor(Extensions ext) {
|
public static FunctionValue regexConstructor(Extensions ext) {
|
||||||
return ext.init(COMPILE_FUNC, new NativeFunction("RegExp", args -> {
|
return ext.init(REGEX_CONSTR, new NativeFunction("RegExp", args -> {
|
||||||
throw EngineException.ofError("Regular expressions not supported.").setCtx(args.ctx);
|
throw EngineException.ofError("Regular expressions not supported.").setCtx(args.ctx);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -95,8 +75,8 @@ public class Environment implements Extensions {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context context(Engine engine) {
|
public Context context() {
|
||||||
return new Context(engine, this);
|
return new Context(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Environment(WrapperProvider nativeConverter, GlobalScope global) {
|
public Environment(WrapperProvider nativeConverter, GlobalScope global) {
|
||||||
|
@ -1,80 +1,23 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.core;
|
||||||
|
|
||||||
import java.util.concurrent.PriorityBlockingQueue;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.ResultRunnable;
|
import me.topchetoeu.jscript.common.ResultRunnable;
|
||||||
import me.topchetoeu.jscript.common.events.DataNotifier;
|
import me.topchetoeu.jscript.common.events.DataNotifier;
|
||||||
import me.topchetoeu.jscript.core.exceptions.InterruptException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
|
||||||
public class EventLoop {
|
public interface EventLoop {
|
||||||
private static class Task implements Comparable<Task> {
|
public static final Key<EventLoop> KEY = new Key<>();
|
||||||
public final ResultRunnable<?> runnable;
|
|
||||||
public final DataNotifier<Object> notifier = new DataNotifier<>();
|
|
||||||
public final boolean micro;
|
|
||||||
|
|
||||||
public Task(ResultRunnable<?> runnable, boolean micro) {
|
public static EventLoop get(Extensions ext) {
|
||||||
this.runnable = runnable;
|
if (ext.hasNotNull(KEY)) return ext.get(KEY);
|
||||||
this.micro = micro;
|
else return new EventLoop() {
|
||||||
}
|
@Override public <T> DataNotifier<T> pushMsg(ResultRunnable<T> runnable, boolean micro) {
|
||||||
|
throw EngineException.ofError("No event loop attached to environment.");
|
||||||
@Override
|
}
|
||||||
public int compareTo(Task other) {
|
};
|
||||||
return Integer.compare(this.micro ? 0 : 1, other.micro ? 0 : 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PriorityBlockingQueue<Task> tasks = new PriorityBlockingQueue<>();
|
public <T> DataNotifier<T> pushMsg(ResultRunnable<T> runnable, boolean micro);
|
||||||
private Thread thread;
|
public default DataNotifier<Void> pushMsg(Runnable runnable, boolean micro) {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> DataNotifier<T> pushMsg(ResultRunnable<T> runnable, boolean micro) {
|
|
||||||
var msg = new Task(runnable, micro);
|
|
||||||
tasks.add(msg);
|
|
||||||
return (DataNotifier<T>)msg.notifier;
|
|
||||||
}
|
|
||||||
public DataNotifier<Void> pushMsg(Runnable runnable, boolean micro) {
|
|
||||||
return pushMsg(() -> { runnable.run(); return null; }, micro);
|
return pushMsg(() -> { runnable.run(); return null; }, micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(boolean untilEmpty) {
|
|
||||||
while (!untilEmpty || !tasks.isEmpty()) {
|
|
||||||
try {
|
|
||||||
var task = tasks.take();
|
|
||||||
|
|
||||||
try {
|
|
||||||
task.notifier.next(task.runnable.run());
|
|
||||||
}
|
|
||||||
catch (RuntimeException e) {
|
|
||||||
if (e instanceof InterruptException) throw e;
|
|
||||||
task.notifier.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InterruptedException | InterruptException e) {
|
|
||||||
for (var msg : tasks) msg.notifier.error(new InterruptException(e));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Thread thread() {
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
public Thread start() {
|
|
||||||
if (thread == null) {
|
|
||||||
thread = new Thread(() -> run(false), "Event loop #" + hashCode());
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
public void stop() {
|
|
||||||
if (thread != null) thread.interrupt();
|
|
||||||
thread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean inLoopThread() {
|
|
||||||
return Thread.currentThread() == thread;
|
|
||||||
}
|
|
||||||
public boolean isRunning() {
|
|
||||||
return this.thread != null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,33 @@
|
|||||||
package me.topchetoeu.jscript.core;
|
package me.topchetoeu.jscript.core;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
|
||||||
|
|
||||||
public interface Extensions {
|
public interface Extensions {
|
||||||
<T> T get(Symbol key);
|
<T> T get(Key<T> key);
|
||||||
<T> void add(Symbol key, T obj);
|
<T> void add(Key<T> key, T obj);
|
||||||
Iterable<Symbol> keys();
|
Iterable<Key<?>> keys();
|
||||||
|
|
||||||
boolean has(Symbol key);
|
boolean has(Key<?> key);
|
||||||
boolean remove(Symbol key);
|
boolean remove(Key<?> key);
|
||||||
|
|
||||||
default boolean hasNotNull(Symbol key) {
|
default boolean hasNotNull(Key<?> key) {
|
||||||
return has(key) && get(key) != null;
|
return has(key) && get(key) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default <T> T get(Symbol key, T defaultVal) {
|
default <T> T get(Key<T> key, T defaultVal) {
|
||||||
if (has(key)) return get(key);
|
if (has(key)) return get(key);
|
||||||
else return defaultVal;
|
else return defaultVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
default <T> T init(Symbol key, T val) {
|
default <T> T init(Key<T> key, T val) {
|
||||||
if (has(key)) return get(key);
|
if (has(key)) return get(key);
|
||||||
else {
|
else {
|
||||||
add(key, val);
|
add(key, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
default void addAll(Extensions source) {
|
default void addAll(Extensions source) {
|
||||||
for (var key : source.keys()) {
|
for (var key : source.keys()) {
|
||||||
add(key, source.get(key));
|
add((Key<Object>)key, (Object)source.get(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package me.topchetoeu.jscript.core;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.core.debug.DebugContext;
|
import me.topchetoeu.jscript.core.debug.DebugContext;
|
||||||
import me.topchetoeu.jscript.core.scope.LocalScope;
|
import me.topchetoeu.jscript.core.scope.LocalScope;
|
||||||
import me.topchetoeu.jscript.core.scope.ValueVariable;
|
import me.topchetoeu.jscript.core.scope.ValueVariable;
|
||||||
@ -159,7 +159,7 @@ public class Frame {
|
|||||||
returnValue = InstructionRunner.exec(ctx, instr, this);
|
returnValue = InstructionRunner.exec(ctx, instr, this);
|
||||||
}
|
}
|
||||||
catch (EngineException e) {
|
catch (EngineException e) {
|
||||||
error = e.add(ctx, function.name, DebugContext.get(ctx).getMap(function).toLocation(codePtr, true));
|
error = e.add(ctx, function.name, DebugContext.get(ctx).getMapOrEmpty(function).toLocation(codePtr, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package me.topchetoeu.jscript.core;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.core.scope.ValueVariable;
|
import me.topchetoeu.jscript.core.scope.ValueVariable;
|
||||||
import me.topchetoeu.jscript.core.values.ArrayValue;
|
import me.topchetoeu.jscript.core.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.core.values.CodeFunction;
|
import me.topchetoeu.jscript.core.values.CodeFunction;
|
||||||
@ -10,6 +9,8 @@ import me.topchetoeu.jscript.core.values.FunctionValue;
|
|||||||
import me.topchetoeu.jscript.core.values.ObjectValue;
|
import me.topchetoeu.jscript.core.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
import me.topchetoeu.jscript.core.values.Symbol;
|
||||||
import me.topchetoeu.jscript.core.values.Values;
|
import me.topchetoeu.jscript.core.values.Values;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
|
||||||
public class InstructionRunner {
|
public class InstructionRunner {
|
||||||
|
@ -6,31 +6,31 @@ import java.util.List;
|
|||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.compilation.FunctionBody;
|
import me.topchetoeu.jscript.common.mapping.FunctionMap;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
|
||||||
import me.topchetoeu.jscript.compilation.mapping.FunctionMap;
|
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Extensions;
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
import me.topchetoeu.jscript.core.Frame;
|
import me.topchetoeu.jscript.core.Frame;
|
||||||
|
import me.topchetoeu.jscript.core.Key;
|
||||||
import me.topchetoeu.jscript.core.values.CodeFunction;
|
import me.topchetoeu.jscript.core.values.CodeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
|
||||||
public class DebugContext implements DebugController {
|
public class DebugContext {
|
||||||
public static final Symbol ENV_KEY = Symbol.get("Engine.debug");
|
public static final Key<DebugContext> KEY = new Key<>();
|
||||||
public static final Symbol IGNORE = Symbol.get("Engine.ignoreDebug");
|
public static final Key<Void> IGNORE = new Key<>();
|
||||||
|
|
||||||
private HashMap<Filename, String> sources;
|
private HashMap<Filename, String> sources;
|
||||||
private WeakHashMap<FunctionBody, FunctionMap> maps;
|
private WeakHashMap<FunctionBody, FunctionMap> maps;
|
||||||
private DebugController debugger;
|
private DebugHandler debugger;
|
||||||
|
|
||||||
public boolean attachDebugger(DebugController debugger) {
|
public boolean attachDebugger(DebugHandler debugger) {
|
||||||
if (this.debugger != null) return false;
|
if (this.debugger != null) return false;
|
||||||
|
|
||||||
if (sources != null) {
|
if (sources != null) {
|
||||||
for (var source : sources.entrySet()) debugger.onSource(source.getKey(), source.getValue());
|
for (var source : sources.entrySet()) debugger.onSourceLoad(source.getKey(), source.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.debugger = debugger;
|
this.debugger = debugger;
|
||||||
@ -41,8 +41,8 @@ public class DebugContext implements DebugController {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DebugController debugger() {
|
public DebugHandler debugger() {
|
||||||
if (debugger == null) return DebugController.empty();
|
if (debugger == null) return DebugHandler.empty();
|
||||||
else return debugger;
|
else return debugger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,24 +61,27 @@ public class DebugContext implements DebugController {
|
|||||||
else return res;
|
else return res;
|
||||||
}
|
}
|
||||||
public FunctionMap getMapOrEmpty(FunctionValue func) {
|
public FunctionMap getMapOrEmpty(FunctionValue func) {
|
||||||
if (maps == null || !(func instanceof CodeFunction)) return null;
|
if (maps == null || !(func instanceof CodeFunction)) return FunctionMap.EMPTY;
|
||||||
return getMapOrEmpty(((CodeFunction)func).body);
|
return getMapOrEmpty(((CodeFunction)func).body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onFramePop(Context ctx, Frame frame) {
|
public void onFramePop(Context ctx, Frame frame) {
|
||||||
if (debugger != null) debugger.onFramePop(ctx, frame);
|
if (debugger != null) debugger.onFramePop(ctx, frame);
|
||||||
}
|
}
|
||||||
@Override public void onFramePush(Context ctx, Frame frame) {
|
public void onFramePush(Context ctx, Frame frame) {
|
||||||
if (debugger != null) debugger.onFramePush(ctx, frame);
|
if (debugger != null) debugger.onFramePush(ctx, frame);
|
||||||
}
|
}
|
||||||
@Override public boolean onInstruction(Context ctx, Frame frame, Instruction instruction, Object returnVal, EngineException error, boolean caught) {
|
public boolean onInstruction(Context ctx, Frame frame, Instruction instruction, Object returnVal, EngineException error, boolean caught) {
|
||||||
if (debugger != null) return debugger.onInstruction(ctx, frame, instruction, returnVal, error, caught);
|
if (debugger != null) return debugger.onInstruction(ctx, frame, instruction, returnVal, error, caught);
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
@Override public void onSource(Filename filename, String source) {
|
public void onSource(Filename filename, String source) {
|
||||||
if (debugger != null) debugger.onSource(filename, source);
|
if (debugger != null) debugger.onSourceLoad(filename, source);
|
||||||
if (sources != null) sources.put(filename, source);
|
if (sources != null) sources.put(filename, source);
|
||||||
}
|
}
|
||||||
|
public void onFunctionLoad(FunctionBody func, FunctionMap map) {
|
||||||
|
if (maps != null) maps.put(func, map);
|
||||||
|
}
|
||||||
|
|
||||||
private DebugContext(boolean enabled) {
|
private DebugContext(boolean enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
@ -92,10 +95,10 @@ public class DebugContext implements DebugController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean enabled(Extensions exts) {
|
public static boolean enabled(Extensions exts) {
|
||||||
return exts.hasNotNull(ENV_KEY) && !exts.has(IGNORE);
|
return exts != null && exts.hasNotNull(KEY) && !exts.has(IGNORE);
|
||||||
}
|
}
|
||||||
public static DebugContext get(Extensions exts) {
|
public static DebugContext get(Extensions exts) {
|
||||||
if (enabled(exts)) return exts.get(ENV_KEY);
|
if (enabled(exts)) return exts.get(KEY);
|
||||||
else return new DebugContext(false);
|
else return new DebugContext(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ public class DebugContext implements DebugController {
|
|||||||
for (var el : ctx.frames()) {
|
for (var el : ctx.frames()) {
|
||||||
var name = el.function.name;
|
var name = el.function.name;
|
||||||
|
|
||||||
var map = dbgCtx.getMap(el.function);
|
var map = dbgCtx.getMapOrEmpty(el.function);
|
||||||
Location loc = null;
|
Location loc = null;
|
||||||
|
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package me.topchetoeu.jscript.core.debug;
|
package me.topchetoeu.jscript.core.debug;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
|
import me.topchetoeu.jscript.common.Instruction;
|
||||||
|
import me.topchetoeu.jscript.common.mapping.FunctionMap;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Frame;
|
import me.topchetoeu.jscript.core.Frame;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
|
||||||
public interface DebugController {
|
public interface DebugHandler {
|
||||||
/**
|
/**
|
||||||
* Called when a script has been loaded
|
* Called when a script has been loaded
|
||||||
* @param filename The name of the source
|
* @param filename The name of the source
|
||||||
@ -14,7 +16,21 @@ public interface DebugController {
|
|||||||
* @param breakpoints A set of all the breakpointable locations in this source
|
* @param breakpoints A set of all the breakpointable locations in this source
|
||||||
* @param map The source map associated with this file. null if this source map isn't mapped
|
* @param map The source map associated with this file. null if this source map isn't mapped
|
||||||
*/
|
*/
|
||||||
void onSource(Filename filename, String source);
|
void onSourceLoad(Filename filename, String source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a function body has been loaded
|
||||||
|
* @param body The body loaded
|
||||||
|
* @param map The map of the function
|
||||||
|
*/
|
||||||
|
void onFunctionLoad(FunctionBody body, FunctionMap map);
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Called when a function body has been loaded
|
||||||
|
// * @param body The body loaded
|
||||||
|
// * @param map The map of the function
|
||||||
|
// */
|
||||||
|
// void onFunctionUnload(FunctionBody body, FunctionMap map);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called immediatly before an instruction is executed, as well as after an instruction, if it has threw or returned.
|
* Called immediatly before an instruction is executed, as well as after an instruction, if it has threw or returned.
|
||||||
@ -44,14 +60,15 @@ public interface DebugController {
|
|||||||
*/
|
*/
|
||||||
void onFramePop(Context ctx, Frame frame);
|
void onFramePop(Context ctx, Frame frame);
|
||||||
|
|
||||||
public static DebugController empty() {
|
public static DebugHandler empty() {
|
||||||
return new DebugController () {
|
return new DebugHandler () {
|
||||||
@Override public void onFramePop(Context ctx, Frame frame) { }
|
@Override public void onFramePop(Context ctx, Frame frame) { }
|
||||||
@Override public void onFramePush(Context ctx, Frame frame) { }
|
@Override public void onFramePush(Context ctx, Frame frame) { }
|
||||||
@Override public boolean onInstruction(Context ctx, Frame frame, Instruction instruction, Object returnVal, EngineException error, boolean caught) {
|
@Override public boolean onInstruction(Context ctx, Frame frame, Instruction instruction, Object returnVal, EngineException error, boolean caught) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@Override public void onSource(Filename filename, String source) { }
|
@Override public void onSourceLoad(Filename filename, String source) { }
|
||||||
|
@Override public void onFunctionLoad(FunctionBody body, FunctionMap map) { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Engine;
|
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
import me.topchetoeu.jscript.core.Environment;
|
||||||
import me.topchetoeu.jscript.core.values.ObjectValue;
|
import me.topchetoeu.jscript.core.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.core.values.Values;
|
import me.topchetoeu.jscript.core.values.Values;
|
||||||
@ -35,7 +34,7 @@ public class EngineException extends RuntimeException {
|
|||||||
if (name.equals("")) name = null;
|
if (name.equals("")) name = null;
|
||||||
|
|
||||||
if (ctx == null) this.ctx = null;
|
if (ctx == null) this.ctx = null;
|
||||||
else this.ctx = new Context(ctx.engine, ctx.environment);
|
else this.ctx = new Context(ctx.environment);
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
@ -44,7 +43,6 @@ public class EngineException extends RuntimeException {
|
|||||||
public final Object value;
|
public final Object value;
|
||||||
public EngineException cause;
|
public EngineException cause;
|
||||||
public Environment env = null;
|
public Environment env = null;
|
||||||
public Engine engine = null;
|
|
||||||
public final List<StackElement> stackTrace = new ArrayList<>();
|
public final List<StackElement> stackTrace = new ArrayList<>();
|
||||||
|
|
||||||
public EngineException add(Context ctx, String name, Location location) {
|
public EngineException add(Context ctx, String name, Location location) {
|
||||||
@ -60,7 +58,6 @@ public class EngineException extends RuntimeException {
|
|||||||
}
|
}
|
||||||
public EngineException setCtx(Context ctx) {
|
public EngineException setCtx(Context ctx) {
|
||||||
if (this.env == null) this.env = ctx.environment;
|
if (this.env == null) this.env = ctx.environment;
|
||||||
if (this.engine == null) this.engine = ctx.engine;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package me.topchetoeu.jscript.core.values;
|
package me.topchetoeu.jscript.core.values;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.compilation.FunctionBody;
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
import me.topchetoeu.jscript.core.Environment;
|
||||||
import me.topchetoeu.jscript.core.Frame;
|
import me.topchetoeu.jscript.core.Frame;
|
||||||
|
@ -12,9 +12,9 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Operation;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
import me.topchetoeu.jscript.core.Environment;
|
||||||
import me.topchetoeu.jscript.core.Operation;
|
|
||||||
import me.topchetoeu.jscript.core.debug.DebugContext;
|
import me.topchetoeu.jscript.core.debug.DebugContext;
|
||||||
import me.topchetoeu.jscript.core.exceptions.ConvertException;
|
import me.topchetoeu.jscript.core.exceptions.ConvertException;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
@ -664,7 +664,7 @@ public class Values {
|
|||||||
|
|
||||||
if (val instanceof FunctionValue) {
|
if (val instanceof FunctionValue) {
|
||||||
res.append(val.toString());
|
res.append(val.toString());
|
||||||
var loc = val instanceof CodeFunction ? dbg.getMap((CodeFunction)val).start() : null;
|
var loc = val instanceof CodeFunction ? dbg.getMapOrEmpty((CodeFunction)val).start() : null;
|
||||||
|
|
||||||
if (loc != null) res.append(" @ " + loc);
|
if (loc != null) res.append(" @ " + loc);
|
||||||
}
|
}
|
||||||
@ -734,10 +734,10 @@ public class Values {
|
|||||||
if (err instanceof EngineException) {
|
if (err instanceof EngineException) {
|
||||||
var ee = ((EngineException)err);
|
var ee = ((EngineException)err);
|
||||||
try {
|
try {
|
||||||
return prefix + " " + ee.toString(new Context(ee.engine, ee.env));
|
return prefix + " " + ee.toString(new Context(ee.env));
|
||||||
}
|
}
|
||||||
catch (EngineException ex) {
|
catch (EngineException ex) {
|
||||||
return prefix + " " + toReadable(new Context(ee.engine, ee.env), ee.value);
|
return prefix + " " + toReadable(new Context(ee.env), ee.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (err instanceof SyntaxException) {
|
else if (err instanceof SyntaxException) {
|
||||||
|
@ -13,7 +13,7 @@ import me.topchetoeu.jscript.utils.interop.WrapperName;
|
|||||||
|
|
||||||
@WrapperName("AsyncFunction")
|
@WrapperName("AsyncFunction")
|
||||||
public class AsyncFunctionLib extends FunctionValue {
|
public class AsyncFunctionLib extends FunctionValue {
|
||||||
public final FunctionValue factory;
|
public final CodeFunction func;
|
||||||
|
|
||||||
private static class AsyncHelper {
|
private static class AsyncHelper {
|
||||||
public PromiseLib promise = new PromiseLib();
|
public PromiseLib promise = new PromiseLib();
|
||||||
@ -67,15 +67,19 @@ public class AsyncFunctionLib extends FunctionValue {
|
|||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new AsyncHelper();
|
var handler = new AsyncHelper();
|
||||||
var func = factory.call(ctx, thisArg, new NativeFunction("await", handler::await));
|
|
||||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
var newArgs = new Object[args.length + 1];
|
||||||
handler.frame = new Frame(ctx, thisArg, args, (CodeFunction)func);
|
newArgs[0] = new NativeFunction("await", handler::await);
|
||||||
|
System.arraycopy(args, 0, newArgs, 1, args.length);
|
||||||
|
|
||||||
|
handler.frame = new Frame(ctx, thisArg, newArgs, (CodeFunction)func);
|
||||||
handler.next(ctx, Values.NO_RETURN, null);
|
handler.next(ctx, Values.NO_RETURN, null);
|
||||||
return handler.promise;
|
return handler.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncFunctionLib(FunctionValue factory) {
|
public AsyncFunctionLib(FunctionValue func) {
|
||||||
super(factory.name, factory.length);
|
super(func.name, func.length);
|
||||||
this.factory = factory;
|
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||||
|
this.func = (CodeFunction)func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,24 @@ import me.topchetoeu.jscript.utils.interop.WrapperName;
|
|||||||
|
|
||||||
@WrapperName("AsyncGeneratorFunction")
|
@WrapperName("AsyncGeneratorFunction")
|
||||||
public class AsyncGeneratorFunctionLib extends FunctionValue {
|
public class AsyncGeneratorFunctionLib extends FunctionValue {
|
||||||
public final FunctionValue factory;
|
public final CodeFunction func;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object call(Context ctx, Object thisArg, Object ...args) {
|
public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new AsyncGeneratorLib();
|
var handler = new AsyncGeneratorLib();
|
||||||
var func = factory.call(ctx, thisArg,
|
|
||||||
new NativeFunction("await", handler::await),
|
var newArgs = new Object[args.length + 2];
|
||||||
new NativeFunction("yield", handler::yield)
|
newArgs[0] = new NativeFunction("await", handler::await);
|
||||||
);
|
newArgs[1] = new NativeFunction("yield", handler::yield);
|
||||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
System.arraycopy(args, 0, newArgs, 2, args.length);
|
||||||
handler.frame = new Frame(ctx, thisArg, args, (CodeFunction)func);
|
|
||||||
|
handler.frame = new Frame(ctx, thisArg, newArgs, func);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncGeneratorFunctionLib(FunctionValue factory) {
|
public AsyncGeneratorFunctionLib(CodeFunction func) {
|
||||||
super(factory.name, factory.length);
|
super(func.name, func.length);
|
||||||
this.factory = factory;
|
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||||
|
this.func = func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
package me.topchetoeu.jscript.lib;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
|
||||||
import me.topchetoeu.jscript.core.values.ObjectValue;
|
|
||||||
import me.topchetoeu.jscript.utils.interop.Arguments;
|
|
||||||
import me.topchetoeu.jscript.utils.interop.Expose;
|
|
||||||
import me.topchetoeu.jscript.utils.interop.ExposeType;
|
|
||||||
import me.topchetoeu.jscript.utils.interop.WrapperName;
|
|
||||||
|
|
||||||
@WrapperName("Environment")
|
|
||||||
public class EnvironmentLib {
|
|
||||||
private Environment env;
|
|
||||||
|
|
||||||
@Expose(value = "@@env", type = ExposeType.GETTER)
|
|
||||||
public Environment __env() { return env; }
|
|
||||||
|
|
||||||
@Expose(type = ExposeType.GETTER)
|
|
||||||
public int __id(Arguments args) {
|
|
||||||
return env.hashCode();
|
|
||||||
}
|
|
||||||
@Expose(type = ExposeType.GETTER)
|
|
||||||
public ObjectValue __global(Arguments args) {
|
|
||||||
return env.global.obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Expose(type = ExposeType.GETTER)
|
|
||||||
public FunctionValue __compile() {
|
|
||||||
return Environment.compileFunc(env);
|
|
||||||
}
|
|
||||||
@Expose(type = ExposeType.SETTER)
|
|
||||||
public void __compile(Arguments args) {
|
|
||||||
env.add(Environment.COMPILE_FUNC, args.convert(0, FunctionValue.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnvironmentLib(Environment env) {
|
|
||||||
this.env = env;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.lib;
|
package me.topchetoeu.jscript.lib;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.values.ArrayValue;
|
import me.topchetoeu.jscript.core.values.ArrayValue;
|
||||||
|
import me.topchetoeu.jscript.core.values.CodeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.NativeFunction;
|
import me.topchetoeu.jscript.core.values.NativeFunction;
|
||||||
import me.topchetoeu.jscript.utils.interop.Arguments;
|
import me.topchetoeu.jscript.utils.interop.Arguments;
|
||||||
@ -44,10 +45,10 @@ public class FunctionLib {
|
|||||||
}
|
}
|
||||||
@Expose(target = ExposeTarget.STATIC)
|
@Expose(target = ExposeTarget.STATIC)
|
||||||
public static FunctionValue __asyncGenerator(Arguments args) {
|
public static FunctionValue __asyncGenerator(Arguments args) {
|
||||||
return new AsyncGeneratorFunctionLib(args.convert(0, FunctionValue.class));
|
return new AsyncGeneratorFunctionLib(args.convert(0, CodeFunction.class));
|
||||||
}
|
}
|
||||||
@Expose(target = ExposeTarget.STATIC)
|
@Expose(target = ExposeTarget.STATIC)
|
||||||
public static FunctionValue __generator(Arguments args) {
|
public static FunctionValue __generator(Arguments args) {
|
||||||
return new GeneratorFunctionLib(args.convert(0, FunctionValue.class));
|
return new GeneratorFunctionLib(args.convert(0, CodeFunction.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,18 +10,22 @@ import me.topchetoeu.jscript.utils.interop.WrapperName;
|
|||||||
|
|
||||||
@WrapperName("GeneratorFunction")
|
@WrapperName("GeneratorFunction")
|
||||||
public class GeneratorFunctionLib extends FunctionValue {
|
public class GeneratorFunctionLib extends FunctionValue {
|
||||||
public final FunctionValue factory;
|
public final CodeFunction func;
|
||||||
|
|
||||||
@Override public Object call(Context ctx, Object thisArg, Object ...args) {
|
@Override public Object call(Context ctx, Object thisArg, Object ...args) {
|
||||||
var handler = new GeneratorLib();
|
var handler = new GeneratorLib();
|
||||||
var func = factory.call(ctx, thisArg, new NativeFunction("yield", handler::yield));
|
|
||||||
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
var newArgs = new Object[args.length + 1];
|
||||||
handler.frame = new Frame(ctx, thisArg, args, (CodeFunction)func);
|
newArgs[0] = new NativeFunction("yield", handler::yield);
|
||||||
|
System.arraycopy(args, 0, newArgs, 1, args.length);
|
||||||
|
|
||||||
|
handler.frame = new Frame(ctx, thisArg, newArgs, func);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneratorFunctionLib(FunctionValue factory) {
|
public GeneratorFunctionLib(CodeFunction func) {
|
||||||
super(factory.name, factory.length);
|
super(func.name, func.length);
|
||||||
this.factory = factory;
|
if (!(func instanceof CodeFunction)) throw EngineException.ofType("Return value of argument must be a js function.");
|
||||||
|
this.func = func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
import me.topchetoeu.jscript.core.Environment;
|
||||||
|
import me.topchetoeu.jscript.core.EventLoop;
|
||||||
|
import me.topchetoeu.jscript.core.Key;
|
||||||
import me.topchetoeu.jscript.core.scope.GlobalScope;
|
import me.topchetoeu.jscript.core.scope.GlobalScope;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
|
||||||
import me.topchetoeu.jscript.core.values.Values;
|
import me.topchetoeu.jscript.core.values.Values;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
import me.topchetoeu.jscript.utils.interop.Arguments;
|
import me.topchetoeu.jscript.utils.interop.Arguments;
|
||||||
@ -16,8 +17,8 @@ import me.topchetoeu.jscript.utils.interop.ExposeTarget;
|
|||||||
import me.topchetoeu.jscript.utils.modules.ModuleRepo;
|
import me.topchetoeu.jscript.utils.modules.ModuleRepo;
|
||||||
|
|
||||||
public class Internals {
|
public class Internals {
|
||||||
private static final Symbol THREADS = new Symbol("Internals.threads");
|
private static final Key<HashMap<Integer, Thread>> THREADS = new Key<>();
|
||||||
private static final Symbol I = new Symbol("Internals.i");
|
private static final Key<Integer> I = new Key<>();
|
||||||
|
|
||||||
@Expose(target = ExposeTarget.STATIC)
|
@Expose(target = ExposeTarget.STATIC)
|
||||||
public static Object __require(Arguments args) {
|
public static Object __require(Arguments args) {
|
||||||
@ -38,6 +39,8 @@ public class Internals {
|
|||||||
var delay = args.getDouble(1);
|
var delay = args.getDouble(1);
|
||||||
var arguments = args.slice(2).args;
|
var arguments = args.slice(2).args;
|
||||||
|
|
||||||
|
if (!args.ctx.hasNotNull(EventLoop.KEY)) throw EngineException.ofError("No event loop");
|
||||||
|
|
||||||
var thread = new Thread(() -> {
|
var thread = new Thread(() -> {
|
||||||
var ms = (long)delay;
|
var ms = (long)delay;
|
||||||
var ns = (int)((delay - ms) * 10000000);
|
var ns = (int)((delay - ms) * 10000000);
|
||||||
@ -45,7 +48,7 @@ public class Internals {
|
|||||||
try { Thread.sleep(ms, ns); }
|
try { Thread.sleep(ms, ns); }
|
||||||
catch (InterruptedException e) { return; }
|
catch (InterruptedException e) { return; }
|
||||||
|
|
||||||
args.ctx.engine.pushMsg(false, args.ctx.environment, func, null, arguments);
|
args.ctx.get(EventLoop.KEY).pushMsg(() -> func.call(new Context(args.ctx.environment), null, arguments), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
@ -61,6 +64,8 @@ public class Internals {
|
|||||||
var delay = args.getDouble(1);
|
var delay = args.getDouble(1);
|
||||||
var arguments = args.slice(2).args;
|
var arguments = args.slice(2).args;
|
||||||
|
|
||||||
|
if (!args.ctx.hasNotNull(EventLoop.KEY)) throw EngineException.ofError("No event loop");
|
||||||
|
|
||||||
var thread = new Thread(() -> {
|
var thread = new Thread(() -> {
|
||||||
var ms = (long)delay;
|
var ms = (long)delay;
|
||||||
var ns = (int)((delay - ms) * 10000000);
|
var ns = (int)((delay - ms) * 10000000);
|
||||||
@ -71,7 +76,7 @@ public class Internals {
|
|||||||
}
|
}
|
||||||
catch (InterruptedException e) { return; }
|
catch (InterruptedException e) { return; }
|
||||||
|
|
||||||
args.ctx.engine.pushMsg(false, args.ctx.environment, func, null, arguments);
|
args.ctx.get(EventLoop.KEY).pushMsg(() -> func.call(new Context(args.ctx.environment), null, arguments), false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
thread.start();
|
thread.start();
|
||||||
|
@ -6,12 +6,14 @@ import java.util.List;
|
|||||||
import me.topchetoeu.jscript.common.ResultRunnable;
|
import me.topchetoeu.jscript.common.ResultRunnable;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.EventLoop;
|
import me.topchetoeu.jscript.core.EventLoop;
|
||||||
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
import me.topchetoeu.jscript.core.values.ArrayValue;
|
import me.topchetoeu.jscript.core.values.ArrayValue;
|
||||||
import me.topchetoeu.jscript.core.values.FunctionValue;
|
import me.topchetoeu.jscript.core.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.core.values.NativeFunction;
|
import me.topchetoeu.jscript.core.values.NativeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.ObjectValue;
|
import me.topchetoeu.jscript.core.values.ObjectValue;
|
||||||
import me.topchetoeu.jscript.core.values.Values;
|
import me.topchetoeu.jscript.core.values.Values;
|
||||||
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
import me.topchetoeu.jscript.core.exceptions.EngineException;
|
||||||
|
import me.topchetoeu.jscript.core.exceptions.InterruptException;
|
||||||
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.ExposeConstructor;
|
||||||
@ -24,14 +26,17 @@ public class PromiseLib {
|
|||||||
void onFulfil(Object val);
|
void onFulfil(Object val);
|
||||||
void onReject(EngineException err);
|
void onReject(EngineException err);
|
||||||
|
|
||||||
default Handle defer(EventLoop loop) {
|
default Handle defer(Extensions loop) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return new Handle() {
|
return new Handle() {
|
||||||
@Override public void onFulfil(Object val) {
|
@Override public void onFulfil(Object val) {
|
||||||
loop.pushMsg(() -> self.onFulfil(val), true);
|
if (!loop.hasNotNull(EventLoop.KEY)) throw EngineException.ofError("No event loop");
|
||||||
|
loop.get(EventLoop.KEY).pushMsg(() -> self.onFulfil(val), true);
|
||||||
}
|
}
|
||||||
@Override public void onReject(EngineException val) {
|
@Override public void onReject(EngineException val) {
|
||||||
loop.pushMsg(() -> self.onReject(val), true);
|
if (!loop.hasNotNull(EventLoop.KEY)) throw EngineException.ofError("No event loop");
|
||||||
|
loop.get(EventLoop.KEY).pushMsg(() -> self.onReject(val), true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -48,7 +53,9 @@ public class PromiseLib {
|
|||||||
private Object val;
|
private Object val;
|
||||||
|
|
||||||
private void resolveSynchronized(Context ctx, Object val, int newState) {
|
private void resolveSynchronized(Context ctx, Object val, int newState) {
|
||||||
ctx.engine.pushMsg(() -> {
|
if (!ctx.hasNotNull(EventLoop.KEY)) throw EngineException.ofError("No event loop");
|
||||||
|
|
||||||
|
ctx.get(EventLoop.KEY).pushMsg(() -> {
|
||||||
this.val = val;
|
this.val = val;
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
|
|
||||||
@ -118,6 +125,12 @@ public class PromiseLib {
|
|||||||
catch (EngineException e) {
|
catch (EngineException e) {
|
||||||
res.reject(ctx, e);
|
res.reject(ctx, e);
|
||||||
}
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if (e instanceof InterruptException) throw e;
|
||||||
|
else {
|
||||||
|
res.reject(ctx, EngineException.ofError("Native code failed with " + e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}, "Promisifier").start();
|
}, "Promisifier").start();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -144,7 +157,8 @@ public class PromiseLib {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
var then = Values.getMember(ctx, obj, "then");
|
var then = Values.getMember(ctx, obj, "then");
|
||||||
Values.call(ctx, then, obj,
|
|
||||||
|
if (then instanceof FunctionValue) Values.call(ctx, then, obj,
|
||||||
new NativeFunction(args -> {
|
new NativeFunction(args -> {
|
||||||
try { handle.onFulfil(args.get(0)); }
|
try { handle.onFulfil(args.get(0)); }
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
@ -162,6 +176,7 @@ public class PromiseLib {
|
|||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
else handle.onFulfil(obj);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -325,7 +340,7 @@ public class PromiseLib {
|
|||||||
try { res.fulfill(args.ctx, onReject.call(args.ctx, null, err.value)); }
|
try { res.fulfill(args.ctx, onReject.call(args.ctx, null, err.value)); }
|
||||||
catch (EngineException e) { res.reject(args.ctx, e); }
|
catch (EngineException e) { res.reject(args.ctx, e); }
|
||||||
}
|
}
|
||||||
}.defer(args.ctx.engine));
|
}.defer(args.ctx));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -354,7 +369,7 @@ public class PromiseLib {
|
|||||||
}
|
}
|
||||||
catch (EngineException e) { res.reject(args.ctx, e); }
|
catch (EngineException e) { res.reject(args.ctx, e); }
|
||||||
}
|
}
|
||||||
}.defer(args.ctx.engine));
|
}.defer(args.ctx));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
34
src/java/me/topchetoeu/jscript/utils/JSCompiler.java
Normal file
34
src/java/me/topchetoeu/jscript/utils/JSCompiler.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package me.topchetoeu.jscript.utils;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
|
import me.topchetoeu.jscript.common.FunctionBody;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileResult;
|
||||||
|
import me.topchetoeu.jscript.compilation.parsing.Parsing;
|
||||||
|
import me.topchetoeu.jscript.core.Compiler;
|
||||||
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
|
import me.topchetoeu.jscript.core.debug.DebugContext;
|
||||||
|
|
||||||
|
public class JSCompiler implements Compiler {
|
||||||
|
public final Extensions ext;
|
||||||
|
|
||||||
|
private void registerFunc(FunctionBody body, CompileResult res) {
|
||||||
|
var map = res.map();
|
||||||
|
DebugContext.get(ext).onFunctionLoad(body, map);
|
||||||
|
|
||||||
|
for (var i = 0; i < body.children.length; i++) {
|
||||||
|
registerFunc(body.children[i], res.children.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public FunctionBody compile(Filename filename, String source) {
|
||||||
|
var res = Parsing.compile(filename, source);
|
||||||
|
var func = res.body();
|
||||||
|
registerFunc(func, res);
|
||||||
|
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSCompiler(Extensions ext) {
|
||||||
|
this.ext = ext;
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,11 @@ import java.nio.file.Path;
|
|||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
import me.topchetoeu.jscript.common.Metadata;
|
import me.topchetoeu.jscript.common.Metadata;
|
||||||
import me.topchetoeu.jscript.common.Reading;
|
import me.topchetoeu.jscript.common.Reading;
|
||||||
|
import me.topchetoeu.jscript.core.Compiler;
|
||||||
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Engine;
|
import me.topchetoeu.jscript.core.Engine;
|
||||||
import me.topchetoeu.jscript.core.Environment;
|
import me.topchetoeu.jscript.core.Environment;
|
||||||
|
import me.topchetoeu.jscript.core.EventLoop;
|
||||||
import me.topchetoeu.jscript.core.debug.DebugContext;
|
import me.topchetoeu.jscript.core.debug.DebugContext;
|
||||||
import me.topchetoeu.jscript.core.values.NativeFunction;
|
import me.topchetoeu.jscript.core.values.NativeFunction;
|
||||||
import me.topchetoeu.jscript.core.values.Values;
|
import me.topchetoeu.jscript.core.values.Values;
|
||||||
@ -36,7 +39,6 @@ public class JScriptRepl {
|
|||||||
static Environment environment = new Environment();
|
static Environment environment = new Environment();
|
||||||
|
|
||||||
static int j = 0;
|
static int j = 0;
|
||||||
static boolean exited = false;
|
|
||||||
static String[] args;
|
static String[] args;
|
||||||
|
|
||||||
private static void reader() {
|
private static void reader() {
|
||||||
@ -74,25 +76,21 @@ public class JScriptRepl {
|
|||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
System.out.println(e.toString());
|
System.out.println(e.toString());
|
||||||
exited = true;
|
engine.thread().interrupt();
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
if (!exited) {
|
if (ex instanceof InterruptException) return;
|
||||||
|
else {
|
||||||
System.out.println("Internal error ocurred:");
|
System.out.println("Internal error ocurred:");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exited) {
|
|
||||||
debugTask.interrupt();
|
|
||||||
engineTask.interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initEnv() {
|
private static void initEnv() {
|
||||||
environment = Internals.apply(environment);
|
environment = Internals.apply(environment);
|
||||||
|
|
||||||
environment.global.define(false, new NativeFunction("exit", args -> {
|
environment.global.define(false, new NativeFunction("exit", args -> {
|
||||||
exited = true;
|
|
||||||
throw new InterruptException();
|
throw new InterruptException();
|
||||||
}));
|
}));
|
||||||
environment.global.define(false, new NativeFunction("go", args -> {
|
environment.global.define(false, new NativeFunction("go", args -> {
|
||||||
@ -105,26 +103,35 @@ public class JScriptRepl {
|
|||||||
throw new EngineException("Couldn't open do.js");
|
throw new EngineException("Couldn't open do.js");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
environment.global.define(false, new NativeFunction("log", args -> {
|
||||||
|
for (var el : args.args) {
|
||||||
|
Values.printValue(args.ctx, el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}));
|
||||||
|
|
||||||
var fs = new RootFilesystem(PermissionsProvider.get(environment));
|
var fs = new RootFilesystem(PermissionsProvider.get(environment));
|
||||||
fs.protocols.put("temp", new MemoryFilesystem(Mode.READ_WRITE));
|
fs.protocols.put("temp", new MemoryFilesystem(Mode.READ_WRITE));
|
||||||
fs.protocols.put("file", new PhysicalFilesystem("."));
|
fs.protocols.put("file", new PhysicalFilesystem("."));
|
||||||
fs.protocols.put("std", STDFilesystem.ofStd(System.in, System.out, System.err));
|
fs.protocols.put("std", STDFilesystem.ofStd(System.in, System.out, System.err));
|
||||||
|
|
||||||
environment.add(PermissionsProvider.ENV_KEY, PermissionsManager.ALL_PERMS);
|
environment.add(PermissionsProvider.KEY, PermissionsManager.ALL_PERMS);
|
||||||
environment.add(Filesystem.ENV_KEY, fs);
|
environment.add(Filesystem.KEY, fs);
|
||||||
environment.add(ModuleRepo.ENV_KEY, ModuleRepo.ofFilesystem(fs));
|
environment.add(ModuleRepo.KEY, ModuleRepo.ofFilesystem(fs));
|
||||||
|
environment.add(Compiler.KEY, new JSCompiler(new Context(environment)));
|
||||||
|
environment.add(EventLoop.KEY, engine);
|
||||||
}
|
}
|
||||||
private static void initEngine() {
|
private static void initEngine() {
|
||||||
// var ctx = new DebugContext();
|
var ctx = new DebugContext();
|
||||||
// engine.add(DebugContext.ENV_KEY, ctx);
|
environment.add(DebugContext.KEY, ctx);
|
||||||
|
|
||||||
// debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws).attach(ctx));
|
// debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws).attach(ctx));
|
||||||
engineTask = engine.start();
|
engineTask = engine.start();
|
||||||
// debugTask = debugServer.start(new InetSocketAddress("127.0.0.1", 9229), true);
|
debugTask = debugServer.start(new InetSocketAddress("127.0.0.1", 9229), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) throws InterruptedException {
|
||||||
System.out.println(String.format("Running %s v%s by %s", Metadata.name(), Metadata.version(), Metadata.author()));
|
System.out.println(String.format("Running %s v%s by %s", Metadata.name(), Metadata.version(), Metadata.author()));
|
||||||
|
|
||||||
JScriptRepl.args = args;
|
JScriptRepl.args = args;
|
||||||
@ -136,5 +143,9 @@ public class JScriptRepl {
|
|||||||
reader.setDaemon(true);
|
reader.setDaemon(true);
|
||||||
reader.setName("STD Reader");
|
reader.setName("STD Reader");
|
||||||
reader.start();
|
reader.start();
|
||||||
|
|
||||||
|
engine.thread().join();
|
||||||
|
debugTask.interrupt();
|
||||||
|
engineTask.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package me.topchetoeu.jscript.utils.debug;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface DebugHandler {
|
|
||||||
void enable(V8Message msg) throws IOException;
|
|
||||||
void disable(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void setBreakpointByUrl(V8Message msg) throws IOException;
|
|
||||||
void removeBreakpoint(V8Message msg) throws IOException;
|
|
||||||
void continueToLocation(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void getScriptSource(V8Message msg) throws IOException;
|
|
||||||
void getPossibleBreakpoints(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void resume(V8Message msg) throws IOException;
|
|
||||||
void pause(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void stepInto(V8Message msg) throws IOException;
|
|
||||||
void stepOut(V8Message msg) throws IOException;
|
|
||||||
void stepOver(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void setPauseOnExceptions(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void evaluateOnCallFrame(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void getProperties(V8Message msg) throws IOException;
|
|
||||||
void releaseObjectGroup(V8Message msg) throws IOException;
|
|
||||||
void releaseObject(V8Message msg) throws IOException;
|
|
||||||
void callFunctionOn(V8Message msg) throws IOException;
|
|
||||||
|
|
||||||
void runtimeEnable(V8Message msg) throws IOException;
|
|
||||||
}
|
|
@ -1,7 +1,36 @@
|
|||||||
package me.topchetoeu.jscript.utils.debug;
|
package me.topchetoeu.jscript.utils.debug;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.debug.DebugController;
|
import me.topchetoeu.jscript.core.debug.DebugHandler;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface Debugger extends DebugHandler, DebugController {
|
public interface Debugger extends DebugHandler {
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
void enable(V8Message msg) throws IOException;
|
||||||
|
void disable(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void setBreakpointByUrl(V8Message msg) throws IOException;
|
||||||
|
void removeBreakpoint(V8Message msg) throws IOException;
|
||||||
|
void continueToLocation(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void getScriptSource(V8Message msg) throws IOException;
|
||||||
|
void getPossibleBreakpoints(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void resume(V8Message msg) throws IOException;
|
||||||
|
void pause(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void stepInto(V8Message msg) throws IOException;
|
||||||
|
void stepOut(V8Message msg) throws IOException;
|
||||||
|
void stepOver(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void setPauseOnExceptions(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void evaluateOnCallFrame(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void getProperties(V8Message msg) throws IOException;
|
||||||
|
void releaseObjectGroup(V8Message msg) throws IOException;
|
||||||
|
void releaseObject(V8Message msg) throws IOException;
|
||||||
|
void callFunctionOn(V8Message msg) throws IOException;
|
||||||
|
|
||||||
|
void runtimeEnable(V8Message msg) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -15,24 +15,31 @@ public interface File {
|
|||||||
|
|
||||||
default byte[] readAll() {
|
default byte[] readAll() {
|
||||||
var parts = new LinkedList<byte[]>();
|
var parts = new LinkedList<byte[]>();
|
||||||
|
var sizes = new LinkedList<Integer>();
|
||||||
var buff = new byte[1024];
|
var buff = new byte[1024];
|
||||||
var size = 0;
|
var size = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var n = read(buff);
|
var n = read(buff);
|
||||||
if (n == 0) break;
|
if (n < 0) break;
|
||||||
|
else if (n == 0) continue;
|
||||||
|
|
||||||
parts.add(buff);
|
parts.add(buff);
|
||||||
|
sizes.add(n);
|
||||||
size += n;
|
size += n;
|
||||||
|
buff = new byte[1024];
|
||||||
}
|
}
|
||||||
|
|
||||||
buff = new byte[size];
|
buff = new byte[size];
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
var j = 0;
|
||||||
|
|
||||||
for (var part : parts) {
|
for (var part : parts) {
|
||||||
System.arraycopy(part, 0, buff, i, part.length);
|
var currSize = sizes.get(j++);
|
||||||
i += part.length;
|
|
||||||
|
System.arraycopy(part, 0, buff, i, currSize);
|
||||||
|
i += currSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buff;
|
return buff;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.utils.filesystem;
|
package me.topchetoeu.jscript.utils.filesystem;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.Extensions;
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
import me.topchetoeu.jscript.core.Key;
|
||||||
|
|
||||||
public interface Filesystem {
|
public interface Filesystem {
|
||||||
public static final Symbol ENV_KEY = Symbol.get("Environment.fs");
|
public static final Key<Filesystem> KEY = new Key<>();
|
||||||
|
|
||||||
default String normalize(String... path) { return Paths.normalize(path); }
|
default String normalize(String... path) { return Paths.normalize(path); }
|
||||||
default boolean create(String path, EntryType type) { throw new FilesystemException(ErrorReason.UNSUPPORTED).setAction(ActionType.CREATE); }
|
default boolean create(String path, EntryType type) { throw new FilesystemException(ErrorReason.UNSUPPORTED).setAction(ActionType.CREATE); }
|
||||||
@ -13,6 +13,6 @@ public interface Filesystem {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
public static Filesystem get(Extensions exts) {
|
public static Filesystem get(Extensions exts) {
|
||||||
return exts.get(ENV_KEY);
|
return exts.get(KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ class MemoryFile extends BaseFile<Buffer> {
|
|||||||
private int ptr;
|
private int ptr;
|
||||||
|
|
||||||
@Override protected int onRead(byte[] buff) {
|
@Override protected int onRead(byte[] buff) {
|
||||||
|
if (ptr >= handle().length()) return -1;
|
||||||
var res = handle().read(ptr, buff);
|
var res = handle().read(ptr, buff);
|
||||||
ptr += res;
|
ptr += res;
|
||||||
return res;
|
return res;
|
||||||
|
@ -39,7 +39,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
throw ((EngineException)e.getTargetException()).add(ctx, name, Location.INTERNAL);
|
throw ((EngineException)e.getTargetException()).add(ctx, name, Location.INTERNAL);
|
||||||
}
|
}
|
||||||
else if (e.getTargetException() instanceof NullPointerException) {
|
else if (e.getTargetException() instanceof NullPointerException) {
|
||||||
e.printStackTrace();
|
// e.getTargetException().printStackTrace();
|
||||||
throw EngineException.ofType("Unexpected value of 'undefined'.").add(ctx, name, Location.INTERNAL);
|
throw EngineException.ofType("Unexpected value of 'undefined'.").add(ctx, name, Location.INTERNAL);
|
||||||
}
|
}
|
||||||
else if (e.getTargetException() instanceof InterruptException || e.getTargetException() instanceof InterruptedException) {
|
else if (e.getTargetException() instanceof InterruptException || e.getTargetException() instanceof InterruptedException) {
|
||||||
@ -172,7 +172,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
||||||
else {
|
else {
|
||||||
checkSignature(method, true, Environment.class);
|
checkSignature(method, true, Environment.class);
|
||||||
obj.defineProperty(null, key, call(new Context(null, env), name, method, null, env), true, true, false);
|
obj.defineProperty(null, key, call(new Context(env), name, method, null, env), true, true, false);
|
||||||
nonProps.add(key);
|
nonProps.add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ public class NativeWrapperProvider implements WrapperProvider {
|
|||||||
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
if (props.contains(key) || nonProps.contains(key)) repeat = true;
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
obj.defineProperty(null, key, Values.normalize(new Context(null, env), field.get(null)), true, true, false);
|
obj.defineProperty(null, key, Values.normalize(new Context(env), field.get(null)), true, true, false);
|
||||||
nonProps.add(key);
|
nonProps.add(key);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException | IllegalAccessException e) { }
|
catch (IllegalArgumentException | IllegalAccessException e) { }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.compilation.mapping;
|
package me.topchetoeu.jscript.utils.mapping;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -6,7 +6,6 @@ import java.util.TreeMap;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.common.Location;
|
import me.topchetoeu.jscript.common.Location;
|
||||||
import me.topchetoeu.jscript.common.VLQ;
|
|
||||||
import me.topchetoeu.jscript.common.json.JSON;
|
import me.topchetoeu.jscript.common.json.JSON;
|
||||||
|
|
||||||
public class SourceMap {
|
public class SourceMap {
|
@ -1,4 +1,4 @@
|
|||||||
package me.topchetoeu.jscript.common;
|
package me.topchetoeu.jscript.utils.mapping;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -5,13 +5,13 @@ import java.util.HashMap;
|
|||||||
import me.topchetoeu.jscript.common.Filename;
|
import me.topchetoeu.jscript.common.Filename;
|
||||||
import me.topchetoeu.jscript.core.Context;
|
import me.topchetoeu.jscript.core.Context;
|
||||||
import me.topchetoeu.jscript.core.Extensions;
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
import me.topchetoeu.jscript.core.Key;
|
||||||
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;
|
||||||
|
|
||||||
public interface ModuleRepo {
|
public interface ModuleRepo {
|
||||||
public static final Symbol ENV_KEY = Symbol.get("Environment.modules");
|
public static final Key<ModuleRepo> KEY = new Key<>();
|
||||||
public static final Symbol CWD = Symbol.get("Environment.moduleCwd");
|
public static final Key<String> CWD = new Key<>();
|
||||||
|
|
||||||
public Module getModule(Context ctx, String cwd, String name);
|
public Module getModule(Context ctx, String cwd, String name);
|
||||||
|
|
||||||
@ -39,6 +39,6 @@ public interface ModuleRepo {
|
|||||||
return exts.init(CWD, "/");
|
return exts.init(CWD, "/");
|
||||||
}
|
}
|
||||||
public static ModuleRepo get(Extensions exts) {
|
public static ModuleRepo get(Extensions exts) {
|
||||||
return exts.get(ENV_KEY);
|
return exts.get(KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class SourceModule extends Module {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object onLoad(Context ctx) {
|
protected Object onLoad(Context ctx) {
|
||||||
var res = new Context(ctx.engine, env).compile(filename, source);
|
var res = new Context(env).compile(filename, source);
|
||||||
return res.call(ctx);
|
return res.call(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.utils.permissions;
|
package me.topchetoeu.jscript.utils.permissions;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.core.Extensions;
|
import me.topchetoeu.jscript.core.Extensions;
|
||||||
import me.topchetoeu.jscript.core.values.Symbol;
|
import me.topchetoeu.jscript.core.Key;
|
||||||
|
|
||||||
public interface PermissionsProvider {
|
public interface PermissionsProvider {
|
||||||
public static final Symbol ENV_KEY = new Symbol("Environment.perms");
|
public static final Key<PermissionsProvider> KEY = new Key<>();
|
||||||
public static final PermissionsProvider ALL_PERMS = (perm, value) -> true;
|
public static final PermissionsProvider ALL_PERMS = (perm, value) -> true;
|
||||||
|
|
||||||
boolean hasPermission(Permission perm, String value);
|
boolean hasPermission(Permission perm, String value);
|
||||||
@ -22,7 +22,7 @@ public interface PermissionsProvider {
|
|||||||
|
|
||||||
public static PermissionsProvider get(Extensions exts) {
|
public static PermissionsProvider get(Extensions exts) {
|
||||||
return (perm, value) -> {
|
return (perm, value) -> {
|
||||||
if (exts.hasNotNull(ENV_KEY)) return ((PermissionsProvider)exts.get(ENV_KEY)).hasPermission(perm);
|
if (exts.hasNotNull(KEY)) return exts.get(KEY).hasPermission(perm);
|
||||||
else return true;
|
else return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user