Add support for source mappings #10

Merged
TopchetoEU merged 22 commits from TopchetoEU/mapping into master 2023-12-18 20:42:38 +00:00
35 changed files with 210 additions and 219 deletions
Showing only changes of commit d5e6edfa8b - Show all commits

View File

@ -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); }

View File

@ -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();
}
}

View File

@ -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

View File

@ -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<Pair> values) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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);
}

View File

@ -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() {

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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()));
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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));
}
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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();
}

View File

@ -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<Object>();
@ -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<Object, Statement> map, Map<Object, FunctionStatement> getters, Map<Object, FunctionStatement> setters) {

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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));
}
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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