From 7c74df4d36a4f80fb3d2fa93ca2da5144dd8c997 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:25:39 +0300 Subject: [PATCH] refactor: use new system to reorder variables that overlaps neighboring scopes --- .../jscript/compilation/CompileResult.java | 1 + .../jscript/compilation/FunctionNode.java | 13 +- .../jscript/compilation/JavaScript.java | 1 + .../compilation/scope/FunctionScope.java | 82 +++++------ .../jscript/compilation/scope/Scope.java | 127 ++++++++++-------- .../jscript/compilation/scope/Variable.java | 16 +-- .../compilation/scope/VariableIndex.java | 44 ++++++ .../compilation/scope/VariableList.java | 105 +++++---------- .../compilation/values/VariableNode.java | 8 +- .../me/topchetoeu/jscript/runtime/Frame.java | 19 ++- .../jscript/runtime/InstructionRunner.java | 2 - src/main/resources/lib/index.js | 4 +- 12 files changed, 205 insertions(+), 217 deletions(-) create mode 100644 src/main/java/me/topchetoeu/jscript/compilation/scope/VariableIndex.java diff --git a/src/main/java/me/topchetoeu/jscript/compilation/CompileResult.java b/src/main/java/me/topchetoeu/jscript/compilation/CompileResult.java index 4234653..c4e6382 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/CompileResult.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/CompileResult.java @@ -106,6 +106,7 @@ public final class CompileResult { for (var suppl : instructions) { instrRes[i] = suppl.apply(i); + // System.out.println(instrRes[i]); i++; } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java b/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java index 154b360..9e09ff2 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/FunctionNode.java @@ -31,13 +31,6 @@ public abstract class FunctionNode extends Node { .remove(LabelContext.CONTINUE_CTX); return new CompileResult(env, scope, params.params.size(), target -> { - // if (params.params.size() > 0) target.add(Instruction.loadArgs(true)); - - // if (hasArgs) { - // var argsVar = scope.defineStrict(new Variable("arguments", true), loc()); - // target.add(_i -> Instruction.storeVar(argsVar.index(), params.params.size() > 0)); - // } - if (params.params.size() > 0) { target.add(Instruction.loadArgs(true)); if (params.params.size() > 1) target.add(Instruction.dup(params.params.size() - 1)); @@ -65,7 +58,7 @@ public abstract class FunctionNode extends Node { end.set(target.size()); } - target.add(_i -> Instruction.storeVar(varI.index())); + target.add(_i -> varI.index().toSet(false)); } } @@ -73,14 +66,14 @@ public abstract class FunctionNode extends Node { if (scope.has(params.restName, false)) throw new SyntaxException(params.restLocation, "Duplicate parameter name not allowed"); var restVar = scope.define(new Variable(params.restName, false), params.restLocation); target.add(Instruction.loadRestArgs(params.params.size())); - target.add(_i -> Instruction.storeVar(restVar.index())); + target.add(_i -> restVar.index().toSet(false)); } if (selfName != null && !scope.has(name, false)) { var i = scope.defineSpecial(new Variable(selfName, true), end); target.add(Instruction.loadCallee()); - target.add(_i -> Instruction.storeVar(i.index(), false)); + target.add(_i -> i.index().toSet(false)); } body.resolve(target); diff --git a/src/main/java/me/topchetoeu/jscript/compilation/JavaScript.java b/src/main/java/me/topchetoeu/jscript/compilation/JavaScript.java index 5e06b59..87d3d7e 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/JavaScript.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/JavaScript.java @@ -311,6 +311,7 @@ public final class JavaScript { else if (res.isFailed()) throw new SyntaxException(src.loc(i), "Unexpected syntax"); i += res.n; + i += Parsing.skipEmpty(src, i); list.add(res.result); } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java b/src/main/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java index 4f8f143..e935be3 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java @@ -4,65 +4,56 @@ import java.util.HashMap; import java.util.HashSet; import me.topchetoeu.jscript.common.parsing.Location; -import me.topchetoeu.jscript.runtime.exceptions.SyntaxException; public class FunctionScope extends Scope { - private final VariableList captures = new VariableList().setIndexMap(v -> ~v); - private final VariableList specials = new VariableList(); - private final VariableList locals = new VariableList(specials); - private final HashMap childToParent = new HashMap<>(); + private final VariableList captures = new VariableList(VariableIndex.IndexType.CAPTURES); + + private final HashMap specialVarMap = new HashMap<>(); + private final HashMap functionVarMap = new HashMap<>(); + private final HashMap capturesMap = new HashMap<>(); private final HashSet blacklistNames = new HashSet<>(); + private final HashMap childToParent = new HashMap<>(); + private final Scope captureParent; public final boolean passtrough; - private void removeCapture(String name) { - var res = captures.remove(name); - if (res != null) { - childToParent.remove(res); - res.setIndexSupplier(() -> { throw new SyntaxException(null, res.name + " has been shadowed"); }); - } - } - @Override public Variable define(Variable var, Location loc) { checkNotEnded(); - if (variables.has(var.name)) throw alreadyDefinedErr(loc, var.name); + if (strictVarMap.containsKey(var.name)) throw alreadyDefinedErr(loc, var.name); if (passtrough) { blacklistNames.add(var.name); return null; } - - removeCapture(var.name); - return locals.add(var); + else { + functionVarMap.put(var.name, var); + return variables.add(var); + } } @Override public Variable defineStrict(Variable var, Location loc) { checkNotEnded(); - if (locals.has(var.name)) throw alreadyDefinedErr(loc, var.name); + if (functionVarMap.containsKey(var.name)) throw alreadyDefinedErr(loc, var.name); if (blacklistNames.contains(var.name)) throw alreadyDefinedErr(loc, var.name); - var res = super.defineStrict(var, loc); - removeCapture(var.name); - return res; + return super.defineStrict(var, loc); } public Variable defineSpecial(Variable var, Location loc) { - return specials.add(var); - } + checkNotEnded(); + if (strictVarMap.containsKey(var.name)) throw alreadyDefinedErr(loc, var.name); - @Override public boolean flattenVariable(Variable variable, boolean capturable) { - // if (!ended()) throw new IllegalStateException("Tried to flatten a variable before the scope has ended"); - this.locals.overlay(variable); - return true; + specialVarMap.put(var.name, var); + return variables.add(var); } @Override public Variable get(String name, boolean capture) { var superRes = super.get(name, capture); if (superRes != null) return superRes; - if (specials.has(name)) return addCaptured(specials.get(name), capture); - if (locals.has(name)) return addCaptured(locals.get(name), capture); - if (captures.has(name)) return addCaptured(captures.get(name), capture); + if (specialVarMap.containsKey(name)) return addCaptured(specialVarMap.get(name), capture); + if (functionVarMap.containsKey(name)) return addCaptured(functionVarMap.get(name), capture); + if (capturesMap.containsKey(name)) return addCaptured(capturesMap.get(name), capture); if (captureParent == null) return null; @@ -70,47 +61,32 @@ public class FunctionScope extends Scope { if (parentVar == null) return null; var childVar = captures.add(parentVar.clone()); - + capturesMap.put(childVar.name, childVar); childToParent.put(childVar, parentVar); return childVar; } @Override public boolean has(String name, boolean capture) { - if (specials.has(name)) return true; - if (locals.has(name)) return true; + if (functionVarMap.containsKey(name)) return true; + if (specialVarMap.containsKey(name)) return true; if (capture) { - if (captures.has(name)) return true; + if (capturesMap.containsKey(name)) return true; if (captureParent != null) return captureParent.has(name, true); } return false; } - @Override public boolean finish() { - if (!super.finish()) return false; - + @Override protected void onFinish() { captures.freeze(); - locals.freeze(); - specials.freeze(); - - return true; + super.onFinish(); } - @Override public int allocCount() { - return 0; - } @Override public int capturesCount() { return captures.size(); } - @Override public int localsCount() { - return locals.size() + specials.size() + super.allocCount(); - } - - public int offset() { - return specials.size() + locals.size(); - } public int[] getCaptureIndices() { var res = new int[captures.size()]; @@ -118,7 +94,7 @@ public class FunctionScope extends Scope { for (var el : captures.all()) { assert childToParent.containsKey(el); - res[i] = childToParent.get(el).index(); + res[i] = childToParent.get(el).index().toCaptureIndex(); i++; } @@ -130,10 +106,12 @@ public class FunctionScope extends Scope { if (parent.finished()) throw new RuntimeException("Parent is finished"); this.captureParent = parent; this.passtrough = false; + this.singleEntry = false; } public FunctionScope(boolean passtrough) { super(); this.captureParent = null; this.passtrough = passtrough; + this.singleEntry = false; } } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/scope/Scope.java b/src/main/java/me/topchetoeu/jscript/compilation/scope/Scope.java index 3129e36..1131766 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/scope/Scope.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/scope/Scope.java @@ -1,27 +1,23 @@ package me.topchetoeu.jscript.compilation.scope; -import java.util.HashSet; +import java.util.HashMap; import java.util.LinkedList; -import java.util.List; import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.runtime.exceptions.SyntaxException; public class Scope { - protected final VariableList variables = new VariableList(this::parentOffset); + protected final HashMap strictVarMap = new HashMap<>(); + + protected final VariableList variables = new VariableList(VariableIndex.IndexType.LOCALS, this::parentVarOffset); + protected final VariableList captured = new VariableList(VariableIndex.IndexType.CAPTURABLES, this::parentCapOffset); private boolean ended = false; private boolean finished = false; private Scope child; - private List prevChildren = new LinkedList<>(); + private LinkedList children = new LinkedList<>(); public final Scope parent; - public final HashSet captured = new HashSet<>(); - - protected final Variable addCaptured(Variable var, boolean captured) { - if (captured) this.captured.add(var); - return var; - } /** * Wether or not the scope is going to be entered multiple times. @@ -29,10 +25,30 @@ public class Scope { */ public boolean singleEntry = true; - private final int parentOffset() { - if (parent != null) return parent.offset(); + + protected void transferCaptured(Variable var) { + if (!singleEntry) { + this.captured.add(var); + } + else if (parent != null) { + parent.transferCaptured(var); + } + else throw new IllegalStateException("Couldn't transfer captured variable"); + } + + protected final Variable addCaptured(Variable var, boolean captured) { + if (captured) transferCaptured(var); + return var; + } + + private final int parentVarOffset() { + if (parent != null) return parent.variableOffset(); else return 0; } + private final int parentCapOffset() { + if (parent != null) return parent.capturedOffset(); + else return localsCount(); + } protected final SyntaxException alreadyDefinedErr(Location loc, String name) { return new SyntaxException(loc, String.format("Identifier '%s' has already been declared", name)); @@ -54,7 +70,7 @@ public class Scope { */ public Variable define(Variable var, Location loc) { checkNotEnded(); - if (variables.has(var.name)) throw alreadyDefinedErr(loc, var.name); + if (strictVarMap.containsKey(var.name)) throw alreadyDefinedErr(loc, var.name); if (parent != null) return parent.define(var, loc); return null; @@ -69,10 +85,10 @@ public class Scope { */ public Variable defineStrict(Variable var, Location loc) { checkNotEnded(); - if (variables.has(var.name)) throw alreadyDefinedErr(loc, var.name); + if (strictVarMap.containsKey(var.name)) throw alreadyDefinedErr(loc, var.name); - variables.add(var); - return var.setIndexSupplier(() -> variables.indexOfKey(var.name)); + strictVarMap.put(var.name, var); + return variables.add(var); } /** * Gets the index supplier of the given variable name, or null if it is a global @@ -80,7 +96,8 @@ public class Scope { * @param capture If true, the variable is being captured by a function */ public Variable get(String name, boolean capture) { - var res = variables.get(name); + var res = strictVarMap.get(name); + if (res != null) return addCaptured(res, capture); if (parent != null) return parent.get(name, capture); @@ -92,7 +109,7 @@ public class Scope { * @param capture If true, will check beyond this function's scope */ public boolean has(String name, boolean capture) { - if (variables.has(name)) return true; + if (strictVarMap.containsKey(name)) return true; if (parent != null) return parent.has(name, capture); return false; @@ -100,31 +117,34 @@ public class Scope { /** * Gets the index offset from this scope to its children */ - public int offset() { - if (parent != null) return parent.offset() + variables.size(); + public final int variableOffset() { + if (parent != null) return parent.variableOffset() + variables.size(); else return variables.size(); } - - /** - * Adds this variable to the current function's locals record. Capturable indicates whether or not the variable - * should still be capturable, or be put in an array (still not implemented) - * - * @return Whether or not the request was actually fuliflled - */ - public boolean flattenVariable(Variable variable, boolean capturable) { - if (singleEntry || !capturable) { - if (parent == null) return false; - return parent.flattenVariable(variable, capturable); - } - else { - variables.overlay(variable); - return true; - } + public final int capturedOffset() { + if (parent != null) return parent.capturedOffset() + captured.size(); + else return localsCount() + captured.size(); } - public int localsCount() { return 0; } + public int localsCount() { + var res = 0; + for (var child : children) { + var childN = child.localsCount(); + if (res < childN) res = childN; + } + + return res + variables.size(); + } public int capturesCount() { return 0; } - public int allocCount() { return variables.size(); } + public int allocCount() { + var res = captured.size(); + return res; + } + public int capturablesCount() { + var res = captured.size(); + for (var child : children) res += child.allocCount(); + return res; + } /** * Ends this scope. This will make it possible for another child to take its place @@ -142,34 +162,23 @@ public class Scope { return true; } + protected void onFinish() { + this.variables.freeze(); + this.captured.freeze(); + } + /** * Finalizes this scope. The scope will become immutable after this call * @return */ - public boolean finish() { + public final boolean finish() { if (finished) return false; + if (parent != null && parent.finished) throw new IllegalStateException("Tried to finish a child after the parent was finished"); + this.onFinish(); - for (var child : prevChildren) child.finish(); + for (var child : children) child.finish(); - var captured = new HashSet(); - var normal = new HashSet(); - - for (var v : variables.all()) { - if (this.captured.contains(v)) { - if (singleEntry) captured.add(v); - } - else normal.add(v); - } - - for (var v : captured) variables.remove(v); - for (var v : normal) variables.remove(v); - - for (var v : captured) flattenVariable(v, true); - for (var v : normal) flattenVariable(v, false); - - - this.variables.freeze(); this.finished = true; return true; @@ -190,7 +199,7 @@ public class Scope { this.parent = parent; this.parent.child = this; - this.parent.prevChildren.add(this); + this.parent.children.add(this); } else this.parent = null; } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/scope/Variable.java b/src/main/java/me/topchetoeu/jscript/compilation/scope/Variable.java index af74088..3a91792 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/scope/Variable.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/scope/Variable.java @@ -1,28 +1,28 @@ package me.topchetoeu.jscript.compilation.scope; -import java.util.function.IntSupplier; +import java.util.function.Supplier; public final class Variable { - private IntSupplier indexSupplier; + private Supplier indexSupplier; private boolean frozen; public final boolean readonly; public final String name; - public final int index() { + public final VariableIndex index() { if (!frozen) throw new IllegalStateException("Tried to access the index of a variable before it was finalized"); - return indexSupplier.getAsInt(); + return indexSupplier.get(); } public final void freeze() { this.frozen = true; } - public final Variable setIndexSupplier(IntSupplier index) { + public final Variable setIndexSupplier(Supplier index) { this.indexSupplier = index; return this; } - public final IntSupplier indexSupplier() { + public final Supplier indexSupplier() { return indexSupplier; } @@ -35,7 +35,7 @@ public final class Variable { this.readonly = readonly; } - public static Variable of(String name, boolean readonly, int i) { - return new Variable(name, readonly).setIndexSupplier(() -> i); + public static Variable of(String name, boolean readonly, VariableIndex index) { + return new Variable(name, readonly).setIndexSupplier(() -> index); } } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableIndex.java b/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableIndex.java new file mode 100644 index 0000000..3e04a05 --- /dev/null +++ b/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableIndex.java @@ -0,0 +1,44 @@ +package me.topchetoeu.jscript.compilation.scope; + +import me.topchetoeu.jscript.common.Instruction; + +public final class VariableIndex { + public static enum IndexType { + LOCALS, + CAPTURABLES, + CAPTURES, + } + + public final VariableIndex.IndexType type; + public final int index; + + public final int toCaptureIndex() { + switch (type) { + case CAPTURES: return ~index; + case CAPTURABLES: return index; + default: throw new UnsupportedOperationException("Index type " + type + " may not be captured"); + } + } + + public final Instruction toGet() { + switch (type) { + case CAPTURES: return Instruction.loadVar(~index); + case CAPTURABLES: return Instruction.loadVar(index); + case LOCALS: return Instruction.loadVar(index); + default: throw new UnsupportedOperationException("Unknown index type " + type); + } + } + public final Instruction toSet(boolean keep) { + switch (type) { + case CAPTURES: return Instruction.storeVar(~index, keep); + case CAPTURABLES: return Instruction.storeVar(index, keep); + case LOCALS: return Instruction.storeVar(index, keep); + default: throw new UnsupportedOperationException("Unknown index type " + type); + } + } + + public VariableIndex(VariableIndex.IndexType type, int index) { + this.type = type; + this.index = index; + } +} \ No newline at end of file diff --git a/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableList.java b/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableList.java index 9dfed4b..3e71689 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableList.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/scope/VariableList.java @@ -4,27 +4,22 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.function.IntSupplier; -import java.util.function.IntUnaryOperator; -import java.util.stream.StreamSupport; +import java.util.function.Supplier; public final class VariableList { - private final class Node implements IntSupplier { + private final class VariableNode implements Supplier { public Variable var; - public Node next; - public Node prev; + public VariableNode next; + public VariableNode prev; public boolean frozen; public int index; - @Override public int getAsInt() { + public VariableList list() { return VariableList.this; } + + @Override public VariableIndex get() { if (frozen) { - if (offset == null) { - return indexConverter == null ? index : indexConverter.applyAsInt(index); - } - else { - return indexConverter == null ? - index + offset.getAsInt() : - indexConverter.applyAsInt(index + offset.getAsInt()); - } + if (offset == null) return new VariableIndex(indexType, index); + else new VariableIndex(indexType, index + offset.getAsInt()); } var res = 0; @@ -34,7 +29,7 @@ public final class VariableList { res++; } - return indexConverter == null ? res : indexConverter.applyAsInt(res); + return new VariableIndex(indexType, res); } public void freeze() { @@ -50,26 +45,26 @@ public final class VariableList { return; } - public Node(Variable var, Node next, Node prev) { + public VariableNode(Variable var, VariableNode next, VariableNode prev) { this.var = var; this.next = next; this.prev = prev; } } - private Node first, last; + private VariableNode first, last; - private final HashMap map = new HashMap<>(); - private ArrayList frozenList = null; - private HashMap varMap = new HashMap<>(); + private ArrayList frozenList = null; + private HashMap varMap = new HashMap<>(); private final IntSupplier offset; - private IntUnaryOperator indexConverter = null; + + public final VariableIndex.IndexType indexType; public boolean frozen() { if (frozenList != null) { assert frozenList != null; - assert map != null; + assert varMap == null; assert first == null; assert last == null; @@ -77,21 +72,20 @@ public final class VariableList { } else { assert frozenList == null; - assert map != null; + assert varMap != null; return false; } } - private Variable add(Variable val, boolean overlay) { + public Variable add(Variable val) { if (frozen()) throw new RuntimeException("The scope has been frozen"); - if (!overlay && map.containsKey(val.name)) { - var node = this.map.get(val.name); - val.setIndexSupplier(node); - return node.var; + + if (val.indexSupplier() instanceof VariableNode prevNode) { + prevNode.list().remove(val); } - var node = new Node(val, null, last); + var node = new VariableNode(val, null, last); if (last != null) { assert first != null; @@ -105,28 +99,17 @@ public final class VariableList { first = last = node; } - map.put(val.name, node); varMap.put(val, node); val.setIndexSupplier(node); return val; } - public Variable add(Variable val) { - return this.add(val, false); - } - public Variable overlay(Variable val) { - return this.add(val, true); - } - public Variable remove(String key) { - var res = map.get(key); - if (res != null) return remove(res.var); - else return null; - } public Variable remove(Variable var) { - if (var == null) return null; if (frozen()) throw new RuntimeException("The scope has been frozen"); + if (var == null) return null; + var node = varMap.get(var); if (node == null) return null; @@ -151,28 +134,18 @@ public final class VariableList { node.next = null; node.prev = null; - map.remove(node.var.name); varMap.remove(node.var); return node.var; } - public Variable get(String name) { - var res = map.get(name); - if (res != null) return res.var; - else return null; - } - public int indexOfKey(String name) { - return map.get(name).getAsInt(); - } - - public boolean has(String name) { - return this.map.containsKey(name); + public Supplier indexer(Variable var) { + return varMap.get(var); } public int size() { if (frozen()) return frozenList.size(); - else return map.size(); + else return varMap.size(); } public void freeze() { @@ -195,7 +168,7 @@ public final class VariableList { public Iterable all() { if (frozen()) return () -> frozenList.stream().map(v -> v.var).iterator(); else return () -> new Iterator() { - private Node curr = first; + private VariableNode curr = first; @Override public boolean hasNext() { return curr != null; @@ -209,25 +182,21 @@ public final class VariableList { } }; } - public Iterable keys() { - return () -> StreamSupport.stream(all().spliterator(), false).map(v -> v.name).iterator(); - } - public VariableList setIndexMap(IntUnaryOperator map) { - indexConverter = map; - return this; - } - - public VariableList(IntSupplier offset) { + public VariableList(VariableIndex.IndexType type, IntSupplier offset) { + this.indexType = type; this.offset = offset; } - public VariableList(int offset) { + public VariableList(VariableIndex.IndexType type, int offset) { + this.indexType = type; this.offset = () -> offset; } - public VariableList(VariableList prev) { + public VariableList(VariableIndex.IndexType type, VariableList prev) { + this.indexType = type; this.offset = prev::size; } - public VariableList() { + public VariableList(VariableIndex.IndexType type) { + this.indexType = type; this.offset = null; } } diff --git a/src/main/java/me/topchetoeu/jscript/compilation/values/VariableNode.java b/src/main/java/me/topchetoeu/jscript/compilation/values/VariableNode.java index 0bf8ea6..eb4db6f 100644 --- a/src/main/java/me/topchetoeu/jscript/compilation/values/VariableNode.java +++ b/src/main/java/me/topchetoeu/jscript/compilation/values/VariableNode.java @@ -34,9 +34,7 @@ public class VariableNode extends Node implements AssignableNode { if (!pollute) target.add(Instruction.discard()); } - else if (pollute) { - target.add(_i -> Instruction.loadVar(i.index())); - } + else if (pollute) target.add(_i -> i.index().toGet()); } public static IntFunction toGet(CompileResult target, Location loc, String name, Supplier onGlobal) { @@ -46,7 +44,7 @@ public class VariableNode extends Node implements AssignableNode { if (target.scope.has(name, false)) return Instruction.throwSyntax(loc, String.format("Cannot access '%s' before initialization", name)); else return onGlobal.get(); }; - else return _i -> Instruction.loadVar(i.index()); + else return _i -> i.index().toGet(); } public static IntFunction toGet(CompileResult target, Location loc, String name) { return toGet(target, loc, name, () -> Instruction.globGet(name)); @@ -61,7 +59,7 @@ public class VariableNode extends Node implements AssignableNode { else return Instruction.globSet(name, keep, define); }; else if (!define && i.readonly) return _i -> Instruction.throwSyntax(new SyntaxException(loc, "Assignment to constant variable")); - else return _i -> Instruction.storeVar(i.index(), keep); + else return _i -> i.index().toSet(keep); } public VariableNode(Location loc, String name) { diff --git a/src/main/java/me/topchetoeu/jscript/runtime/Frame.java b/src/main/java/me/topchetoeu/jscript/runtime/Frame.java index 31f9434..170162c 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/Frame.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/Frame.java @@ -18,7 +18,6 @@ import me.topchetoeu.jscript.runtime.values.Value; import me.topchetoeu.jscript.runtime.values.Member.FieldMember; import me.topchetoeu.jscript.runtime.values.functions.CodeFunction; import me.topchetoeu.jscript.runtime.values.objects.ObjectValue; -import me.topchetoeu.jscript.runtime.values.objects.ScopeValue; public final class Frame { public static final Key KEY = Key.of(); @@ -357,18 +356,18 @@ public final class Frame { * Gets an object proxy of the capture locals */ public ObjectValue getCaptureScope() { - // throw new RuntimeException("Not supported"); + throw new RuntimeException("Not supported"); - var names = new String[captures.length]; - var map = DebugContext.get(env).getMapOrEmpty(function); + // var names = new String[captures.length]; + // var map = DebugContext.get(env).getMapOrEmpty(function); - for (int i = 0; i < captures.length; i++) { - var name = "capture_" + (i - 2); - if (i < map.captureNames.length) name = map.captureNames[i]; - names[i] = name; - } + // for (int i = 0; i < captures.length; i++) { + // var name = "capture_" + (i - 2); + // if (i < map.captureNames.length) name = map.captureNames[i]; + // names[i] = name; + // } - return new ScopeValue(captures, names); + // return new ScopeValue(captures, names); } /** * Gets an array proxy of the local locals diff --git a/src/main/java/me/topchetoeu/jscript/runtime/InstructionRunner.java b/src/main/java/me/topchetoeu/jscript/runtime/InstructionRunner.java index 67badc2..0c464bf 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/InstructionRunner.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/InstructionRunner.java @@ -340,8 +340,6 @@ public class InstructionRunner { frame.stackPtr -= 1; var ptr = frame.stackPtr; - // for (var i = op.operands - 1; i >= 0; i--) args[i] = frame.pop(); - switch (op) { case ADD: res = Value.add(env, stack[ptr - 1], stack[ptr]); diff --git a/src/main/resources/lib/index.js b/src/main/resources/lib/index.js index c807527..43e8837 100644 --- a/src/main/resources/lib/index.js +++ b/src/main/resources/lib/index.js @@ -257,8 +257,6 @@ const Function = function() { parts[parts.length] = String(arguments[arguments.length - 1]); parts[parts.length] = "\n}"; - print(parts); - const res = compile(stringBuild(parts))(); return res; }; @@ -310,4 +308,4 @@ setGlobalPrototype("string", String.prototype); setGlobalPrototype("number", Number.prototype); setGlobalPrototype("boolean", Boolean.prototype); setGlobalPrototype("symbol", Symbol.prototype); -setGlobalPrototype("object", Object.prototype); \ No newline at end of file +setGlobalPrototype("object", Object.prototype);