diff --git a/src/me/topchetoeu/jscript/compilation/CompileTarget.java b/src/me/topchetoeu/jscript/compilation/CompileTarget.java index 1484d19..7f71ad0 100644 --- a/src/me/topchetoeu/jscript/compilation/CompileTarget.java +++ b/src/me/topchetoeu/jscript/compilation/CompileTarget.java @@ -28,6 +28,10 @@ public class CompileTarget { return target.get(i); } public int size() { return target.size(); } + public Location lastLoc(Location fallback) { + if (target.size() == 0) return fallback; + else return target.get(target.size() - 1).location; + } public Instruction[] array() { return target.toArray(Instruction[]::new); } diff --git a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java index 1e25de7..d38d6bf 100644 --- a/src/me/topchetoeu/jscript/compilation/CompoundStatement.java +++ b/src/me/topchetoeu/jscript/compilation/CompoundStatement.java @@ -23,10 +23,7 @@ public class CompoundStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { for (var stm : statements) { - if (stm instanceof FunctionStatement) { - ((FunctionStatement)stm).compile(target, scope, null, true); - target.add(Instruction.discard()); - } + if (stm instanceof FunctionStatement) stm.compile(target, scope, false); } for (var i = 0; i < statements.length; i++) { @@ -38,7 +35,7 @@ public class CompoundStatement extends Statement { } if (end != null) { - target.add(Instruction.nop().locate(end)); + target.add(Instruction.nop(end)); target.setDebug(); } } diff --git a/src/me/topchetoeu/jscript/compilation/Instruction.java b/src/me/topchetoeu/jscript/compilation/Instruction.java index c1dae6e..1df5293 100644 --- a/src/me/topchetoeu/jscript/compilation/Instruction.java +++ b/src/me/topchetoeu/jscript/compilation/Instruction.java @@ -129,26 +129,29 @@ public class Instruction { this.params = params; } - public static Instruction tryInstr(int n, int catchN, int finallyN) { - return new Instruction(null, Type.TRY, n, catchN, finallyN); + public static Instruction tryInstr(Location loc, int n, int catchN, int finallyN) { + return new Instruction(loc, Type.TRY, n, catchN, finallyN); } - public static Instruction throwInstr() { - return new Instruction(null, Type.THROW); + public static Instruction throwInstr(Location loc) { + return new Instruction(loc, Type.THROW); } - public static Instruction throwSyntax(SyntaxException err) { - return new Instruction(null, Type.THROW_SYNTAX, err.getMessage()); + public static Instruction throwSyntax(Location loc, SyntaxException err) { + return new Instruction(loc, Type.THROW_SYNTAX, err.getMessage()); } - public static Instruction delete() { - return new Instruction(null, Type.DELETE); + public static Instruction throwSyntax(Location loc, String err) { + return new Instruction(loc, Type.THROW_SYNTAX, err); } - public static Instruction ret() { - return new Instruction(null, Type.RETURN); + public static Instruction delete(Location loc) { + return new Instruction(loc, Type.DELETE); } - public static Instruction debug() { - return new Instruction(null, Type.NOP, "debug"); + public static Instruction ret(Location loc) { + return new Instruction(loc, Type.RETURN); + } + public static Instruction debug(Location loc) { + return new Instruction(loc, Type.NOP, "debug"); } - public static Instruction nop(Object ...params) { + public static Instruction nop(Location loc, Object ...params) { for (var param : params) { if (param instanceof String) continue; if (param instanceof Boolean) continue; @@ -158,109 +161,107 @@ public class Instruction { throw new RuntimeException("NOP params may contain only strings, booleans, doubles, integers and nulls."); } - return new Instruction(null, Type.NOP, params); + return new Instruction(loc, Type.NOP, params); } - public static Instruction call(int argn) { - return new Instruction(null, Type.CALL, argn); + public static Instruction call(Location loc, int argn) { + return new Instruction(loc, Type.CALL, argn); } - public static Instruction callNew(int argn) { - return new Instruction(null, Type.CALL_NEW, argn); + public static Instruction callNew(Location loc, int argn) { + return new Instruction(loc, Type.CALL_NEW, argn); } - public static Instruction jmp(int offset) { - return new Instruction(null, Type.JMP, offset); + public static Instruction jmp(Location loc, int offset) { + return new Instruction(loc, Type.JMP, offset); } - public static Instruction jmpIf(int offset) { - return new Instruction(null, Type.JMP_IF, offset); + public static Instruction jmpIf(Location loc, int offset) { + return new Instruction(loc, Type.JMP_IF, offset); } - public static Instruction jmpIfNot(int offset) { - return new Instruction(null, Type.JMP_IFN, offset); + public static Instruction jmpIfNot(Location loc, int offset) { + return new Instruction(loc, Type.JMP_IFN, offset); } - public static Instruction loadValue(Object val) { - return new Instruction(null, Type.LOAD_VALUE, val); + public static Instruction loadValue(Location loc, Object val) { + return new Instruction(loc, Type.LOAD_VALUE, val); } - public static Instruction makeVar(String name) { - return new Instruction(null, Type.MAKE_VAR, name); + public static Instruction makeVar(Location loc, String name) { + return new Instruction(loc, Type.MAKE_VAR, name); } - public static Instruction loadVar(Object i) { - return new Instruction(null, Type.LOAD_VAR, i); + public static Instruction loadVar(Location loc, Object i) { + return new Instruction(loc, Type.LOAD_VAR, i); } - public static Instruction loadGlob() { - return new Instruction(null, Type.LOAD_GLOB); + public static Instruction loadGlob(Location loc) { + return new Instruction(loc, Type.LOAD_GLOB); } - public static Instruction loadMember() { - return new Instruction(null, Type.LOAD_MEMBER); + public static Instruction loadMember(Location loc) { + return new Instruction(loc, Type.LOAD_MEMBER); } - public static Instruction loadMember(Object key) { + public static Instruction loadMember(Location loc, Object key) { if (key instanceof Number) key = ((Number)key).doubleValue(); - return new Instruction(null, Type.LOAD_VAL_MEMBER, key); + return new Instruction(loc, Type.LOAD_VAL_MEMBER, key); } - public static Instruction loadRegex(String pattern, String flags) { - return new Instruction(null, Type.LOAD_REGEX, pattern, flags); + public static Instruction loadRegex(Location loc, String pattern, String flags) { + return new Instruction(loc, Type.LOAD_REGEX, pattern, flags); } - public static Instruction loadFunc(long id, int varN, int len, int[] captures) { - var args = new Object[3 + captures.length]; + public static Instruction loadFunc(Location loc, long id, int[] captures) { + var args = new Object[1 + captures.length]; args[0] = id; - args[1] = varN; - args[2] = len; - for (var i = 0; i < captures.length; i++) args[i + 3] = captures[i]; - return new Instruction(null, Type.LOAD_FUNC, args); + for (var i = 0; i < captures.length; i++) args[i + 1] = captures[i]; + return new Instruction(loc, Type.LOAD_FUNC, args); } - public static Instruction loadObj() { - return new Instruction(null, Type.LOAD_OBJ); + public static Instruction loadObj(Location loc) { + return new Instruction(loc, Type.LOAD_OBJ); } - public static Instruction loadArr(int count) { - return new Instruction(null, Type.LOAD_ARR, count); + public static Instruction loadArr(Location loc, int count) { + return new Instruction(loc, Type.LOAD_ARR, count); } - public static Instruction dup() { - return new Instruction(null, Type.DUP, 0, 1); + public static Instruction dup(Location loc) { + return new Instruction(loc, Type.DUP, 0, 1); } - public static Instruction dup(int count, int offset) { - return new Instruction(null, Type.DUP, offset, count); + public static Instruction dup(Location loc, int count, int offset) { + return new Instruction(loc, Type.DUP, offset, count); } - public static Instruction move(int count, int offset) { - return new Instruction(null, Type.MOVE, offset, count); + public static Instruction move(Location loc, int count, int offset) { + return new Instruction(loc, Type.MOVE, offset, count); } - public static Instruction storeSelfFunc(int i) { - return new Instruction(null, Type.STORE_SELF_FUNC, i); + public static Instruction storeSelfFunc(Location loc, int i) { + return new Instruction(loc, Type.STORE_SELF_FUNC, i); } - public static Instruction storeVar(Object i) { - return new Instruction(null, Type.STORE_VAR, i, false); + public static Instruction storeVar(Location loc, Object i) { + return new Instruction(loc, Type.STORE_VAR, i, false); } - public static Instruction storeVar(Object i, boolean keep) { - return new Instruction(null, Type.STORE_VAR, i, keep); + public static Instruction storeVar(Location loc, Object i, boolean keep) { + return new Instruction(loc, Type.STORE_VAR, i, keep); } - public static Instruction storeMember() { - return new Instruction(null, Type.STORE_MEMBER, false); + public static Instruction storeMember(Location loc) { + return new Instruction(loc, Type.STORE_MEMBER, false); } - public static Instruction storeMember(boolean keep) { - return new Instruction(null, Type.STORE_MEMBER, keep); + public static Instruction storeMember(Location loc, boolean keep) { + return new Instruction(loc, Type.STORE_MEMBER, keep); } - public static Instruction discard() { - return new Instruction(null, Type.DISCARD); + public static Instruction discard(Location loc) { + return new Instruction(loc, Type.DISCARD); } - public static Instruction typeof() { - return new Instruction(null, Type.TYPEOF); + public static Instruction typeof(Location loc) { + return new Instruction(loc, Type.TYPEOF); } - public static Instruction typeof(Object varName) { - return new Instruction(null, Type.TYPEOF, varName); + public static Instruction typeof(Location loc, Object varName) { + return new Instruction(loc, Type.TYPEOF, varName); } - public static Instruction keys(boolean forInFormat) { - return new Instruction(null, Type.KEYS, forInFormat); + public static Instruction keys(Location loc, boolean forInFormat) { + return new Instruction(loc, Type.KEYS, forInFormat); } - public static Instruction defProp() { - return new Instruction(null, Type.DEF_PROP); + public static Instruction defProp(Location loc) { + return new Instruction(loc, Type.DEF_PROP); } - public static Instruction operation(Operation op) { - return new Instruction(null, Type.OPERATION, op); + public static Instruction operation(Location loc, Operation op) { + return new Instruction(loc, Type.OPERATION, op); } @Override diff --git a/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java b/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java index c51de30..f1529f8 100644 --- a/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java +++ b/src/me/topchetoeu/jscript/compilation/VariableDeclareStatement.java @@ -34,21 +34,17 @@ public class VariableDeclareStatement extends Statement { var key = scope.getKey(entry.name); int start = target.size(); - if (key instanceof String) target.add(Instruction.makeVar((String)key).locate(entry.location)); + if (key instanceof String) target.add(Instruction.makeVar(entry.location, (String)key)); - if (entry.value instanceof FunctionStatement) { - ((FunctionStatement)entry.value).compile(target, scope, entry.name, false); - target.add(Instruction.storeVar(key).locate(entry.location)); - } - else if (entry.value != null) { - entry.value.compile(target, scope, true); - target.add(Instruction.storeVar(key).locate(entry.location)); + if (entry.value != null) { + FunctionStatement.compileWithName(entry.value, target, scope, true, entry.name); + target.add(Instruction.storeVar(entry.location, key)); } if (target.size() != start) target.setDebug(start); } - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } public VariableDeclareStatement(Location loc, List values) { diff --git a/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java b/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java index 88be1ab..c9a9f4a 100644 --- a/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/BreakStatement.java @@ -11,8 +11,8 @@ public class BreakStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.nop("break", label).locate(loc())); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + target.add(Instruction.nop(loc(), "break", label)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } 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 6828502..87b6452 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ContinueStatement.java @@ -11,8 +11,8 @@ public class ContinueStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.nop("cont", label).locate(loc())); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + target.add(Instruction.nop(loc(), "cont", label)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } 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 f98a434..bf610eb 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DebugStatement.java @@ -9,8 +9,8 @@ import me.topchetoeu.jscript.engine.scope.ScopeRecord; public class DebugStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.debug().locate(loc())); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + target.add(Instruction.debug(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } 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 526ff74..894b4ab 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DeleteStatement.java @@ -15,8 +15,8 @@ public class DeleteStatement extends Statement { value.compile(target, scope, true); key.compile(target, scope, true); - target.add(Instruction.delete().locate(loc())); - if (!pollute) target.add(Instruction.discard().locate(loc())); + target.add(Instruction.delete(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), true)); } 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 41f9dfe..b176d0d 100644 --- a/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/DoWhileStatement.java @@ -28,10 +28,10 @@ public class DoWhileStatement extends Statement { WhileStatement.replaceBreaks(target, label, start, end, end + 1, end + 1); } else { - target.add(Instruction.jmp(start - end).locate(loc())); + target.add(Instruction.jmp(loc(), start - end)); WhileStatement.replaceBreaks(target, label, start, end, start, end + 1); } - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); return; } @@ -42,7 +42,7 @@ public class DoWhileStatement extends Statement { int end = target.size(); WhileStatement.replaceBreaks(target, label, start, mid - 1, mid, end + 1); - target.add(Instruction.jmpIf(start - end).locate(loc())); + target.add(Instruction.jmpIf(loc(), start - end)); } @Override diff --git a/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java b/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java index f5d04d8..9deec5a 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ForInStatement.java @@ -25,26 +25,26 @@ public class ForInStatement extends Statement { var key = scope.getKey(varName); int first = target.size(); - if (key instanceof String) target.add(Instruction.makeVar((String)key)); + if (key instanceof String) target.add(Instruction.makeVar(loc(), (String)key)); if (varValue != null) { varValue.compile(target, scope, true); - target.add(Instruction.storeVar(scope.getKey(varName))); + target.add(Instruction.storeVar(loc(), scope.getKey(varName))); } object.compileWithDebug(target, scope, true); - target.add(Instruction.keys(true)); + target.add(Instruction.keys(loc(), true)); int start = target.size(); - target.add(Instruction.dup()); - target.add(Instruction.loadValue(null)); - target.add(Instruction.operation(Operation.EQUALS)); + target.add(Instruction.dup(loc())); + target.add(Instruction.loadValue(loc(), null)); + target.add(Instruction.operation(loc(), Operation.EQUALS)); int mid = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(loc())); - target.add(Instruction.loadMember("value").locate(varLocation)); + target.add(Instruction.loadMember(varLocation, "value")); + target.add(Instruction.storeVar(varLocation, key)); target.setDebug(); - target.add(Instruction.storeVar(key)); body.compileWithDebug(target, scope, false); @@ -52,10 +52,10 @@ public class ForInStatement extends Statement { WhileStatement.replaceBreaks(target, label, mid + 1, end, start, end + 1); - target.add(Instruction.jmp(start - end)); - target.add(Instruction.discard()); - target.set(mid, Instruction.jmpIf(end - mid + 1)); - if (pollute) target.add(Instruction.loadValue(null)); + target.add(Instruction.jmp(loc(), start - end)); + target.add(Instruction.discard(loc())); + target.set(mid, Instruction.jmpIf(loc(), end - mid + 1)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); target.get(first).locate(loc()); target.setDebug(first); } diff --git a/src/me/topchetoeu/jscript/compilation/control/ForStatement.java b/src/me/topchetoeu/jscript/compilation/control/ForStatement.java index 726e05e..fcb96e8 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ForStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ForStatement.java @@ -30,8 +30,8 @@ public class ForStatement extends Statement { 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())); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + target.add(Instruction.jmp(loc(), start - target.size())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } return; } @@ -39,7 +39,7 @@ public class ForStatement extends Statement { int start = target.size(); condition.compile(target, scope, true); int mid = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); body.compile(target, scope, false); int beforeAssign = target.size(); assignment.compileWithDebug(target, scope, false); @@ -47,9 +47,9 @@ public class ForStatement extends Statement { 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())); + target.add(Instruction.jmp(loc(), start - end)); + target.set(mid, Instruction.jmpIfNot(loc(), end - mid + 1)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } @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 96c94ac..55fca6e 100644 --- a/src/me/topchetoeu/jscript/compilation/control/IfStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/IfStatement.java @@ -36,22 +36,22 @@ public class IfStatement extends Statement { if (elseBody == null) { int i = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); body.compileWithDebug(target, scope, pollute); int endI = target.size(); - target.set(i, Instruction.jmpIfNot(endI - i).locate(loc())); + target.set(i, Instruction.jmpIfNot(loc(), endI - i)); } else { int start = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); body.compileWithDebug(target, scope, pollute); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); int mid = target.size(); elseBody.compileWithDebug(target, scope, pollute); int end = target.size(); - target.set(start, Instruction.jmpIfNot(mid - start).locate(loc())); - target.set(mid - 1, Instruction.jmp(end - mid + 1).locate(loc())); + target.set(start, Instruction.jmpIfNot(loc(), mid - start)); + target.set(mid - 1, Instruction.jmp(loc(), end - mid + 1)); } } diff --git a/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java b/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java index 896f33c..1ec792f 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ReturnStatement.java @@ -11,9 +11,9 @@ public class ReturnStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - if (value == null) target.add(Instruction.loadValue(null).locate(loc())); + if (value == null) target.add(Instruction.loadValue(loc(), null)); else value.compile(target, scope, true); - target.add(Instruction.ret().locate(loc())); + target.add(Instruction.ret(loc())); } public ReturnStatement(Location loc, Statement value) { diff --git a/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java b/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java index 9efc9e7..fab7f4d 100644 --- a/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/SwitchStatement.java @@ -39,16 +39,16 @@ public class SwitchStatement extends Statement { value.compile(target, scope, true); for (var ccase : cases) { - target.add(Instruction.dup().locate(loc())); + target.add(Instruction.dup(loc())); ccase.value.compile(target, scope, true); - target.add(Instruction.operation(Operation.EQUALS).locate(loc())); + target.add(Instruction.operation(loc(), Operation.EQUALS)); caseToStatement.put(target.size(), ccase.statementI); - target.add(Instruction.nop().locate(ccase.value.loc())); + target.add(Instruction.nop(null)); } int start = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); for (var stm : body) { statementToIndex.put(statementToIndex.size(), target.size()); @@ -56,24 +56,22 @@ public class SwitchStatement extends Statement { } int end = target.size(); - target.add(Instruction.discard().locate(loc())); - if (pollute) target.add(Instruction.loadValue(null)); + target.add(Instruction.discard(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); - if (defaultI < 0 || defaultI >= body.length) target.set(start, Instruction.jmp(end - start).locate(loc())); - else target.set(start, Instruction.jmp(statementToIndex.get(defaultI) - start)).locate(loc()); + if (defaultI < 0 || defaultI >= body.length) target.set(start, Instruction.jmp(loc(), end - start)); + else target.set(start, Instruction.jmp(loc(), statementToIndex.get(defaultI) - start)); for (int i = start; i < end; i++) { var instr = target.get(i); if (instr.type == Type.NOP && instr.is(0, "break") && instr.get(1) == null) { - target.set(i, Instruction.jmp(end - i).locate(instr.location)); + target.set(i, Instruction.jmp(loc(), end - i).locate(instr.location)); } } for (var el : caseToStatement.entrySet()) { - var loc = target.get(el.getKey()).location; var i = statementToIndex.get(el.getValue()); if (i == null) i = end; - target.set(el.getKey(), Instruction.jmpIf(i - el.getKey()).locate(loc)); - target.setDebug(el.getKey()); + target.set(el.getKey(), Instruction.jmpIf(loc(), i - el.getKey())); } } diff --git a/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java b/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java index cf424ad..5aa69ff 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/ThrowStatement.java @@ -12,7 +12,7 @@ public class ThrowStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { value.compile(target, scope, true); - target.add(Instruction.throwInstr().locate(loc())); + target.add(Instruction.throwInstr(loc())); } public ThrowStatement(Location loc, Statement value) { diff --git a/src/me/topchetoeu/jscript/compilation/control/TryStatement.java b/src/me/topchetoeu/jscript/compilation/control/TryStatement.java index 1855f1b..f85e0a6 100644 --- a/src/me/topchetoeu/jscript/compilation/control/TryStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/TryStatement.java @@ -23,7 +23,7 @@ public class TryStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); int start = target.size(), tryN, catchN = -1, finN = -1; @@ -45,8 +45,8 @@ public class TryStatement extends Statement { finN = target.size() - tmp; } - target.set(start - 1, Instruction.tryInstr(tryN, catchN, finN).locate(loc())); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + target.set(start - 1, Instruction.tryInstr(loc(), tryN, catchN, finN)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } 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 68a9e1b..40ebdf5 100644 --- a/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java +++ b/src/me/topchetoeu/jscript/compilation/control/WhileStatement.java @@ -27,7 +27,7 @@ public class WhileStatement extends Statement { 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())); + target.add(Instruction.jmp(loc(), start - target.size())); return; } } @@ -35,16 +35,16 @@ public class WhileStatement extends Statement { int start = target.size(); condition.compile(target, scope, true); int mid = target.size(); - target.add(Instruction.nop()); + target.add(Instruction.nop(null)); body.compile(target, scope, false); int end = target.size(); replaceBreaks(target, label, mid + 1, end, start, 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())); + target.add(Instruction.jmp(loc(), start - end)); + target.set(mid, Instruction.jmpIfNot(loc(), end - mid + 1)); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } @Override public Statement optimize() { @@ -71,12 +71,10 @@ public class WhileStatement extends Statement { for (int i = start; i < end; i++) { var instr = target.get(i); if (instr.type == Type.NOP && instr.is(0, "cont") && (instr.get(1) == null || instr.is(1, label))) { - target.set(i, Instruction.jmp(continuePoint - i)); - target.get(i).location = instr.location; + target.set(i, Instruction.jmp(instr.location, continuePoint - i)); } if (instr.type == Type.NOP && instr.is(0, "break") && (instr.get(1) == null || instr.is(1, label))) { - target.set(i, Instruction.jmp(breakPoint - i)); - target.get(i).location = instr.location; + target.set(i, Instruction.jmp(instr.location, breakPoint - i)); } } } diff --git a/src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java b/src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java similarity index 61% rename from src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java rename to src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java index e819baa..ead97d9 100644 --- a/src/me/topchetoeu/jscript/compilation/control/ArrayStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ArrayStatement.java @@ -1,4 +1,4 @@ -package me.topchetoeu.jscript.compilation.control; +package me.topchetoeu.jscript.compilation.values; import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.compilation.CompileTarget; @@ -14,18 +14,19 @@ public class ArrayStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.loadArr(statements.length).locate(loc())); - var i = 0; - for (var el : statements) { + target.add(Instruction.loadArr(loc(), statements.length)); + + for (var i = 0; i < statements.length; i++) { + var el = statements[i]; if (el != null) { - target.add(Instruction.dup().locate(loc())); - target.add(Instruction.loadValue(i).locate(loc())); + target.add(Instruction.dup(loc())); + target.add(Instruction.loadValue(loc(), i)); el.compile(target, scope, true); - target.add(Instruction.storeMember().locate(loc())); + target.add(Instruction.storeMember(loc())); } - i++; } - if (!pollute) target.add(Instruction.discard().locate(loc())); + + if (!pollute) target.add(Instruction.discard(loc())); } public ArrayStatement(Location loc, Statement[] statements) { diff --git a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java index a14be7d..6b00ac5 100644 --- a/src/me/topchetoeu/jscript/compilation/values/CallStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/CallStatement.java @@ -16,15 +16,15 @@ public class CallStatement extends Statement { ((IndexStatement)func).compile(target, scope, true, true); } else { - target.add(Instruction.loadValue(null).locate(loc())); + target.add(Instruction.loadValue(loc(), null)); func.compile(target, scope, true); } for (var arg : args) arg.compile(target, scope, true); - target.add(Instruction.call(args.length).locate(loc())); + target.add(Instruction.call(loc(), args.length)); target.setDebug(); - if (!pollute) target.add(Instruction.discard().locate(loc())); + if (!pollute) target.add(Instruction.discard(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 9f8db27..f6705f7 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ChangeStatement.java @@ -16,10 +16,10 @@ public class ChangeStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { value.toAssign(new ConstantStatement(loc(), -addAmount), Operation.SUBTRACT).compile(target, scope, true); - if (!pollute) target.add(Instruction.discard().locate(loc())); + if (!pollute) target.add(Instruction.discard(loc())); else if (postfix) { - target.add(Instruction.loadValue(addAmount)); - target.add(Instruction.operation(Operation.SUBTRACT)); + target.add(Instruction.loadValue(loc(), addAmount)); + target.add(Instruction.operation(loc(), Operation.SUBTRACT)); } } diff --git a/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java b/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java index f0458ae..cc042e6 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ConstantStatement.java @@ -14,7 +14,7 @@ public class ConstantStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - if (pollute) target.add(Instruction.loadValue(value).locate(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), value)); } public ConstantStatement(Location loc, Object val) { diff --git a/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java b/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java index 354d09d..2281603 100644 --- a/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/GlobalThisStatement.java @@ -12,7 +12,7 @@ public class GlobalThisStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - if (pollute) target.add(Instruction.loadGlob().locate(loc())); + if (pollute) target.add(Instruction.loadGlob(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 2cf8b00..7782d84 100644 --- a/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/IndexAssignStatement.java @@ -18,13 +18,13 @@ public class IndexAssignStatement extends Statement { if (operation != null) { object.compile(target, scope, true); index.compile(target, scope, true); - target.add(Instruction.dup(2, 0).locate(loc())); + target.add(Instruction.dup(loc(), 2, 0)); - target.add(Instruction.loadMember().locate(loc())); + target.add(Instruction.loadMember(loc())); value.compile(target, scope, true); - target.add(Instruction.operation(operation).locate(loc())); + target.add(Instruction.operation(loc(), operation)); - target.add(Instruction.storeMember(pollute).locate(loc())); + target.add(Instruction.storeMember(loc(), pollute)); target.setDebug(); } else { @@ -32,7 +32,7 @@ public class IndexAssignStatement extends Statement { index.compile(target, scope, true); value.compile(target, scope, true); - target.add(Instruction.storeMember(pollute).locate(loc())); + target.add(Instruction.storeMember(loc(), pollute)); target.setDebug(); } } diff --git a/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java b/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java index b821cd0..1f02b86 100644 --- a/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/IndexStatement.java @@ -21,17 +21,17 @@ public class IndexStatement extends AssignableStatement { } public void compile(CompileTarget target, ScopeRecord scope, boolean dupObj, boolean pollute) { object.compile(target, scope, true); - if (dupObj) target.add(Instruction.dup().locate(loc())); + if (dupObj) target.add(Instruction.dup(loc())); if (index instanceof ConstantStatement) { - target.add(Instruction.loadMember(((ConstantStatement)index).value).locate(loc())); + target.add(Instruction.loadMember(loc(), ((ConstantStatement)index).value)); target.setDebug(); return; } index.compile(target, scope, true); - target.add(Instruction.loadMember().locate(loc())); + target.add(Instruction.loadMember(loc())); target.setDebug(); - if (!pollute) target.add(Instruction.discard().locate(loc())); + if (!pollute) target.add(Instruction.discard(loc())); } @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { diff --git a/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java b/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java index fea8de5..36c4f6b 100644 --- a/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/LazyAndStatement.java @@ -26,12 +26,12 @@ public class LazyAndStatement extends Statement { } first.compile(target, scope, true); - if (pollute) target.add(Instruction.dup().locate(loc())); + if (pollute) target.add(Instruction.dup(loc())); int start = target.size(); - target.add(Instruction.nop()); - if (pollute) target.add(Instruction.discard().locate(loc())); + target.add(Instruction.nop(null)); + if (pollute) target.add(Instruction.discard(loc())); second.compile(target, scope, pollute); - target.set(start, Instruction.jmpIfNot(target.size() - start).locate(loc())); + target.set(start, Instruction.jmpIfNot(loc(), target.size() - start)); } public LazyAndStatement(Location loc, Statement first, Statement second) { diff --git a/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java b/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java index 3e896dd..dc0eefa 100644 --- a/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/LazyOrStatement.java @@ -26,12 +26,12 @@ public class LazyOrStatement extends Statement { } first.compile(target, scope, true); - if (pollute) target.add(Instruction.dup().locate(loc())); + if (pollute) target.add(Instruction.dup(loc())); int start = target.size(); - target.add(Instruction.nop()); - if (pollute) target.add(Instruction.discard().locate(loc())); + target.add(Instruction.nop(null)); + if (pollute) target.add(Instruction.discard(loc())); second.compile(target, scope, pollute); - target.set(start, Instruction.jmpIf(target.size() - start).locate(loc())); + target.set(start, Instruction.jmpIf(loc(), target.size() - start)); } public LazyOrStatement(Location loc, Statement first, Statement second) { diff --git a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java index d60ef3a..d52b542 100644 --- a/src/me/topchetoeu/jscript/compilation/values/NewStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/NewStatement.java @@ -16,7 +16,7 @@ public class NewStatement extends Statement { for (var arg : args) arg.compile(target, scope, true); - target.add(Instruction.callNew(args.length).locate(loc())); + target.add(Instruction.callNew(loc(), args.length)); target.setDebug(); } diff --git a/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java b/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java index abcec8d..f600f30 100644 --- a/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/ObjectStatement.java @@ -16,15 +16,14 @@ public class ObjectStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.loadObj().locate(loc())); + target.add(Instruction.loadObj(loc())); for (var el : map.entrySet()) { - target.add(Instruction.dup().locate(loc())); - target.add(Instruction.loadValue(el.getKey()).locate(loc())); + target.add(Instruction.dup(loc())); + target.add(Instruction.loadValue(loc(), el.getKey())); var val = el.getValue(); - if (val instanceof FunctionStatement) ((FunctionStatement)val).compile(target, scope, el.getKey().toString(), false); - else val.compile(target, scope, true); - target.add(Instruction.storeMember().locate(loc())); + FunctionStatement.compileWithName(val, target, scope, true, el.getKey().toString()); + target.add(Instruction.storeMember(loc())); } var keys = new ArrayList(); @@ -32,19 +31,19 @@ public class ObjectStatement extends Statement { keys.addAll(setters.keySet()); for (var key : keys) { - if (key instanceof String) target.add(Instruction.loadValue((String)key).locate(loc())); - else target.add(Instruction.loadValue((Double)key).locate(loc())); + if (key instanceof String) target.add(Instruction.loadValue(loc(), (String)key)); + else target.add(Instruction.loadValue(loc(), (Double)key)); if (getters.containsKey(key)) getters.get(key).compile(target, scope, true); - else target.add(Instruction.loadValue(null).locate(loc())); + else target.add(Instruction.loadValue(loc(), null)); if (setters.containsKey(key)) setters.get(key).compile(target, scope, true); - else target.add(Instruction.loadValue(null).locate(loc())); + else target.add(Instruction.loadValue(loc(), null)); - target.add(Instruction.defProp().locate(loc())); + target.add(Instruction.defProp(loc())); } - if (!pollute) target.add(Instruction.discard().locate(loc())); + if (!pollute) target.add(Instruction.discard(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 97479bd..6b426fc 100644 --- a/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/OperationStatement.java @@ -20,8 +20,8 @@ public class OperationStatement extends Statement { arg.compile(target, scope, true); } - if (pollute) target.add(Instruction.operation(operation).locate(loc())); - else target.add(Instruction.discard().locate(loc())); + if (pollute) target.add(Instruction.operation(loc(), operation)); + else target.add(Instruction.discard(loc())); } @Override diff --git a/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java b/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java index 26f83b4..ce41f4f 100644 --- a/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/RegexStatement.java @@ -14,8 +14,8 @@ public class RegexStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - target.add(Instruction.loadRegex(pattern, flags).locate(loc())); - if (!pollute) target.add(Instruction.discard().locate(loc())); + target.add(Instruction.loadRegex(loc(), pattern, flags)); + if (!pollute) target.add(Instruction.discard(loc())); } public RegexStatement(Location loc, String pattern, String flags) { diff --git a/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java b/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java index 41eb2a1..0206405 100644 --- a/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/TypeofStatement.java @@ -4,7 +4,6 @@ import me.topchetoeu.jscript.Location; import me.topchetoeu.jscript.compilation.CompileTarget; 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; @@ -19,12 +18,12 @@ public class TypeofStatement extends Statement { if (value instanceof VariableStatement) { var i = scope.getKey(((VariableStatement)value).name); if (i instanceof String) { - target.add(Instruction.typeof((String)i).locate(loc())); + target.add(Instruction.typeof(loc(), (String)i)); return; } } value.compile(target, scope, pollute); - target.add(Instruction.typeof().locate(loc())); + target.add(Instruction.typeof(loc())); } @Override diff --git a/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java b/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java index 28f46e9..00204bf 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableAssignStatement.java @@ -16,16 +16,14 @@ public class VariableAssignStatement extends Statement { public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { var i = scope.getKey(name); if (operation != null) { - target.add(Instruction.loadVar(i).locate(loc())); - if (value instanceof FunctionStatement) ((FunctionStatement)value).compile(target, scope, name, false); - else value.compile(target, scope, true); - target.add(Instruction.operation(operation).locate(loc())); - target.add(Instruction.storeVar(i, pollute).locate(loc())); + target.add(Instruction.loadVar(loc(), i)); + FunctionStatement.compileWithName(value, target, scope, true, name); + target.add(Instruction.operation(loc(), operation)); + target.add(Instruction.storeVar(loc(), i, pollute)); } else { - if (value instanceof FunctionStatement) ((FunctionStatement)value).compile(target, scope, name, false); - else value.compile(target, scope, true); - target.add(Instruction.storeVar(i, pollute).locate(loc())); + FunctionStatement.compileWithName(value, target, scope, true, name); + target.add(Instruction.storeVar(loc(), i, pollute)); } } diff --git a/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java b/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java index a916407..ed73475 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableIndexStatement.java @@ -14,7 +14,7 @@ public class VariableIndexStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { - if (pollute) target.add(Instruction.loadVar(index).locate(loc())); + if (pollute) target.add(Instruction.loadVar(loc(), index)); } 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 947d029..d18411d 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VariableStatement.java @@ -22,8 +22,8 @@ public class VariableStatement extends AssignableStatement { @Override public void compile(CompileTarget 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())); + target.add(Instruction.loadVar(loc(), i)); + if (!pollute) target.add(Instruction.discard(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 fbf0b63..7c21bae 100644 --- a/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java +++ b/src/me/topchetoeu/jscript/compilation/values/VoidStatement.java @@ -12,7 +12,7 @@ public class VoidStatement extends Statement { @Override public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) { if (value != null) value.compile(target, scope, false); - if (pollute) target.add(Instruction.loadValue(null).locate(loc())); + if (pollute) target.add(Instruction.loadValue(loc(), null)); } @Override