diff --git a/src/me/topchetoeu/jscript/compilation/AssignStatement.java b/src/me/topchetoeu/jscript/compilation/AssignStatement.java deleted file mode 100644 index 6bb714f..0000000 --- a/src/me/topchetoeu/jscript/compilation/AssignStatement.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -import java.util.List; - -import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.engine.scope.ScopeRecord; - -public abstract class AssignStatement extends Statement { - public abstract void compile(List target, ScopeRecord scope, boolean retPrevValue); - - @Override - public void compile(List target, ScopeRecord scope) { - compile(target, scope, false); - } - - protected AssignStatement(Location loc) { - super(loc); - } -} diff --git a/src/me/topchetoeu/jscript/compilation/AssignableStatement.java b/src/me/topchetoeu/jscript/compilation/AssignableStatement.java index 810c2f8..4c3dfdb 100644 --- a/src/me/topchetoeu/jscript/compilation/AssignableStatement.java +++ b/src/me/topchetoeu/jscript/compilation/AssignableStatement.java @@ -4,7 +4,7 @@ import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.engine.Operation; public abstract class AssignableStatement extends Statement { - public abstract AssignStatement toAssign(Statement val, Operation operation); + public abstract Statement toAssign(Statement val, Operation operation); protected AssignableStatement(Location loc) { super(loc); diff --git a/src/me/topchetoeu/jscript/compilation/CompileOptions.java b/src/me/topchetoeu/jscript/compilation/CompileOptions.java deleted file mode 100644 index ab59b5d..0000000 --- a/src/me/topchetoeu/jscript/compilation/CompileOptions.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.topchetoeu.jscript.compilation; - -public class CompileOptions { - public final boolean emitBpMap; - public final boolean emitVarNames; - - public CompileOptions(boolean emitBpMap, boolean emitVarNames) { - this.emitBpMap = emitBpMap; - this.emitVarNames = emitVarNames; - } -} diff --git a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java index b5054c3..07fc640 100644 --- a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java +++ b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java @@ -13,16 +13,6 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class CompoundStatement extends Statement { public final Statement[] statements; - @Override - public boolean pollutesStack() { - for (var stm : statements) { - if (stm instanceof FunctionStatement) continue; - return true; - } - - return false; - } - @Override public void declare(ScopeRecord varsScope) { for (var stm : statements) { @@ -31,7 +21,7 @@ public class CompoundStatement extends Statement { } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { for (var stm : statements) { if (stm instanceof FunctionStatement) { int start = target.size(); @@ -45,8 +35,8 @@ public class CompoundStatement extends Statement { var stm = statements[i]; if (stm instanceof FunctionStatement) continue; - if (i != statements.length - 1) stm.compileNoPollution(target, scope, true); - else stm.compileWithPollution(target, scope); + if (i != statements.length - 1) stm.compileWithDebug(target, scope, false); + else stm.compileWithDebug(target, scope, pollute); } } diff --git a/src/me/topchetoeu/jscript/compilation/DiscardStatement.java b/src/me/topchetoeu/jscript/compilation/DiscardStatement.java index 3b216eb..67ad9f8 100644 --- a/src/me/topchetoeu/jscript/compilation/DiscardStatement.java +++ b/src/me/topchetoeu/jscript/compilation/DiscardStatement.java @@ -10,13 +10,9 @@ public class DiscardStatement extends Statement { public final Statement value; @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { - if (value == null) return; - value.compile(target, scope); - if (value.pollutesStack()) target.add(Instruction.discard()); + public void compile(List target, ScopeRecord scope, boolean pollute) { + value.compile(target, scope, false); + } @Override public Statement optimize() { diff --git a/src/me/topchetoeu/jscript/compilation/Instruction.java b/src/me/topchetoeu/jscript/compilation/Instruction.java index b0f66a0..bc588d8 100644 --- a/src/me/topchetoeu/jscript/compilation/Instruction.java +++ b/src/me/topchetoeu/jscript/compilation/Instruction.java @@ -7,7 +7,6 @@ import me.topchetoeu.jscript.exceptions.SyntaxException; public class Instruction { public static enum Type { RETURN, - SIGNAL, THROW, THROW_SYNTAX, DELETE, @@ -162,12 +161,6 @@ public class Instruction { return new Instruction(null, Type.NOP, args); } - /** - * ATTENTION: Usage outside of try/catch is broken af - */ - public static Instruction signal(String name) { - return new Instruction(null, Type.SIGNAL, name); - } public static Instruction nop(Object ...params) { for (var param : params) { if (param instanceof String) continue; diff --git a/src/me/topchetoeu/jscript/compilation/Statement.java b/src/me/topchetoeu/jscript/compilation/Statement.java index 95c5836..88d9644 100644 --- a/src/me/topchetoeu/jscript/compilation/Statement.java +++ b/src/me/topchetoeu/jscript/compilation/Statement.java @@ -8,29 +8,15 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public abstract class Statement { private Location _loc; - public abstract boolean pollutesStack(); public boolean pure() { return false; } - public abstract void compile(List target, ScopeRecord scope); + public abstract void compile(List target, ScopeRecord scope, boolean pollute); public void declare(ScopeRecord varsScope) { } public Statement optimize() { return this; } - public void compileNoPollution(List target, ScopeRecord scope, boolean debug) { + public void compileWithDebug(List target, ScopeRecord scope, boolean pollute) { int start = target.size(); - compile(target, scope); - if (debug && target.size() != start) target.get(start).setDebug(true); - if (pollutesStack()) target.add(Instruction.discard().locate(loc())); - } - public void compileWithPollution(List target, ScopeRecord scope, boolean debug) { - int start = target.size(); - compile(target, scope); - if (debug && target.size() != start) target.get(start).setDebug(true); - if (!pollutesStack()) target.add(Instruction.loadValue(null).locate(loc())); - } - public void compileNoPollution(List target, ScopeRecord scope) { - compileNoPollution(target, scope, false); - } - public void compileWithPollution(List target, ScopeRecord scope) { - compileWithPollution(target, scope, false); + compile(target, scope, pollute); + if (target.size() != start) target.get(start).setDebug(true); } public Location loc() { return _loc; } diff --git a/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java b/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java index 111f95b..ca91393 100644 --- a/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java +++ b/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java @@ -19,8 +19,6 @@ public class VariableDeclareStatement extends Statement { public final List values; - @Override - public boolean pollutesStack() { return false; } @Override public void declare(ScopeRecord varsScope) { for (var key : values) { @@ -28,7 +26,7 @@ public class VariableDeclareStatement extends Statement { } } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { for (var entry : values) { if (entry.name == null) continue; var key = scope.getKey(entry.name); @@ -39,10 +37,12 @@ public class VariableDeclareStatement extends Statement { target.add(Instruction.storeVar(key).locate(loc())); } else if (entry.value != null) { - entry.value.compileWithPollution(target, scope); + entry.value.compile(target, scope, true); target.add(Instruction.storeVar(key).locate(loc())); } } + + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public VariableDeclareStatement(Location loc, List values) { diff --git a/src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java b/src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java similarity index 82% rename from src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java rename to src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java index 640ac5c..7c4f1ce 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java @@ -1,37 +1,36 @@ -package me.topchetoeu.jscript.compilation.values; - -import java.util.List; - -import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.Instruction; -import me.topchetoeu.jscript.compilation.Statement; -import me.topchetoeu.jscript.engine.scope.ScopeRecord; - -public class ArrayStatement extends Statement { - public final Statement[] statements; - - @Override - public boolean pollutesStack() { return true; } - @Override - public boolean pure() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { - target.add(Instruction.loadArr(statements.length).locate(loc())); - var i = 0; - for (var el : statements) { - if (el != null) { - target.add(Instruction.dup().locate(loc())); - target.add(Instruction.loadValue(i).locate(loc())); - el.compileWithPollution(target, scope); - target.add(Instruction.storeMember().locate(loc())); - } - i++; - } - } - - public ArrayStatement(Location loc, Statement[] statements) { - super(loc); - this.statements = statements; - } -} +package me.topchetoeu.jscript.compilation.control; + +import java.util.List; + +import me.topchetoeu.jscript.Location; +import me.topchetoeu.jscript.compilation.Instruction; +import me.topchetoeu.jscript.compilation.Statement; +import me.topchetoeu.jscript.engine.scope.ScopeRecord; + +public class ArrayStatement extends Statement { + public final Statement[] statements; + + @Override + public boolean pure() { return true; } + + @Override + public void compile(List target, ScopeRecord scope, boolean pollute) { + target.add(Instruction.loadArr(statements.length).locate(loc())); + var i = 0; + for (var el : statements) { + if (el != null) { + target.add(Instruction.dup().locate(loc())); + target.add(Instruction.loadValue(i).locate(loc())); + el.compile(target, scope, true); + target.add(Instruction.storeMember().locate(loc())); + } + i++; + } + if (!pollute) target.add(Instruction.discard().locate(loc())); + } + + public ArrayStatement(Location loc, Statement[] statements) { + super(loc); + this.statements = statements; + } +} diff --git a/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java b/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java index 17a530e..7e84fac 100644 --- a/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java @@ -11,11 +11,9 @@ public class BreakStatement extends Statement { public final String label; @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.nop("break", label).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public BreakStatement(Location loc, String label) { diff --git a/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java b/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java index 3d3f827..a0c8b6b 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java @@ -11,11 +11,9 @@ public class ContinueStatement extends Statement { public final String label; @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.nop("cont", label).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public ContinueStatement(Location loc, String label) { diff --git a/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java b/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java index a65f7ae..3edb6c0 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java @@ -9,11 +9,9 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class DebugStatement extends Statement { @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.debug().locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public DebugStatement(Location loc) { diff --git a/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java b/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java index 01bc3c4..9907524 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java @@ -12,13 +12,12 @@ public class DeleteStatement extends Statement { public final Statement value; @Override - public boolean pollutesStack() { return true; } + public void compile(List target, ScopeRecord scope, boolean pollute) { + value.compile(target, scope, true); + key.compile(target, scope, true); - @Override - public void compile(List target, ScopeRecord scope) { - value.compile(target, scope); - key.compile(target, scope); target.add(Instruction.delete().locate(loc())); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public DeleteStatement(Location loc, Statement key, Statement value) { diff --git a/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java b/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java index e648bf0..49621d5 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java @@ -14,19 +14,16 @@ public class DoWhileStatement extends Statement { public final Statement condition, body; public final String label; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { body.declare(globScope); } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (condition instanceof ConstantStatement) { int start = target.size(); - body.compileNoPollution(target, scope); + body.compile(target, scope, false); int end = target.size(); if (Values.toBoolean(((ConstantStatement)condition).value)) { WhileStatement.replaceBreaks(target, label, start, end, end + 1, end + 1); @@ -35,13 +32,14 @@ public class DoWhileStatement extends Statement { target.add(Instruction.jmp(start - end).locate(loc())); WhileStatement.replaceBreaks(target, label, start, end, start, end + 1); } + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); return; } int start = target.size(); - body.compileNoPollution(target, scope, true); + body.compileWithDebug(target, scope, false); int mid = target.size(); - condition.compileWithPollution(target, scope); + condition.compile(target, scope, true); int end = target.size(); WhileStatement.replaceBreaks(target, label, start, mid - 1, mid, end + 1); diff --git a/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java b/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java index 5f7538d..fb82218 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java @@ -14,9 +14,6 @@ public class ForInStatement extends Statement { public final Statement varValue, object, body; public final String label; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { body.declare(globScope); @@ -24,16 +21,16 @@ public class ForInStatement extends Statement { } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { var key = scope.getKey(varName); if (key instanceof String) target.add(Instruction.makeVar((String)key)); if (varValue != null) { - varValue.compileWithPollution(target, scope); + varValue.compile(target, scope, true); target.add(Instruction.storeVar(scope.getKey(varName))); } - object.compileWithPollution(target, scope); + object.compile(target, scope, true); target.add(Instruction.keys()); int start = target.size(); @@ -58,8 +55,7 @@ public class ForInStatement extends Statement { for (var i = start; i < target.size(); i++) target.get(i).locate(loc()); - body.compileNoPollution(target, scope, true); - + body.compileWithDebug(target, scope, false); int end = target.size(); @@ -68,6 +64,7 @@ public class ForInStatement extends Statement { target.add(Instruction.jmp(start - end).locate(loc())); target.add(Instruction.discard().locate(loc())); target.set(mid, Instruction.jmpIf(end - mid + 1).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public ForInStatement(Location loc, String label, boolean isDecl, String varName, Statement varValue, Statement object, Statement body) { diff --git a/src/me/topchetoeu/jscript/compilation/control/ForStatement.java b/src/me/topchetoeu/jscript/compilation/control/ForStatement.java index 6fce19f..e135a74 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ForStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ForStatement.java @@ -14,44 +14,43 @@ public class ForStatement extends Statement { public final Statement declaration, assignment, condition, body; public final String label; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { declaration.declare(globScope); body.declare(globScope); } @Override - public void compile(List target, ScopeRecord scope) { - declaration.compile(target, scope); + public void compile(List target, ScopeRecord scope, boolean pollute) { + declaration.compile(target, scope, false); if (condition instanceof ConstantStatement) { if (Values.toBoolean(((ConstantStatement)condition).value)) { int start = target.size(); - body.compileNoPollution(target, scope); + body.compile(target, scope, false); int mid = target.size(); - assignment.compileNoPollution(target, scope, true); + assignment.compileWithDebug(target, scope, false); int end = target.size(); WhileStatement.replaceBreaks(target, label, start, mid, mid, end + 1); target.add(Instruction.jmp(start - target.size()).locate(loc())); - return; + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } + return; } int start = target.size(); - condition.compileWithPollution(target, scope); + condition.compile(target, scope, true); int mid = target.size(); target.add(Instruction.nop()); - body.compileNoPollution(target, scope); + body.compile(target, scope, false); int beforeAssign = target.size(); - assignment.compile(target, scope); + assignment.compileWithDebug(target, scope, false); int end = target.size(); WhileStatement.replaceBreaks(target, label, mid + 1, end, beforeAssign, end + 1); target.add(Instruction.jmp(start - end).locate(loc())); target.set(mid, Instruction.jmpIfNot(end - mid + 1).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } @Override public Statement optimize() { diff --git a/src/me/topchetoeu/jscript/compilation/control/IfStatement.java b/src/me/topchetoeu/jscript/compilation/control/IfStatement.java index b3e1579..1f2921b 100644 --- a/src/me/topchetoeu/jscript/compilation/control/IfStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/IfStatement.java @@ -14,9 +14,6 @@ import me.topchetoeu.jscript.engine.values.Values; public class IfStatement extends Statement { public final Statement condition, body, elseBody; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { body.declare(globScope); @@ -24,33 +21,34 @@ public class IfStatement extends Statement { } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (condition instanceof ConstantStatement) { if (Values.not(((ConstantStatement)condition).value)) { - if (elseBody != null) elseBody.compileNoPollution(target, scope, true); + if (elseBody != null) elseBody.compileWithDebug(target, scope, pollute); } else { - body.compileNoPollution(target, scope, true); + body.compileWithDebug(target, scope, pollute); } return; } - condition.compileWithPollution(target, scope); + condition.compile(target, scope, true); + if (elseBody == null) { int i = target.size(); target.add(Instruction.nop()); - body.compileNoPollution(target, scope, true); + body.compileWithDebug(target, scope, pollute); int endI = target.size(); target.set(i, Instruction.jmpIfNot(endI - i).locate(loc())); } else { int start = target.size(); target.add(Instruction.nop()); - body.compileNoPollution(target, scope, true); + body.compileWithDebug(target, scope, pollute); target.add(Instruction.nop()); int mid = target.size(); - elseBody.compileNoPollution(target, scope, true); + elseBody.compileWithDebug(target, scope, pollute); int end = target.size(); target.set(start, Instruction.jmpIfNot(mid - start).locate(loc())); diff --git a/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java b/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java index 3139e24..8d10211 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java @@ -11,12 +11,9 @@ public class ReturnStatement extends Statement { public final Statement value; @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (value == null) target.add(Instruction.loadValue(null).locate(loc())); - else value.compileWithPollution(target, scope); + else value.compile(target, scope, true); target.add(Instruction.ret().locate(loc())); } diff --git a/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java b/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java index 1151a35..a9b0993 100644 --- a/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java @@ -21,9 +21,6 @@ public class SwitchStatement extends Statement { } } - @Override - public boolean pollutesStack() { return false; } - public final Statement value; public final SwitchCase[] cases; public final Statement[] body; @@ -35,15 +32,15 @@ public class SwitchStatement extends Statement { } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { var caseMap = new HashMap(); var stmIndexMap = new HashMap(); - value.compile(target, scope); + value.compile(target, scope, true); for (var ccase : cases) { target.add(Instruction.dup().locate(loc())); - ccase.value.compileWithPollution(target, scope); + ccase.value.compile(target, scope, true); target.add(Instruction.operation(Operation.EQUALS).locate(loc())); caseMap.put(target.size(), ccase.statementI); target.add(Instruction.nop()); @@ -55,7 +52,7 @@ public class SwitchStatement extends Statement { for (var stm : body) { stmIndexMap.put(stmIndexMap.size(), target.size()); - stm.compileNoPollution(target, scope, true); + stm.compileWithDebug(target, scope, false); } if (defaultI < 0 || defaultI >= body.length) target.set(start, Instruction.jmp(target.size() - start).locate(loc())); diff --git a/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java b/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java index 136446e..ea68d47 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java @@ -11,11 +11,8 @@ public class ThrowStatement extends Statement { public final Statement value; @Override - public boolean pollutesStack() { return false; } - - @Override - public void compile(List target, ScopeRecord scope) { - value.compileWithPollution(target, scope); + public void compile(List target, ScopeRecord scope, boolean pollute) { + value.compile(target, scope, true); target.add(Instruction.throwInstr().locate(loc())); } diff --git a/src/me/topchetoeu/jscript/compilation/control/TryStatement.java b/src/me/topchetoeu/jscript/compilation/control/TryStatement.java index 0c23230..f25fdf2 100644 --- a/src/me/topchetoeu/jscript/compilation/control/TryStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/TryStatement.java @@ -15,9 +15,6 @@ public class TryStatement extends Statement { public final Statement finallyBody; public final String name; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { tryBody.declare(globScope); @@ -26,30 +23,31 @@ public class TryStatement extends Statement { } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.nop()); int start = target.size(), tryN, catchN = -1, finN = -1; - tryBody.compileNoPollution(target, scope); + tryBody.compile(target, scope, false); tryN = target.size() - start; if (catchBody != null) { int tmp = target.size(); var local = scope instanceof GlobalScope ? scope.child() : (LocalScopeRecord)scope; local.define(name, true); - catchBody.compileNoPollution(target, scope); + catchBody.compile(target, scope, false); local.undefine(); catchN = target.size() - tmp; } if (finallyBody != null) { int tmp = target.size(); - finallyBody.compileNoPollution(target, scope); + finallyBody.compile(target, scope, false); finN = target.size() - tmp; } target.set(start - 1, Instruction.tryInstr(tryN, catchN, finN).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public TryStatement(Location loc, Statement tryBody, Statement catchBody, Statement finallyBody, String name) { diff --git a/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java b/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java index af7738b..84dbde8 100644 --- a/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java @@ -16,19 +16,16 @@ public class WhileStatement extends Statement { public final Statement condition, body; public final String label; - @Override - public boolean pollutesStack() { return false; } - @Override public void declare(ScopeRecord globScope) { body.declare(globScope); } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (condition instanceof ConstantStatement) { if (Values.toBoolean(((ConstantStatement)condition).value)) { int start = target.size(); - body.compileNoPollution(target, scope); + body.compile(target, scope, false); int end = target.size(); replaceBreaks(target, label, start, end, start, end + 1); target.add(Instruction.jmp(start - target.size()).locate(loc())); @@ -37,10 +34,10 @@ public class WhileStatement extends Statement { } int start = target.size(); - condition.compileWithPollution(target, scope); + condition.compile(target, scope, true); int mid = target.size(); target.add(Instruction.nop()); - body.compileNoPollution(target, scope); + body.compile(target, scope, false); int end = target.size(); @@ -48,6 +45,7 @@ public class WhileStatement extends Statement { target.add(Instruction.jmp(start - end).locate(loc())); target.set(mid, Instruction.jmpIfNot(end - mid + 1).locate(loc())); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } @Override public Statement optimize() { diff --git a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java index de1c495..8908179 100644 --- a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java @@ -12,23 +12,19 @@ public class CallStatement extends Statement { public final Statement[] args; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (func instanceof IndexStatement) { - ((IndexStatement)func).compile(target, scope, true); + ((IndexStatement)func).compile(target, scope, true, true); } else { - target.add(Instruction.loadValue(null).locate(loc())); - func.compileWithPollution(target, scope); + target.add(Instruction.loadValue(null).locate(loc())); + func.compile(target, scope, true); } - for (var arg : args) { - arg.compileWithPollution(target, scope); - } + for (var arg : args) arg.compile(target, scope, true); target.add(Instruction.call(args.length).locate(loc()).setDebug(true)); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public CallStatement(Location loc, Statement func, Statement ...args) { diff --git a/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java b/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java index 3574f95..0d97f15 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java @@ -15,11 +15,9 @@ public class ChangeStatement extends Statement { public final boolean postfix; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { value.toAssign(new ConstantStatement(loc(), -addAmount), Operation.SUBTRACT).compile(target, scope, postfix); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public ChangeStatement(Location loc, AssignableStatement value, double addAmount, boolean postfix) { diff --git a/src/me/topchetoeu/jscript/compilation/values/CommaStatement.java b/src/me/topchetoeu/jscript/compilation/values/CommaStatement.java deleted file mode 100644 index 541b5c2..0000000 --- a/src/me/topchetoeu/jscript/compilation/values/CommaStatement.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.topchetoeu.jscript.compilation.values; - -import java.util.List; - -import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.Instruction; -import me.topchetoeu.jscript.compilation.Statement; -import me.topchetoeu.jscript.engine.scope.ScopeRecord; - -public class CommaStatement extends Statement { - public final Statement first; - public final Statement second; - - @Override - public boolean pollutesStack() { return true; } - @Override - public boolean pure() { return first.pure() && second.pure(); } - - @Override - public void compile(List target, ScopeRecord scope) { - first.compileNoPollution(target, scope); - second.compileWithPollution(target, scope); - } - - @Override - public Statement optimize() { - var f = first.optimize(); - var s = second.optimize(); - if (f.pure()) return s; - else return new CommaStatement(loc(), f, s); - } - - public CommaStatement(Location loc, Statement first, Statement second) { - super(loc); - this.first = first; - this.second = second; - } -} diff --git a/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java b/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java index e254eee..563175b 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java @@ -10,14 +10,12 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class ConstantStatement extends Statement { public final Object value; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public void compile(List target, ScopeRecord scope) { - target.add(Instruction.loadValue(value).locate(loc())); + public void compile(List target, ScopeRecord scope, boolean pollute) { + if (pollute) target.add(Instruction.loadValue(value).locate(loc())); } public ConstantStatement(Location loc, Object val) { diff --git a/src/me/topchetoeu/jscript/compilation/values/FunctionStatement.java b/src/me/topchetoeu/jscript/compilation/values/FunctionStatement.java index c0937db..60cb65b 100644 --- a/src/me/topchetoeu/jscript/compilation/values/FunctionStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/FunctionStatement.java @@ -17,8 +17,6 @@ public class FunctionStatement extends Statement { @Override public boolean pure() { return name == null; } - @Override - public boolean pollutesStack() { return true; } @Override public void declare(ScopeRecord scope) { @@ -69,7 +67,7 @@ public class FunctionStatement extends Statement { body.declare(subscope); target.add(Instruction.debugVarNames(subscope.locals())); - body.compile(target, subscope); + body.compile(target, subscope, false); checkBreakAndCont(target, start); @@ -90,12 +88,13 @@ public class FunctionStatement extends Statement { var key = scope.getKey(this.name); if (key instanceof String) target.add(Instruction.makeVar((String)key).locate(loc())); - target.add(Instruction.storeVar(scope.getKey(this.name), true).locate(loc())); + target.add(Instruction.storeVar(scope.getKey(this.name), false).locate(loc())); } } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { compile(target, scope, null, false); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public FunctionStatement(Location loc, String name, String[] args, CompoundStatement body) { diff --git a/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java b/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java index 15e0515..0b8479c 100644 --- a/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java @@ -8,14 +8,12 @@ import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class GlobalThisStatement extends Statement { - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public void compile(List target, ScopeRecord scope) { - target.add(Instruction.loadGlob().locate(loc())); + public void compile(List target, ScopeRecord scope, boolean pollute) { + if (pollute) target.add(Instruction.loadGlob().locate(loc())); } public GlobalThisStatement(Location loc) { diff --git a/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java b/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java index 872e804..b14b70f 100644 --- a/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java @@ -3,49 +3,37 @@ package me.topchetoeu.jscript.compilation.values; import java.util.List; import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.AssignStatement; import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.compilation.Statement; import me.topchetoeu.jscript.engine.Operation; import me.topchetoeu.jscript.engine.scope.ScopeRecord; -public class IndexAssignStatement extends AssignStatement { +public class IndexAssignStatement extends Statement { public final Statement object; public final Statement index; public final Statement value; public final Operation operation; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope, boolean retPrevValue) { - int start = 0; - + public void compile(List target, ScopeRecord scope, boolean pollute) { if (operation != null) { - object.compileWithPollution(target, scope); - index.compileWithPollution(target, scope); + object.compile(target, scope, true); + index.compile(target, scope, true); target.add(Instruction.dup(2, 0).locate(loc())); target.add(Instruction.loadMember().locate(loc())); - if (retPrevValue) { - target.add(Instruction.dup().locate(loc())); - target.add(Instruction.move(3, 1).locate(loc())); - } - value.compileWithPollution(target, scope); + value.compile(target, scope, true); target.add(Instruction.operation(operation).locate(loc())); - target.add(Instruction.storeMember(!retPrevValue).locate(loc()).setDebug(true)); + target.add(Instruction.storeMember(pollute).locate(loc()).setDebug(true)); } else { - object.compileWithPollution(target, scope); - if (retPrevValue) target.add(Instruction.dup().locate(loc())); - index.compileWithPollution(target, scope); - value.compileWithPollution(target, scope); + object.compile(target, scope, true); + index.compile(target, scope, true); + value.compile(target, scope, true); - target.add(Instruction.storeMember(!retPrevValue).locate(loc()).setDebug(true)); + target.add(Instruction.storeMember(pollute).locate(loc()).setDebug(true)); } - target.get(start); } public IndexAssignStatement(Location loc, Statement object, Statement index, Statement value, Operation operation) { diff --git a/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java b/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java index 39fe76d..ff913aa 100644 --- a/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java @@ -3,7 +3,6 @@ package me.topchetoeu.jscript.compilation.values; import java.util.List; import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.AssignStatement; import me.topchetoeu.jscript.compilation.AssignableStatement; import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.compilation.Statement; @@ -14,31 +13,30 @@ public class IndexStatement extends AssignableStatement { public final Statement object; public final Statement index; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public AssignStatement toAssign(Statement val, Operation operation) { + public Statement toAssign(Statement val, Operation operation) { return new IndexAssignStatement(loc(), object, index, val, operation); } - public void compile(List target, ScopeRecord scope, boolean dupObj) { + public void compile(List target, ScopeRecord scope, boolean dupObj, boolean pollute) { int start = 0; - object.compileWithPollution(target, scope); + object.compile(target, scope, true); if (dupObj) target.add(Instruction.dup().locate(loc())); if (index instanceof ConstantStatement) { target.add(Instruction.loadMember(((ConstantStatement)index).value).locate(loc())); return; } - index.compileWithPollution(target, scope); + index.compile(target, scope, true); target.add(Instruction.loadMember().locate(loc())); target.get(start).setDebug(true); + if (!pollute) target.add(Instruction.discard().locate(loc())); } @Override - public void compile(List target, ScopeRecord scope) { - compile(target, scope, false); + public void compile(List target, ScopeRecord scope, boolean pollute) { + compile(target, scope, false, pollute); } public IndexStatement(Location loc, Statement object, Statement index) { diff --git a/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java b/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java index 59fb3e1..0517dcf 100644 --- a/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java @@ -11,29 +11,27 @@ import me.topchetoeu.jscript.engine.values.Values; public class LazyAndStatement extends Statement { public final Statement first, second; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return first.pure() && second.pure(); } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (first instanceof ConstantStatement) { if (Values.not(((ConstantStatement)first).value)) { - first.compileWithPollution(target, scope); + first.compile(target, scope, pollute); } - else second.compileWithPollution(target, scope); + else second.compile(target, scope, pollute); return; } - first.compileWithPollution(target, scope); - target.add(Instruction.dup().locate(loc())); + first.compile(target, scope, true); + if (pollute) target.add(Instruction.dup().locate(loc())); int start = target.size(); target.add(Instruction.nop()); target.add(Instruction.discard().locate(loc())); - second.compileWithPollution(target, scope); + second.compile(target, scope, pollute); target.set(start, Instruction.jmpIfNot(target.size() - start).locate(loc())); } diff --git a/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java b/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java index 78b6104..d601429 100644 --- a/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java @@ -11,29 +11,27 @@ import me.topchetoeu.jscript.engine.values.Values; public class LazyOrStatement extends Statement { public final Statement first, second; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return first.pure() && second.pure(); } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (first instanceof ConstantStatement) { if (Values.not(((ConstantStatement)first).value)) { - second.compileWithPollution(target, scope); + second.compile(target, scope, pollute); } - else first.compileWithPollution(target, scope); + else first.compile(target, scope, pollute); return; } - first.compileWithPollution(target, scope); - target.add(Instruction.dup().locate(loc())); + first.compile(target, scope, true); + if (pollute) target.add(Instruction.dup().locate(loc())); int start = target.size(); target.add(Instruction.nop()); target.add(Instruction.discard().locate(loc())); - second.compileWithPollution(target, scope); + second.compile(target, scope, pollute); target.set(start, Instruction.jmpIf(target.size() - start).locate(loc())); } diff --git a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java index 3b5d1d8..4f50098 100644 --- a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java @@ -12,14 +12,10 @@ public class NewStatement extends Statement { public final Statement[] args; @Override - public boolean pollutesStack() { return true; } + public void compile(List target, ScopeRecord scope, boolean pollute) { + func.compile(target, scope, true); - @Override - public void compile(List target, ScopeRecord scope) { - func.compileWithPollution(target, scope); - for (var arg : args) { - arg.compileWithPollution(target, scope); - } + for (var arg : args) arg.compile(target, scope, true); target.add(Instruction.callNew(args.length).locate(loc()).setDebug(true)); } diff --git a/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java b/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java index 2852aca..7a2e9cc 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java @@ -15,10 +15,7 @@ public class ObjectStatement extends Statement { public final Map setters; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.loadObj().locate(loc())); for (var el : map.entrySet()) { @@ -26,7 +23,7 @@ public class ObjectStatement extends Statement { target.add(Instruction.loadValue(el.getKey()).locate(loc())); var val = el.getValue(); if (val instanceof FunctionStatement) ((FunctionStatement)val).compile(target, scope, el.getKey().toString(), false); - else val.compileWithPollution(target, scope); + else val.compile(target, scope, true); target.add(Instruction.storeMember().locate(loc())); } @@ -38,14 +35,16 @@ public class ObjectStatement extends Statement { if (key instanceof String) target.add(Instruction.loadValue((String)key).locate(loc())); else target.add(Instruction.loadValue((Double)key).locate(loc())); - if (getters.containsKey(key)) getters.get(key).compileWithPollution(target, scope); + if (getters.containsKey(key)) getters.get(key).compile(target, scope, true); else target.add(Instruction.loadValue(null).locate(loc())); - if (setters.containsKey(key)) setters.get(key).compileWithPollution(target, scope); + if (setters.containsKey(key)) setters.get(key).compile(target, scope, true); else target.add(Instruction.loadValue(null).locate(loc())); target.add(Instruction.defProp().locate(loc())); } + + if (!pollute) target.add(Instruction.discard().locate(loc())); } public ObjectStatement(Location loc, Map map, Map getters, Map setters) { diff --git a/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java b/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java index 1723429..96d12ab 100644 --- a/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java @@ -16,15 +16,15 @@ public class OperationStatement extends Statement { public final Operation operation; @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { for (var arg : args) { - arg.compileWithPollution(target, scope); + arg.compile(target, scope, true); } - target.add(Instruction.operation(operation).locate(loc())); + + if (pollute) target.add(Instruction.operation(operation).locate(loc())); + else target.add(Instruction.discard().locate(loc())); } - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { for (var arg : args) { diff --git a/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java b/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java index ad92abd..162c71c 100644 --- a/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java @@ -10,14 +10,13 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class RegexStatement extends Statement { public final String pattern, flags; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { target.add(Instruction.loadRegex(pattern, flags).locate(loc())); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public RegexStatement(Location loc, String pattern, String flags) { diff --git a/src/me/topchetoeu/jscript/compilation/values/TernaryStatement.java b/src/me/topchetoeu/jscript/compilation/values/TernaryStatement.java deleted file mode 100644 index d2c5a6d..0000000 --- a/src/me/topchetoeu/jscript/compilation/values/TernaryStatement.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.topchetoeu.jscript.compilation.values; - -import java.util.List; - -import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.Instruction; -import me.topchetoeu.jscript.compilation.Statement; -import me.topchetoeu.jscript.engine.scope.ScopeRecord; -import me.topchetoeu.jscript.engine.values.Values; - -public class TernaryStatement extends Statement { - public final Statement condition; - public final Statement first; - public final Statement second; - - @Override - public boolean pollutesStack() { return true; } - @Override - public boolean pure() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { - if (condition instanceof ConstantStatement) { - if (!Values.toBoolean(((ConstantStatement)condition).value)) { - second.compileWithPollution(target, scope); - } - else first.compileWithPollution(target, scope); - return; - } - - condition.compileWithPollution(target, scope); - int start = target.size(); - target.add(Instruction.nop()); - first.compileWithPollution(target, scope); - int mid = target.size(); - target.add(Instruction.nop()); - second.compileWithPollution(target, scope); - int end = target.size(); - - target.set(start, Instruction.jmpIfNot(mid - start + 1).locate(loc())); - target.set(mid, Instruction.jmp(end - mid).locate(loc())); - } - - @Override - public Statement optimize() { - var cond = condition.optimize(); - var f = first.optimize(); - var s = second.optimize(); - return new TernaryStatement(loc(), cond, f, s); - } - - public TernaryStatement(Location loc, Statement condition, Statement first, Statement second) { - super(loc); - this.condition = condition; - this.first = first; - this.second = second; - } -} diff --git a/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java b/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java index 0c069fd..50a0183 100644 --- a/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java @@ -5,19 +5,18 @@ import java.util.List; import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.compilation.Statement; +import me.topchetoeu.jscript.compilation.control.ArrayStatement; import me.topchetoeu.jscript.engine.scope.ScopeRecord; import me.topchetoeu.jscript.engine.values.Values; public class TypeofStatement extends Statement { public final Statement value; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { if (value instanceof VariableStatement) { var i = scope.getKey(((VariableStatement)value).name); if (i instanceof String) { @@ -25,7 +24,7 @@ public class TypeofStatement extends Statement { return; } } - value.compileWithPollution(target, scope); + value.compile(target, scope, pollute); target.add(Instruction.typeof().locate(loc())); } diff --git a/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java b/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java index 5740c11..749f939 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java @@ -4,36 +4,32 @@ import java.util.List; import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.compilation.Statement; -import me.topchetoeu.jscript.compilation.AssignStatement; import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.engine.Operation; import me.topchetoeu.jscript.engine.scope.ScopeRecord; -public class VariableAssignStatement extends AssignStatement { +public class VariableAssignStatement extends Statement { public final String name; public final Statement value; public final Operation operation; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope, boolean retPrevValue) { + public void compile(List target, ScopeRecord scope, boolean pollute) { var i = scope.getKey(name); if (operation != null) { target.add(Instruction.loadVar(i).locate(loc())); - if (retPrevValue) target.add(Instruction.dup().locate(loc())); if (value instanceof FunctionStatement) ((FunctionStatement)value).compile(target, scope, name, false); - else value.compileWithPollution(target, scope); + else value.compile(target, scope, true); target.add(Instruction.operation(operation).locate(loc())); - target.add(Instruction.storeVar(i, !retPrevValue).locate(loc())); + target.add(Instruction.storeVar(i, false).locate(loc())); } else { - if (retPrevValue) target.add(Instruction.loadVar(i).locate(loc())); if (value instanceof FunctionStatement) ((FunctionStatement)value).compile(target, scope, name, false); - else value.compileWithPollution(target, scope); - target.add(Instruction.storeVar(i, !retPrevValue).locate(loc())); + else value.compile(target, scope, true); + target.add(Instruction.storeVar(i, false).locate(loc())); } + + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } public VariableAssignStatement(Location loc, String name, Statement val, Operation operation) { diff --git a/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java b/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java index 2556af8..e02a5fd 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java @@ -10,14 +10,12 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class VariableIndexStatement extends Statement { public final int index; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public void compile(List target, ScopeRecord scope) { - target.add(Instruction.loadVar(index).locate(loc())); + public void compile(List target, ScopeRecord scope, boolean pollute) { + if (pollute) target.add(Instruction.loadVar(index).locate(loc())); } public VariableIndexStatement(Location loc, int i) { diff --git a/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java b/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java index b2db5ae..1059014 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java @@ -3,7 +3,6 @@ package me.topchetoeu.jscript.compilation.values; import java.util.List; import me.topchetoeu.jscript.Location; -import me.topchetoeu.jscript.compilation.AssignStatement; import me.topchetoeu.jscript.compilation.AssignableStatement; import me.topchetoeu.jscript.compilation.Instruction; import me.topchetoeu.jscript.compilation.Statement; @@ -13,20 +12,19 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class VariableStatement extends AssignableStatement { public final String name; - @Override - public boolean pollutesStack() { return true; } @Override public boolean pure() { return true; } @Override - public AssignStatement toAssign(Statement val, Operation operation) { + public Statement toAssign(Statement val, Operation operation) { return new VariableAssignStatement(loc(), name, val, operation); } @Override - public void compile(List target, ScopeRecord scope) { + public void compile(List target, ScopeRecord scope, boolean pollute) { var i = scope.getKey(name); target.add(Instruction.loadVar(i).locate(loc())); + if (!pollute) target.add(Instruction.discard().locate(loc())); } public VariableStatement(Location loc, String name) { diff --git a/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java b/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java index dbcbe38..21b5bb2 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java @@ -11,12 +11,9 @@ public class VoidStatement extends Statement { public final Statement value; @Override - public boolean pollutesStack() { return true; } - - @Override - public void compile(List target, ScopeRecord scope) { - if (value != null) value.compileNoPollution(target, scope); - target.add(Instruction.loadValue(null).locate(loc())); + public void compile(List target, ScopeRecord scope, boolean pollute) { + if (value != null) value.compile(target, scope, false); + if (pollute) target.add(Instruction.loadValue(null).locate(loc())); } @Override diff --git a/src/me/topchetoeu/jscript/engine/frame/Runners.java b/src/me/topchetoeu/jscript/engine/frame/Runners.java index 09f3f18..2869eda 100644 --- a/src/me/topchetoeu/jscript/engine/frame/Runners.java +++ b/src/me/topchetoeu/jscript/engine/frame/Runners.java @@ -9,7 +9,6 @@ import me.topchetoeu.jscript.engine.scope.ValueVariable; import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.CodeFunction; import me.topchetoeu.jscript.engine.values.ObjectValue; -import me.topchetoeu.jscript.engine.values.SignalValue; import me.topchetoeu.jscript.engine.values.Symbol; import me.topchetoeu.jscript.engine.values.Values; import me.topchetoeu.jscript.exceptions.EngineException; @@ -20,9 +19,6 @@ public class Runners { public static Object execReturn(Context ctx, Instruction instr, CodeFrame frame) { return frame.pop(); } - public static Object execSignal(Context ctx, Instruction instr, CodeFrame frame) { - return new SignalValue(instr.get(0)); - } public static Object execThrow(Context ctx, Instruction instr, CodeFrame frame) { throw new EngineException(frame.pop()); } @@ -343,11 +339,9 @@ public class Runners { } public static Object exec(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException { - // System.out.println(instr + "@" + instr.location); switch (instr.type) { case NOP: return execNop(ctx, instr, frame); case RETURN: return execReturn(ctx, instr, frame); - case SIGNAL: return execSignal(ctx, instr, frame); case THROW: return execThrow(ctx, instr, frame); case THROW_SYNTAX: return execThrowSyntax(ctx, instr, frame); case CALL: return execCall(ctx, instr, frame); diff --git a/src/me/topchetoeu/jscript/engine/values/SignalValue.java b/src/me/topchetoeu/jscript/engine/values/SignalValue.java deleted file mode 100644 index 2c2ad2a..0000000 --- a/src/me/topchetoeu/jscript/engine/values/SignalValue.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.topchetoeu.jscript.engine.values; - -public final class SignalValue { - public final String data; - - public SignalValue(String data) { - this.data = data; - } - - public static boolean isSignal(Object signal, String value) { - if (!(signal instanceof SignalValue)) return false; - var val = ((SignalValue)signal).data; - - if (value.endsWith("*")) return val.startsWith(value.substring(0, value.length() - 1)); - else return val.equals(value); - } -} diff --git a/src/me/topchetoeu/jscript/engine/values/Values.java b/src/me/topchetoeu/jscript/engine/values/Values.java index 07a0036..cc27f10 100644 --- a/src/me/topchetoeu/jscript/engine/values/Values.java +++ b/src/me/topchetoeu/jscript/engine/values/Values.java @@ -84,7 +84,6 @@ public class Values { obj instanceof String || obj instanceof Boolean || obj instanceof Symbol || - obj instanceof SignalValue || obj == null || obj == NULL; } @@ -143,7 +142,6 @@ public class Values { if (val instanceof Boolean) return (Boolean)val ? "true" : "false"; if (val instanceof String) return (String)val; if (val instanceof Symbol) return ((Symbol)val).toString(); - if (val instanceof SignalValue) return "[signal '" + ((SignalValue)val).data + "']"; return "Unknown value"; } diff --git a/src/me/topchetoeu/jscript/parsing/Parsing.java b/src/me/topchetoeu/jscript/parsing/Parsing.java index 16d2f8c..5962f42 100644 --- a/src/me/topchetoeu/jscript/parsing/Parsing.java +++ b/src/me/topchetoeu/jscript/parsing/Parsing.java @@ -1230,7 +1230,7 @@ public class Parsing { return ParseRes.res(new OperationStatement(loc, Operation.IN, prev, valRes.result), n); } - public static ParseRes parseComma(String filename, List tokens, int i, Statement prev, int precedence) { + public static ParseRes parseComma(String filename, List tokens, int i, Statement prev, int precedence) { var loc = getLoc(filename, tokens, i); var n = 0; @@ -1241,9 +1241,9 @@ public class Parsing { if (!res.isSuccess()) return ParseRes.error(loc, "Expected a value after the comma.", res); n += res.n; - return ParseRes.res(new CommaStatement(loc, prev, res.result), n); + return ParseRes.res(new CompoundStatement(loc, prev, res.result), n); } - public static ParseRes parseTernary(String filename, List tokens, int i, Statement prev, int precedence) { + public static ParseRes parseTernary(String filename, List tokens, int i, Statement prev, int precedence) { var loc = getLoc(filename, tokens, i); var n = 0; @@ -1260,7 +1260,7 @@ public class Parsing { if (!b.isSuccess()) return ParseRes.error(loc, "Expected a second value after the ternary operator.", b); n += b.n; - return ParseRes.res(new TernaryStatement(loc, prev, a.result, b.result), n); + return ParseRes.res(new IfStatement(loc, prev, a.result, b.result), n); } public static ParseRes parseOperator(String filename, List tokens, int i, Statement prev, int precedence) { var loc = getLoc(filename, tokens, i); @@ -1886,7 +1886,7 @@ public class Parsing { body.declare(target); try { - body.compile(res, subscope); + body.compile(res, subscope, true); FunctionStatement.checkBreakAndCont(res, 0); } catch (SyntaxException e) {