Merge pull request #6 from TopchetoEU/TopchetoEU/function-optimizations
Cache function bodies
This commit is contained in:
commit
005610ca40
27
src/me/topchetoeu/jscript/compilation/CompileTarget.java
Normal file
27
src/me/topchetoeu/jscript/compilation/CompileTarget.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class CompileTarget {
|
||||||
|
public final Vector<Instruction> target = new Vector<>();
|
||||||
|
public final Map<Long, Instruction[]> functions;
|
||||||
|
|
||||||
|
public Instruction add(Instruction instr) {
|
||||||
|
target.add(instr);
|
||||||
|
return instr;
|
||||||
|
}
|
||||||
|
public Instruction set(int i, Instruction instr) {
|
||||||
|
return target.set(i, instr);
|
||||||
|
}
|
||||||
|
public Instruction get(int i) {
|
||||||
|
return target.get(i);
|
||||||
|
}
|
||||||
|
public int size() { return target.size(); }
|
||||||
|
|
||||||
|
public Instruction[] array() { return target.toArray(Instruction[]::new); }
|
||||||
|
|
||||||
|
public CompileTarget(Map<Long, Instruction[]> functions) {
|
||||||
|
this.functions = functions;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Vector;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.control.ContinueStatement;
|
import me.topchetoeu.jscript.compilation.control.ContinueStatement;
|
||||||
@ -21,7 +20,7 @@ public class CompoundStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
for (var stm : statements) {
|
for (var stm : statements) {
|
||||||
if (stm instanceof FunctionStatement) {
|
if (stm instanceof FunctionStatement) {
|
||||||
int start = target.size();
|
int start = target.size();
|
||||||
@ -42,7 +41,7 @@ public class CompoundStatement extends Statement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement optimize() {
|
public Statement optimize() {
|
||||||
var res = new ArrayList<Statement>();
|
var res = new Vector<Statement>(statements.length);
|
||||||
|
|
||||||
for (var i = 0; i < statements.length; i++) {
|
for (var i = 0; i < statements.length; i++) {
|
||||||
var stm = statements[i].optimize();
|
var stm = statements[i].optimize();
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.values.ConstantStatement;
|
import me.topchetoeu.jscript.compilation.values.ConstantStatement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -10,7 +8,7 @@ public class DiscardStatement extends Statement {
|
|||||||
public final Statement value;
|
public final Statement value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
value.compile(target, scope, false);
|
value.compile(target, scope, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -214,9 +214,9 @@ public class Instruction {
|
|||||||
public static Instruction loadRegex(String pattern, String flags) {
|
public static Instruction loadRegex(String pattern, String flags) {
|
||||||
return new Instruction(null, Type.LOAD_REGEX, pattern, flags);
|
return new Instruction(null, Type.LOAD_REGEX, pattern, flags);
|
||||||
}
|
}
|
||||||
public static Instruction loadFunc(int instrN, int varN, int len, int[] captures) {
|
public static Instruction loadFunc(long id, int varN, int len, int[] captures) {
|
||||||
var args = new Object[3 + captures.length];
|
var args = new Object[3 + captures.length];
|
||||||
args[0] = instrN;
|
args[0] = id;
|
||||||
args[1] = varN;
|
args[1] = varN;
|
||||||
args[2] = len;
|
args[2] = len;
|
||||||
for (var i = 0; i < captures.length; i++) args[i + 3] = captures[i];
|
for (var i = 0; i < captures.length; i++) args[i + 3] = captures[i];
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package me.topchetoeu.jscript.compilation;
|
package me.topchetoeu.jscript.compilation;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
|
|
||||||
@ -9,11 +7,11 @@ public abstract class Statement {
|
|||||||
private Location _loc;
|
private Location _loc;
|
||||||
|
|
||||||
public boolean pure() { return false; }
|
public boolean pure() { return false; }
|
||||||
public abstract void compile(List<Instruction> target, ScopeRecord scope, boolean pollute);
|
public abstract void compile(CompileTarget target, ScopeRecord scope, boolean pollute);
|
||||||
public void declare(ScopeRecord varsScope) { }
|
public void declare(ScopeRecord varsScope) { }
|
||||||
public Statement optimize() { return this; }
|
public Statement optimize() { return this; }
|
||||||
|
|
||||||
public void compileWithDebug(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compileWithDebug(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
int start = target.size();
|
int start = target.size();
|
||||||
compile(target, scope, pollute);
|
compile(target, scope, pollute);
|
||||||
if (target.size() != start) target.get(start).setDebug(true);
|
if (target.size() != start) target.get(start).setDebug(true);
|
||||||
|
@ -26,7 +26,7 @@ public class VariableDeclareStatement extends Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
for (var entry : values) {
|
for (var entry : values) {
|
||||||
if (entry.name == null) continue;
|
if (entry.name == null) continue;
|
||||||
var key = scope.getKey(entry.name);
|
var key = scope.getKey(entry.name);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -14,7 +13,7 @@ public class ArrayStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.loadArr(statements.length).locate(loc()));
|
target.add(Instruction.loadArr(statements.length).locate(loc()));
|
||||||
var i = 0;
|
var i = 0;
|
||||||
for (var el : statements) {
|
for (var el : statements) {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -11,7 +10,7 @@ public class BreakStatement extends Statement {
|
|||||||
public final String label;
|
public final String label;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.nop("break", label).locate(loc()));
|
target.add(Instruction.nop("break", label).locate(loc()));
|
||||||
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -11,7 +10,7 @@ public class ContinueStatement extends Statement {
|
|||||||
public final String label;
|
public final String label;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.nop("cont", label).locate(loc()));
|
target.add(Instruction.nop("cont", label).locate(loc()));
|
||||||
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
|
|
||||||
public class DebugStatement extends Statement {
|
public class DebugStatement extends Statement {
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.debug().locate(loc()));
|
target.add(Instruction.debug().locate(loc()));
|
||||||
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -12,7 +11,7 @@ public class DeleteStatement extends Statement {
|
|||||||
public final Statement value;
|
public final Statement value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
value.compile(target, scope, true);
|
value.compile(target, scope, true);
|
||||||
key.compile(target, scope, true);
|
key.compile(target, scope, true);
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
@ -20,7 +19,7 @@ public class DoWhileStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (condition instanceof ConstantStatement) {
|
if (condition instanceof ConstantStatement) {
|
||||||
int start = target.size();
|
int start = target.size();
|
||||||
body.compile(target, scope, false);
|
body.compile(target, scope, false);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
@ -21,7 +20,7 @@ public class ForInStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
var key = scope.getKey(varName);
|
var key = scope.getKey(varName);
|
||||||
if (key instanceof String) target.add(Instruction.makeVar((String)key));
|
if (key instanceof String) target.add(Instruction.makeVar((String)key));
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.values.ConstantStatement;
|
import me.topchetoeu.jscript.compilation.values.ConstantStatement;
|
||||||
@ -20,7 +19,7 @@ public class ForStatement extends Statement {
|
|||||||
body.declare(globScope);
|
body.declare(globScope);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
declaration.compile(target, scope, false);
|
declaration.compile(target, scope, false);
|
||||||
|
|
||||||
if (condition instanceof ConstantStatement) {
|
if (condition instanceof ConstantStatement) {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.DiscardStatement;
|
import me.topchetoeu.jscript.compilation.DiscardStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
@ -21,7 +20,7 @@ public class IfStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (condition instanceof ConstantStatement) {
|
if (condition instanceof ConstantStatement) {
|
||||||
if (Values.not(((ConstantStatement)condition).value)) {
|
if (Values.not(((ConstantStatement)condition).value)) {
|
||||||
if (elseBody != null) elseBody.compileWithDebug(target, scope, pollute);
|
if (elseBody != null) elseBody.compileWithDebug(target, scope, pollute);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -11,7 +10,7 @@ public class ReturnStatement extends Statement {
|
|||||||
public final Statement value;
|
public final Statement value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
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(null).locate(loc()));
|
||||||
else value.compile(target, scope, true);
|
else value.compile(target, scope, true);
|
||||||
target.add(Instruction.ret().locate(loc()));
|
target.add(Instruction.ret().locate(loc()));
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction.Type;
|
import me.topchetoeu.jscript.compilation.Instruction.Type;
|
||||||
@ -32,7 +32,7 @@ public class SwitchStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
var caseMap = new HashMap<Integer, Integer>();
|
var caseMap = new HashMap<Integer, Integer>();
|
||||||
var stmIndexMap = new HashMap<Integer, Integer>();
|
var stmIndexMap = new HashMap<Integer, Integer>();
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -11,7 +10,7 @@ public class ThrowStatement extends Statement {
|
|||||||
public final Statement value;
|
public final Statement value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
value.compile(target, scope, true);
|
value.compile(target, scope, true);
|
||||||
target.add(Instruction.throwInstr().locate(loc()));
|
target.add(Instruction.throwInstr().locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||||
@ -23,7 +22,7 @@ public class TryStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.nop());
|
target.add(Instruction.nop());
|
||||||
|
|
||||||
int start = target.size(), tryN, catchN = -1, finN = -1;
|
int start = target.size(), tryN, catchN = -1, finN = -1;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.control;
|
package me.topchetoeu.jscript.compilation.control;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.DiscardStatement;
|
import me.topchetoeu.jscript.compilation.DiscardStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
@ -21,7 +20,7 @@ public class WhileStatement extends Statement {
|
|||||||
body.declare(globScope);
|
body.declare(globScope);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (condition instanceof ConstantStatement) {
|
if (condition instanceof ConstantStatement) {
|
||||||
if (Values.toBoolean(((ConstantStatement)condition).value)) {
|
if (Values.toBoolean(((ConstantStatement)condition).value)) {
|
||||||
int start = target.size();
|
int start = target.size();
|
||||||
@ -68,7 +67,7 @@ public class WhileStatement extends Statement {
|
|||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void replaceBreaks(List<Instruction> target, String label, int start, int end, int continuePoint, int breakPoint) {
|
public static void replaceBreaks(CompileTarget target, String label, int start, int end, int continuePoint, int breakPoint) {
|
||||||
for (int i = start; i < end; i++) {
|
for (int i = start; i < end; i++) {
|
||||||
var instr = target.get(i);
|
var instr = target.get(i);
|
||||||
if (instr.type == Type.NOP && instr.is(0, "cont") && (instr.get(1) == null || instr.is(1, label))) {
|
if (instr.type == Type.NOP && instr.is(0, "cont") && (instr.get(1) == null || instr.is(1, label))) {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -12,7 +11,7 @@ public class CallStatement extends Statement {
|
|||||||
public final Statement[] args;
|
public final Statement[] args;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (func instanceof IndexStatement) {
|
if (func instanceof IndexStatement) {
|
||||||
((IndexStatement)func).compile(target, scope, true, true);
|
((IndexStatement)func).compile(target, scope, true, true);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
@ -15,7 +14,7 @@ public class ChangeStatement extends Statement {
|
|||||||
public final boolean postfix;
|
public final boolean postfix;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
value.toAssign(new ConstantStatement(loc(), -addAmount), Operation.SUBTRACT).compile(target, scope, postfix);
|
value.toAssign(new ConstantStatement(loc(), -addAmount), Operation.SUBTRACT).compile(target, scope, postfix);
|
||||||
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -14,7 +13,7 @@ public class ConstantStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (pollute) target.add(Instruction.loadValue(value).locate(loc()));
|
if (pollute) target.add(Instruction.loadValue(value).locate(loc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Random;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
import me.topchetoeu.jscript.compilation.CompoundStatement;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
@ -15,6 +16,8 @@ public class FunctionStatement extends Statement {
|
|||||||
public final String name;
|
public final String name;
|
||||||
public final String[] args;
|
public final String[] args;
|
||||||
|
|
||||||
|
private static Random rand = new Random();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pure() { return name == null; }
|
public boolean pure() { return name == null; }
|
||||||
|
|
||||||
@ -23,7 +26,7 @@ public class FunctionStatement extends Statement {
|
|||||||
if (name != null) scope.define(name);
|
if (name != null) scope.define(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkBreakAndCont(List<Instruction> target, int start) {
|
public static void checkBreakAndCont(CompileTarget target, int start) {
|
||||||
for (int i = start; i < target.size(); i++) {
|
for (int i = start; i < target.size(); i++) {
|
||||||
if (target.get(i).type == Type.NOP) {
|
if (target.get(i).type == Type.NOP) {
|
||||||
if (target.get(i).is(0, "break") ) {
|
if (target.get(i).is(0, "break") ) {
|
||||||
@ -36,7 +39,7 @@ public class FunctionStatement extends Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, String name, boolean isStatement) {
|
public void compile(CompileTarget target, ScopeRecord scope, String name, boolean isStatement) {
|
||||||
for (var i = 0; i < args.length; i++) {
|
for (var i = 0; i < args.length; i++) {
|
||||||
for (var j = 0; j < i; j++) {
|
for (var j = 0; j < i; j++) {
|
||||||
if (args[i].equals(args[j])){
|
if (args[i].equals(args[j])){
|
||||||
@ -48,32 +51,33 @@ public class FunctionStatement extends Statement {
|
|||||||
var subscope = scope.child();
|
var subscope = scope.child();
|
||||||
|
|
||||||
int start = target.size();
|
int start = target.size();
|
||||||
|
var funcTarget = new CompileTarget(target.functions);
|
||||||
|
|
||||||
target.add(Instruction.nop());
|
|
||||||
subscope.define("this");
|
subscope.define("this");
|
||||||
var argsVar = subscope.define("arguments");
|
var argsVar = subscope.define("arguments");
|
||||||
|
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
for (var i = 0; i < args.length; i++) {
|
for (var i = 0; i < args.length; i++) {
|
||||||
target.add(Instruction.loadVar(argsVar).locate(loc()));
|
funcTarget.add(Instruction.loadVar(argsVar).locate(loc()));
|
||||||
target.add(Instruction.loadMember(i).locate(loc()));
|
funcTarget.add(Instruction.loadMember(i).locate(loc()));
|
||||||
target.add(Instruction.storeVar(subscope.define(args[i])).locate(loc()));
|
funcTarget.add(Instruction.storeVar(subscope.define(args[i])).locate(loc()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isStatement && this.name != null) {
|
if (!isStatement && this.name != null) {
|
||||||
target.add(Instruction.storeSelfFunc((int)subscope.define(this.name)));
|
funcTarget.add(Instruction.storeSelfFunc((int)subscope.define(this.name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
body.declare(subscope);
|
body.declare(subscope);
|
||||||
target.add(Instruction.debugVarNames(subscope.locals()));
|
funcTarget.add(Instruction.debugVarNames(subscope.locals()));
|
||||||
body.compile(target, subscope, false);
|
body.compile(funcTarget, subscope, false);
|
||||||
|
funcTarget.add(Instruction.ret().locate(loc()));
|
||||||
|
checkBreakAndCont(funcTarget, start);
|
||||||
|
|
||||||
checkBreakAndCont(target, start);
|
var id = rand.nextLong();
|
||||||
|
|
||||||
if (!(body instanceof CompoundStatement)) target.add(Instruction.ret().locate(loc()));
|
target.add(Instruction.loadFunc(id, subscope.localsCount(), args.length, subscope.getCaptures()).locate(loc()));
|
||||||
|
target.functions.put(id, funcTarget.array());
|
||||||
target.set(start, Instruction.loadFunc(target.size() - start, subscope.localsCount(), args.length, subscope.getCaptures()).locate(loc()));
|
|
||||||
|
|
||||||
if (name == null) name = this.name;
|
if (name == null) name = this.name;
|
||||||
|
|
||||||
@ -90,9 +94,10 @@ public class FunctionStatement extends Statement {
|
|||||||
if (key instanceof String) target.add(Instruction.makeVar((String)key).locate(loc()));
|
if (key instanceof String) target.add(Instruction.makeVar((String)key).locate(loc()));
|
||||||
target.add(Instruction.storeVar(scope.getKey(this.name), false).locate(loc()));
|
target.add(Instruction.storeVar(scope.getKey(this.name), false).locate(loc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
compile(target, scope, null, false);
|
compile(target, scope, null, false);
|
||||||
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
|
|
||||||
@ -12,7 +11,7 @@ public class GlobalThisStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (pollute) target.add(Instruction.loadGlob().locate(loc()));
|
if (pollute) target.add(Instruction.loadGlob().locate(loc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
@ -15,7 +14,7 @@ public class IndexAssignStatement extends Statement {
|
|||||||
public final Operation operation;
|
public final Operation operation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (operation != null) {
|
if (operation != null) {
|
||||||
object.compile(target, scope, true);
|
object.compile(target, scope, true);
|
||||||
index.compile(target, scope, true);
|
index.compile(target, scope, true);
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
@ -20,7 +19,7 @@ public class IndexStatement extends AssignableStatement {
|
|||||||
public Statement toAssign(Statement val, Operation operation) {
|
public Statement toAssign(Statement val, Operation operation) {
|
||||||
return new IndexAssignStatement(loc(), object, index, val, operation);
|
return new IndexAssignStatement(loc(), object, index, val, operation);
|
||||||
}
|
}
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean dupObj, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean dupObj, boolean pollute) {
|
||||||
int start = 0;
|
int start = 0;
|
||||||
object.compile(target, scope, true);
|
object.compile(target, scope, true);
|
||||||
if (dupObj) target.add(Instruction.dup().locate(loc()));
|
if (dupObj) target.add(Instruction.dup().locate(loc()));
|
||||||
@ -35,7 +34,7 @@ public class IndexStatement extends AssignableStatement {
|
|||||||
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
compile(target, scope, false, pollute);
|
compile(target, scope, false, pollute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -17,7 +16,7 @@ public class LazyAndStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (first instanceof ConstantStatement) {
|
if (first instanceof ConstantStatement) {
|
||||||
if (Values.not(((ConstantStatement)first).value)) {
|
if (Values.not(((ConstantStatement)first).value)) {
|
||||||
first.compile(target, scope, pollute);
|
first.compile(target, scope, pollute);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -17,7 +16,7 @@ public class LazyOrStatement extends Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (first instanceof ConstantStatement) {
|
if (first instanceof ConstantStatement) {
|
||||||
if (Values.not(((ConstantStatement)first).value)) {
|
if (Values.not(((ConstantStatement)first).value)) {
|
||||||
second.compile(target, scope, pollute);
|
second.compile(target, scope, pollute);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -12,7 +11,7 @@ public class NewStatement extends Statement {
|
|||||||
public final Statement[] args;
|
public final Statement[] args;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
func.compile(target, scope, true);
|
func.compile(target, scope, true);
|
||||||
|
|
||||||
for (var arg : args) arg.compile(target, scope, true);
|
for (var arg : args) arg.compile(target, scope, true);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -15,7 +15,7 @@ public class ObjectStatement extends Statement {
|
|||||||
public final Map<Object, FunctionStatement> setters;
|
public final Map<Object, FunctionStatement> setters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.loadObj().locate(loc()));
|
target.add(Instruction.loadObj().locate(loc()));
|
||||||
|
|
||||||
for (var el : map.entrySet()) {
|
for (var el : map.entrySet()) {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.control.ThrowStatement;
|
import me.topchetoeu.jscript.compilation.control.ThrowStatement;
|
||||||
@ -16,7 +15,7 @@ public class OperationStatement extends Statement {
|
|||||||
public final Operation operation;
|
public final Operation operation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
for (var arg : args) {
|
for (var arg : args) {
|
||||||
arg.compile(target, scope, true);
|
arg.compile(target, scope, true);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -14,7 +13,7 @@ public class RegexStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
target.add(Instruction.loadRegex(pattern, flags).locate(loc()));
|
target.add(Instruction.loadRegex(pattern, flags).locate(loc()));
|
||||||
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.compilation.control.ArrayStatement;
|
import me.topchetoeu.jscript.compilation.control.ArrayStatement;
|
||||||
@ -16,7 +15,7 @@ public class TypeofStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (value instanceof VariableStatement) {
|
if (value instanceof VariableStatement) {
|
||||||
var i = scope.getKey(((VariableStatement)value).name);
|
var i = scope.getKey(((VariableStatement)value).name);
|
||||||
if (i instanceof String) {
|
if (i instanceof String) {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
@ -14,7 +13,7 @@ public class VariableAssignStatement extends Statement {
|
|||||||
public final Operation operation;
|
public final Operation operation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
var i = scope.getKey(name);
|
var i = scope.getKey(name);
|
||||||
if (operation != null) {
|
if (operation != null) {
|
||||||
target.add(Instruction.loadVar(i).locate(loc()));
|
target.add(Instruction.loadVar(i).locate(loc()));
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ public class VariableIndexStatement extends Statement {
|
|||||||
public boolean pure() { return true; }
|
public boolean pure() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (pollute) target.add(Instruction.loadVar(index).locate(loc()));
|
if (pollute) target.add(Instruction.loadVar(index).locate(loc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
import me.topchetoeu.jscript.compilation.AssignableStatement;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.Operation;
|
import me.topchetoeu.jscript.engine.Operation;
|
||||||
@ -21,7 +20,7 @@ public class VariableStatement extends AssignableStatement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
var i = scope.getKey(name);
|
var i = scope.getKey(name);
|
||||||
target.add(Instruction.loadVar(i).locate(loc()));
|
target.add(Instruction.loadVar(i).locate(loc()));
|
||||||
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
if (!pollute) target.add(Instruction.discard().locate(loc()));
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
package me.topchetoeu.jscript.compilation.values;
|
package me.topchetoeu.jscript.compilation.values;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import me.topchetoeu.jscript.Location;
|
import me.topchetoeu.jscript.Location;
|
||||||
import me.topchetoeu.jscript.compilation.Statement;
|
import me.topchetoeu.jscript.compilation.Statement;
|
||||||
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
import me.topchetoeu.jscript.engine.scope.ScopeRecord;
|
||||||
|
import me.topchetoeu.jscript.compilation.CompileTarget;
|
||||||
import me.topchetoeu.jscript.compilation.Instruction;
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
|
|
||||||
public class VoidStatement extends Statement {
|
public class VoidStatement extends Statement {
|
||||||
public final Statement value;
|
public final Statement value;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(List<Instruction> target, ScopeRecord scope, boolean pollute) {
|
public void compile(CompileTarget target, ScopeRecord scope, boolean pollute) {
|
||||||
if (value != null) value.compile(target, scope, false);
|
if (value != null) value.compile(target, scope, false);
|
||||||
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
if (pollute) target.add(Instruction.loadValue(null).locate(loc()));
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ public class Context {
|
|||||||
|
|
||||||
public FunctionValue compile(String filename, String raw) throws InterruptedException {
|
public FunctionValue compile(String filename, String raw) throws InterruptedException {
|
||||||
var res = Values.toString(this, env.compile.call(this, null, raw, filename));
|
var res = Values.toString(this, env.compile.call(this, null, raw, filename));
|
||||||
return Parsing.compile(env, filename, res);
|
return Parsing.compile(message.engine.functions, env, filename, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context setEnv(Environment env) {
|
public Context setEnv(Environment env) {
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package me.topchetoeu.jscript.engine;
|
package me.topchetoeu.jscript.engine;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.compilation.Instruction;
|
||||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||||
import me.topchetoeu.jscript.events.Awaitable;
|
import me.topchetoeu.jscript.events.Awaitable;
|
||||||
import me.topchetoeu.jscript.events.DataNotifier;
|
import me.topchetoeu.jscript.events.DataNotifier;
|
||||||
@ -49,6 +51,7 @@ public class Engine {
|
|||||||
private LinkedBlockingDeque<Task> microTasks = new LinkedBlockingDeque<>();
|
private LinkedBlockingDeque<Task> microTasks = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
public final int id = ++nextId;
|
public final int id = ++nextId;
|
||||||
|
public final HashMap<Long, Instruction[]> functions = new HashMap<>();
|
||||||
|
|
||||||
private void runTask(Task task) throws InterruptedException {
|
private void runTask(Task task) throws InterruptedException {
|
||||||
try {
|
try {
|
||||||
|
@ -182,7 +182,7 @@ public class Runners {
|
|||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadFunc(Context ctx, Instruction instr, CodeFrame frame) {
|
public static Object execLoadFunc(Context ctx, Instruction instr, CodeFrame frame) {
|
||||||
int n = (Integer)instr.get(0);
|
long id = (Long)instr.get(0);
|
||||||
int localsN = (Integer)instr.get(1);
|
int localsN = (Integer)instr.get(1);
|
||||||
int len = (Integer)instr.get(2);
|
int len = (Integer)instr.get(2);
|
||||||
var captures = new ValueVariable[instr.params.length - 3];
|
var captures = new ValueVariable[instr.params.length - 3];
|
||||||
@ -191,15 +191,12 @@ public class Runners {
|
|||||||
captures[i - 3] = frame.scope.get(instr.get(i));
|
captures[i - 3] = frame.scope.get(instr.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = frame.codePtr + 1;
|
var body = ctx.message.engine.functions.get(id);
|
||||||
var end = start + n - 1;
|
|
||||||
var body = new Instruction[end - start];
|
|
||||||
System.arraycopy(frame.function.body, start, body, 0, end - start);
|
|
||||||
|
|
||||||
var func = new CodeFunction(ctx.env, "", localsN, len, captures, body);
|
var func = new CodeFunction(ctx.env, "", localsN, len, captures, body);
|
||||||
|
|
||||||
frame.push(ctx, func);
|
frame.push(ctx, func);
|
||||||
|
|
||||||
frame.codePtr += n;
|
frame.codePtr++;
|
||||||
return NO_RETURN;
|
return NO_RETURN;
|
||||||
}
|
}
|
||||||
public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
public static Object execLoadMember(Context ctx, Instruction instr, CodeFrame frame) throws InterruptedException {
|
||||||
|
@ -2,6 +2,7 @@ package me.topchetoeu.jscript.parsing;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -39,6 +40,8 @@ public class Parsing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final HashMap<Long, ArrayList<Instruction>> functions = new HashMap<>();
|
||||||
|
|
||||||
private static final HashSet<String> reserved = new HashSet<String>();
|
private static final HashSet<String> reserved = new HashSet<String>();
|
||||||
static {
|
static {
|
||||||
reserved.add("true");
|
reserved.add("true");
|
||||||
@ -1871,12 +1874,11 @@ public class Parsing {
|
|||||||
return list.toArray(Statement[]::new);
|
return list.toArray(Statement[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CodeFunction compile(Environment environment, Statement ...statements) {
|
public static CodeFunction compile(HashMap<Long, Instruction[]> funcs, Environment environment, Statement ...statements) {
|
||||||
var target = environment.global.globalChild();
|
var target = environment.global.globalChild();
|
||||||
var subscope = target.child();
|
var subscope = target.child();
|
||||||
var res = new ArrayList<Instruction>();
|
var res = new CompileTarget(funcs);
|
||||||
var body = new CompoundStatement(null, statements);
|
var body = new CompoundStatement(null, statements);
|
||||||
// var optimized = body.optimize();
|
|
||||||
if (body instanceof CompoundStatement) body = (CompoundStatement)body;
|
if (body instanceof CompoundStatement) body = (CompoundStatement)body;
|
||||||
else body = new CompoundStatement(null, new Statement[] { body });
|
else body = new CompoundStatement(null, new Statement[] { body });
|
||||||
|
|
||||||
@ -1890,7 +1892,7 @@ public class Parsing {
|
|||||||
FunctionStatement.checkBreakAndCont(res, 0);
|
FunctionStatement.checkBreakAndCont(res, 0);
|
||||||
}
|
}
|
||||||
catch (SyntaxException e) {
|
catch (SyntaxException e) {
|
||||||
res.clear();
|
res.target.clear();
|
||||||
res.add(Instruction.throwSyntax(e));
|
res.add(Instruction.throwSyntax(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1899,11 +1901,11 @@ public class Parsing {
|
|||||||
}
|
}
|
||||||
else res.add(Instruction.ret());
|
else res.add(Instruction.ret());
|
||||||
|
|
||||||
return new CodeFunction(environment, "", subscope.localsCount(), 0, new ValueVariable[0], res.toArray(Instruction[]::new));
|
return new CodeFunction(environment, "", subscope.localsCount(), 0, new ValueVariable[0], res.array());
|
||||||
}
|
}
|
||||||
public static CodeFunction compile(Environment environment, String filename, String raw) {
|
public static CodeFunction compile(HashMap<Long, Instruction[]> funcs, Environment environment, String filename, String raw) {
|
||||||
try {
|
try {
|
||||||
return compile(environment, parse(filename, raw));
|
return compile(funcs, environment, parse(filename, raw));
|
||||||
}
|
}
|
||||||
catch (SyntaxException e) {
|
catch (SyntaxException e) {
|
||||||
return new CodeFunction(environment, null, 2, 0, new ValueVariable[0], new Instruction[] { Instruction.throwSyntax(e) });
|
return new CodeFunction(environment, null, 2, 0, new ValueVariable[0], new Instruction[] { Instruction.throwSyntax(e) });
|
||||||
|
Loading…
Reference in New Issue
Block a user