Cache function bodies #6

Merged
TopchetoEU merged 1 commits from TopchetoEU/function-optimizations into master 2023-10-04 18:38:30 +00:00
42 changed files with 137 additions and 137 deletions

View 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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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