diff --git a/src/java/me/topchetoeu/jscript/common/FunctionBody.java b/src/java/me/topchetoeu/jscript/common/FunctionBody.java index 9d3cab1..3b91614 100644 --- a/src/java/me/topchetoeu/jscript/common/FunctionBody.java +++ b/src/java/me/topchetoeu/jscript/common/FunctionBody.java @@ -3,10 +3,11 @@ package me.topchetoeu.jscript.common; public class FunctionBody { public final FunctionBody[] children; public final Instruction[] instructions; - public final int localsN, capturesN, argsN; + public final int localsN, capturesN, argsN, length; - public FunctionBody(int localsN, int capturesN, int argsN, Instruction[] instructions, FunctionBody[] children) { + public FunctionBody(int localsN, int capturesN, int length, int argsN, Instruction[] instructions, FunctionBody[] children) { this.children = children; + this.length = length; this.argsN = argsN; this.localsN = localsN; this.capturesN = capturesN; diff --git a/src/java/me/topchetoeu/jscript/compilation/CompileResult.java b/src/java/me/topchetoeu/jscript/compilation/CompileResult.java index 59ce8fd..0a78253 100644 --- a/src/java/me/topchetoeu/jscript/compilation/CompileResult.java +++ b/src/java/me/topchetoeu/jscript/compilation/CompileResult.java @@ -3,7 +3,7 @@ package me.topchetoeu.jscript.compilation; import java.util.List; import java.util.ArrayList; import java.util.LinkedList; -import java.util.function.Supplier; +import java.util.function.IntFunction; import me.topchetoeu.jscript.common.FunctionBody; import me.topchetoeu.jscript.common.Instruction; @@ -16,11 +16,11 @@ import me.topchetoeu.jscript.compilation.scope.LocalScope; import me.topchetoeu.jscript.compilation.scope.Scope; public final class CompileResult { - public final List> instructions; + public final List> instructions; public final List children; public final FunctionMapBuilder map; public final Environment env; - public int length = 0; + public int length, assignN; public final Scope scope; public int temp() { @@ -29,18 +29,18 @@ public final class CompileResult { } public CompileResult add(Instruction instr) { - instructions.add(() -> instr); + instructions.add(i -> instr); return this; } - public CompileResult add(Supplier instr) { + public CompileResult add(IntFunction instr) { instructions.add(instr); return this; } public CompileResult set(int i, Instruction instr) { - instructions.set(i, () -> instr); + instructions.set(i, _i -> instr); return this; } - public CompileResult set(int i, Supplierinstr) { + public CompileResult set(int i, IntFunctioninstr) { instructions.set(i, instr); return this; } @@ -76,7 +76,10 @@ public final class CompileResult { public Instruction[] instructions() { var res = new Instruction[instructions.size()]; var i = 0; - for (var suppl : instructions) res[i++] = suppl.get(); + for (var suppl : instructions) { + res[i] = suppl.apply(i); + i++; + } return res; } @@ -90,10 +93,15 @@ public final class CompileResult { var instrRes = new Instruction[instructions.size()]; var i = 0; - for (var suppl : instructions) instrRes[i++] = suppl.get(); + + for (var suppl : instructions) { + instrRes[i] = suppl.apply(i); + i++; + } return new FunctionBody( - scope.localsCount() + scope.allocCount(), scope.capturesCount(), length, + scope.localsCount() + scope.allocCount(), scope.capturesCount(), + length, assignN, instrRes, builtChildren ); } diff --git a/src/java/me/topchetoeu/jscript/compilation/CompoundNode.java b/src/java/me/topchetoeu/jscript/compilation/CompoundNode.java index a45f58b..0a03de1 100644 --- a/src/java/me/topchetoeu/jscript/compilation/CompoundNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/CompoundNode.java @@ -19,11 +19,11 @@ public class CompoundNode extends Node { for (var stm : statements) stm.resolve(target); } - @Override public void compile(CompileResult target, boolean pollute, BreakpointType type) { + public void compile(CompileResult target, boolean pollute, boolean alloc, BreakpointType type) { List statements = new ArrayList(); var subtarget = target.subtarget(); - subtarget.add(() -> Instruction.stackAlloc(subtarget.scope.allocCount())); + if (alloc) subtarget.add(i -> Instruction.stackAlloc(subtarget.scope.allocCount())); for (var stm : this.statements) { if (stm instanceof FunctionStatementNode func) { @@ -42,13 +42,17 @@ public class CompoundNode extends Node { } subtarget.scope.end(); - subtarget.add(Instruction.stackFree(subtarget.scope.allocCount())); + if (alloc) subtarget.add(Instruction.stackFree(subtarget.scope.allocCount())); if (!polluted && pollute) { target.add(Instruction.pushUndefined()); } } + @Override public void compile(CompileResult target, boolean pollute, BreakpointType type) { + compile(target, pollute, true, type); + } + public CompoundNode setEnd(Location loc) { this.end = loc; return this; diff --git a/src/java/me/topchetoeu/jscript/compilation/FunctionNode.java b/src/java/me/topchetoeu/jscript/compilation/FunctionNode.java index ed54d94..66c88e4 100644 --- a/src/java/me/topchetoeu/jscript/compilation/FunctionNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/FunctionNode.java @@ -1,6 +1,7 @@ package me.topchetoeu.jscript.compilation; import me.topchetoeu.jscript.common.Instruction; +import me.topchetoeu.jscript.common.Operation; import me.topchetoeu.jscript.common.Instruction.BreakpointType; import me.topchetoeu.jscript.common.parsing.Location; import me.topchetoeu.jscript.common.parsing.ParseRes; @@ -12,7 +13,7 @@ import me.topchetoeu.jscript.runtime.exceptions.SyntaxException; public abstract class FunctionNode extends Node { public final CompoundNode body; - public final String[] args; + public final Parameters params; public final Location end; public abstract String name(); @@ -39,14 +40,6 @@ public abstract class FunctionNode extends Node { } private CompileResult compileBody(CompileResult target, String name, boolean storeSelf, boolean pollute, BreakpointType bp) { - for (var i = 0; i < args.length; i++) { - for (var j = 0; j < i; j++) { - if (args[i].equals(args[j])) { - throw new SyntaxException(loc(), "Duplicate parameter '" + args[i] + "'."); - } - } - } - var env = target.env.child() .remove(LabelContext.BREAK_CTX) .remove(LabelContext.CONTINUE_CTX); @@ -54,16 +47,31 @@ public abstract class FunctionNode extends Node { var funcScope = new FunctionScope(target.scope); var subtarget = new CompileResult(env, new LocalScope(funcScope)); - for (var arg : args) { + for (var param : params.params) { // TODO: Implement default values // TODO: Implement argument location - funcScope.defineArg(arg, loc()); + if (funcScope.hasArg(param.name)) throw new SyntaxException(param.loc, "Duplicate parameter name not allowed"); + var i = funcScope.defineParam(param.name, param.loc); + + if (param.node != null) { + var end = new DeferredIntSupplier(); + + subtarget.add(_i -> Instruction.loadVar(i.index())); + subtarget.add(Instruction.pushUndefined()); + subtarget.add(Instruction.operation(Operation.EQUALS)); + subtarget.add(_i -> Instruction.jmpIfNot(end.getAsInt() - _i)); + param.node.compile(subtarget, pollute); + subtarget.add(_i -> Instruction.storeVar(i.index())); + + end.set(subtarget.size()); + } } body.resolve(subtarget); - body.compile(subtarget, false); + body.compile(subtarget, false, false, BreakpointType.NONE); - subtarget.length = args.length; + subtarget.length = params.length; + subtarget.assignN = params.params.size(); subtarget.scope.end(); funcScope.end(); @@ -88,11 +96,11 @@ public abstract class FunctionNode extends Node { compile(target, pollute, (String)null, BreakpointType.NONE); } - public FunctionNode(Location loc, Location end, String[] args, CompoundNode body) { + public FunctionNode(Location loc, Location end, Parameters params, CompoundNode body) { super(loc); this.end = end; - this.args = args; + this.params = params; this.body = body; } @@ -117,21 +125,21 @@ public abstract class FunctionNode extends Node { n += name.n; n += Parsing.skipEmpty(src, i + n); - var args = JavaScript.parseParamList(src, i + n); - if (!args.isSuccess()) return args.chainError(src.loc(i + n), "Expected a parameter list"); - n += args.n; + var params = JavaScript.parseParameters(src, i + n); + if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected a parameter list"); + n += params.n; var body = CompoundNode.parse(src, i + n); - if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compound statement for function."); + if (!body.isSuccess()) return body.chainError(src.loc(i + n), "Expected a compound statement for function"); n += body.n; if (statement) return ParseRes.res(new FunctionStatementNode( loc, src.loc(i + n - 1), - args.result.toArray(String[]::new), body.result, name.result + params.result, body.result, name.result ), n); else return ParseRes.res(new FunctionValueNode( loc, src.loc(i + n - 1), - args.result.toArray(String[]::new), body.result, name.result + params.result, body.result, name.result ), n); } } diff --git a/src/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java b/src/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java index 1b404f3..183fcd9 100644 --- a/src/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/FunctionStatementNode.java @@ -18,8 +18,8 @@ public class FunctionStatementNode extends FunctionNode { target.add(VariableNode.toSet(target, end, this.name, pollute, true)); } - public FunctionStatementNode(Location loc, Location end, String[] args, CompoundNode body, String name) { - super(loc, end, args, body); + public FunctionStatementNode(Location loc, Location end, Parameters params, CompoundNode body, String name) { + super(loc, end, params, body); this.name = name; } } diff --git a/src/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java b/src/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java index c89d48d..89f96dd 100644 --- a/src/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/FunctionValueNode.java @@ -12,8 +12,8 @@ public class FunctionValueNode extends FunctionNode { compile(target, pollute, true, name, bp); } - public FunctionValueNode(Location loc, Location end, String[] args, CompoundNode body, String name) { - super(loc, end, args, body); + public FunctionValueNode(Location loc, Location end, Parameters params, CompoundNode body, String name) { + super(loc, end, params, body); this.name = name; } } diff --git a/src/java/me/topchetoeu/jscript/compilation/JavaScript.java b/src/java/me/topchetoeu/jscript/compilation/JavaScript.java index 96f2bbb..7b58aae 100644 --- a/src/java/me/topchetoeu/jscript/compilation/JavaScript.java +++ b/src/java/me/topchetoeu/jscript/compilation/JavaScript.java @@ -1,10 +1,10 @@ package me.topchetoeu.jscript.compilation; import java.util.ArrayList; -import java.util.List; import java.util.Set; import me.topchetoeu.jscript.common.Instruction; +import me.topchetoeu.jscript.common.Instruction.BreakpointType; import me.topchetoeu.jscript.common.environment.Environment; import me.topchetoeu.jscript.common.parsing.Filename; import me.topchetoeu.jscript.common.parsing.ParseRes; @@ -212,40 +212,53 @@ public class JavaScript { return ParseRes.failed(); } - public static ParseRes> parseParamList(Source src, int i) { + public static ParseRes parseParameters(Source src, int i) { var n = Parsing.skipEmpty(src, i); var openParen = Parsing.parseOperator(src, i + n, "("); - if (!openParen.isSuccess()) return openParen.chainError(src.loc(i + n), "Expected a parameter list."); + if (!openParen.isSuccess()) return openParen.chainError(src.loc(i + n), "Expected a parameter list"); n += openParen.n; - var args = new ArrayList(); + var params = new ArrayList(); var closeParen = Parsing.parseOperator(src, i + n, ")"); n += closeParen.n; if (!closeParen.isSuccess()) { while (true) { - var argRes = Parsing.parseIdentifier(src, i + n); - if (argRes.isSuccess()) { - args.add(argRes.result); - n += argRes.n; - n += Parsing.skipEmpty(src, i); + n += Parsing.skipEmpty(src, i + n); - if (src.is(i + n, ",")) { - n++; - n += Parsing.skipEmpty(src, i + n); - } - if (src.is(i + n, ")")) { - n++; - break; - } + var paramLoc = src.loc(i); + + var name = Parsing.parseIdentifier(src, i + n); + if (!name.isSuccess()) return ParseRes.error(src.loc(i + n), "Expected an argument or a closing brace"); + n += name.n; + n += Parsing.skipEmpty(src, i + n); + + if (src.is(i + n, "=")) { + n++; + + var val = parseExpression(src, i + n, 2); + if (!val.isSuccess()) return openParen.chainError(src.loc(i + n), "Expected a default value"); + n += val.n; + n += Parsing.skipEmpty(src, i + n); + + params.add(new Parameter(paramLoc, name.result, val.result)); + } + else params.add(new Parameter(paramLoc, name.result, null)); + + if (src.is(i + n, ",")) { + n++; + n += Parsing.skipEmpty(src, i + n); + } + if (src.is(i + n, ")")) { + n++; + break; } - else return ParseRes.error(src.loc(i + n), "Expected an argument, or a closing brace."); } } - return ParseRes.res(args, n); + return ParseRes.res(new Parameters(params), n); } public static Node[] parse(Environment env, Filename filename, String raw) { @@ -279,7 +292,7 @@ public class JavaScript { try { stm.resolve(target); - stm.compile(target, true); + stm.compile(target, true, false, BreakpointType.NONE); // FunctionNode.checkBreakAndCont(target, 0); } catch (SyntaxException e) { diff --git a/src/java/me/topchetoeu/jscript/compilation/LabelContext.java b/src/java/me/topchetoeu/jscript/compilation/LabelContext.java index 5cfb1a3..0dea994 100644 --- a/src/java/me/topchetoeu/jscript/compilation/LabelContext.java +++ b/src/java/me/topchetoeu/jscript/compilation/LabelContext.java @@ -2,8 +2,8 @@ package me.topchetoeu.jscript.compilation; import java.util.HashMap; import java.util.LinkedList; +import java.util.function.IntFunction; import java.util.function.IntSupplier; -import java.util.function.Supplier; import me.topchetoeu.jscript.common.Instruction; import me.topchetoeu.jscript.common.environment.Environment; @@ -25,15 +25,15 @@ public class LabelContext { return map.get(name); } - public Supplier getJump(int offset) { + public IntFunction getJump() { var res = get(); if (res == null) return null; - else return () -> Instruction.jmp(res.getAsInt() - offset); + else return i -> Instruction.jmp(res.getAsInt() - i); } - public Supplier getJump(int offset, String name) { + public IntFunction getJump(String name) { var res = get(name); if (res == null) return null; - else return () -> Instruction.jmp(res.getAsInt() - offset); + else return i -> Instruction.jmp(res.getAsInt() - i); } public void push(IntSupplier jumpTarget) { diff --git a/src/java/me/topchetoeu/jscript/compilation/Parameter.java b/src/java/me/topchetoeu/jscript/compilation/Parameter.java new file mode 100644 index 0000000..9404d5d --- /dev/null +++ b/src/java/me/topchetoeu/jscript/compilation/Parameter.java @@ -0,0 +1,15 @@ +package me.topchetoeu.jscript.compilation; + +import me.topchetoeu.jscript.common.parsing.Location; + +public final class Parameter { + public final Location loc; + public final String name; + public final Node node; + + public Parameter(Location loc, String name, Node node) { + this.name = name; + this.node = node; + this.loc = loc; + } +} \ No newline at end of file diff --git a/src/java/me/topchetoeu/jscript/compilation/Parameters.java b/src/java/me/topchetoeu/jscript/compilation/Parameters.java new file mode 100644 index 0000000..c104a38 --- /dev/null +++ b/src/java/me/topchetoeu/jscript/compilation/Parameters.java @@ -0,0 +1,28 @@ +package me.topchetoeu.jscript.compilation; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public final class Parameters { + public final int length; + public final List params; + public final Set names; + + public Parameters(List params) { + this.names = new HashSet<>(); + var len = params.size(); + + for (var i = params.size() - 1; i >= 0; i--) { + if (params.get(i).node == null) break; + len--; + } + + for (var param : params) { + this.names.add(param.name); + } + + this.params = params; + this.length = len; + } +} diff --git a/src/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java b/src/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java index 84c7014..69b91f8 100644 --- a/src/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/VariableDeclareNode.java @@ -40,7 +40,7 @@ public class VariableDeclareNode extends Node { target.add(VariableNode.toSet(target, entry.location, entry.name, false, true)); } else { - target.add(() -> { + target.add(_i -> { var i = target.scope.get(entry.name, true); if (i == null) return Instruction.globDef(entry.name); diff --git a/src/java/me/topchetoeu/jscript/compilation/control/BreakNode.java b/src/java/me/topchetoeu/jscript/compilation/control/BreakNode.java index e052b30..b74e2a4 100644 --- a/src/java/me/topchetoeu/jscript/compilation/control/BreakNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/control/BreakNode.java @@ -15,7 +15,7 @@ public class BreakNode extends Node { public final String label; @Override public void compile(CompileResult target, boolean pollute) { - var res = LabelContext.getBreak(target.env).getJump(target.size()); + var res = LabelContext.getBreak(target.env).getJump(); if (res == null) { if (label != null) throw new SyntaxException(loc(), String.format("Undefined label '%s'", label)); else throw new SyntaxException(loc(), "Illegal break statement"); diff --git a/src/java/me/topchetoeu/jscript/compilation/control/ContinueNode.java b/src/java/me/topchetoeu/jscript/compilation/control/ContinueNode.java index be09e72..afc94a5 100644 --- a/src/java/me/topchetoeu/jscript/compilation/control/ContinueNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/control/ContinueNode.java @@ -15,7 +15,7 @@ public class ContinueNode extends Node { public final String label; @Override public void compile(CompileResult target, boolean pollute) { - var res = LabelContext.getCont(target.env).getJump(target.size()); + var res = LabelContext.getCont(target.env).getJump(); if (res == null) { if (label != null) throw new SyntaxException(loc(), String.format("Undefined label '%s'", label)); else throw new SyntaxException(loc(), "Illegal continue statement"); diff --git a/src/java/me/topchetoeu/jscript/compilation/control/SwitchNode.java b/src/java/me/topchetoeu/jscript/compilation/control/SwitchNode.java index 311a1a9..f41a997 100644 --- a/src/java/me/topchetoeu/jscript/compilation/control/SwitchNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/control/SwitchNode.java @@ -44,7 +44,7 @@ public class SwitchNode extends Node { value.compile(target, true, BreakpointType.STEP_OVER); var subtarget = target.subtarget(); - subtarget.add(() -> Instruction.stackAlloc(subtarget.scope.allocCount())); + subtarget.add(_i -> Instruction.stackAlloc(subtarget.scope.allocCount())); // TODO: create a jump map for (var ccase : cases) { diff --git a/src/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java b/src/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java index 5741a63..3e70aa5 100644 --- a/src/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java +++ b/src/java/me/topchetoeu/jscript/compilation/scope/FunctionScope.java @@ -27,7 +27,7 @@ public class FunctionScope extends Scope { else if (parent == null) throw new RuntimeException("Strict variables may be defined only in local scopes"); else return parent.defineStrict(name, readonly, loc); } - public VariableDescriptor defineArg(String name, Location loc) { + public VariableDescriptor defineParam(String name, Location loc) { return specials.add(name, false); } public boolean hasArg(String name) { diff --git a/src/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java b/src/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java index 48bab87..9382b81 100644 --- a/src/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/values/ObjectNode.java @@ -97,7 +97,7 @@ public class ObjectNode extends Node { if (!name.isSuccess()) return name.chainError(src.loc(i + n), "Expected a property name after '" + access + "'"); n += name.n; - var params = JavaScript.parseParamList(src, i + n); + var params = JavaScript.parseParameters(src, i + n); if (!params.isSuccess()) return params.chainError(src.loc(i + n), "Expected an argument list"); n += params.n; @@ -109,7 +109,7 @@ public class ObjectNode extends Node { return ParseRes.res(new ObjProp( name.result, access.result, - new FunctionValueNode(loc, end, params.result.toArray(String[]::new), body.result, access + " " + name.result.toString()) + new FunctionValueNode(loc, end, params.result, body.result, access + " " + name.result.toString()) ), n); } diff --git a/src/java/me/topchetoeu/jscript/compilation/values/VariableNode.java b/src/java/me/topchetoeu/jscript/compilation/values/VariableNode.java index bea5355..1ced342 100644 --- a/src/java/me/topchetoeu/jscript/compilation/values/VariableNode.java +++ b/src/java/me/topchetoeu/jscript/compilation/values/VariableNode.java @@ -1,5 +1,6 @@ package me.topchetoeu.jscript.compilation.values; +import java.util.function.IntFunction; import java.util.function.Supplier; import me.topchetoeu.jscript.common.Instruction; @@ -33,7 +34,7 @@ public class VariableNode extends Node implements AssignableNode { var i = target.scope.get(name, true); if (i == null) { - target.add((Supplier)() -> { + target.add(_i -> { if (target.scope.has(name)) throw new SyntaxException(loc(), String.format("Cannot access '%s' before initialization", name)); return Instruction.globGet(name); }); @@ -45,28 +46,28 @@ public class VariableNode extends Node implements AssignableNode { } } - public static Supplier toGet(CompileResult target, Location loc, String name, Supplier onGlobal) { + public static IntFunction toGet(CompileResult target, Location loc, String name, Supplier onGlobal) { var i = target.scope.get(name, true); - if (i == null) return () -> { + if (i == null) return _i -> { if (target.scope.has(name)) throw new SyntaxException(loc, String.format("Cannot access '%s' before initialization", name)); else return onGlobal.get(); }; - else return () -> Instruction.loadVar(i.index()); + else return _i -> Instruction.loadVar(i.index()); } - public static Supplier toGet(CompileResult target, Location loc, String name) { + public static IntFunction toGet(CompileResult target, Location loc, String name) { return toGet(target, loc, name, () -> Instruction.globGet(name)); } - public static Supplier toSet(CompileResult target, Location loc, String name, boolean keep, boolean define) { + public static IntFunction toSet(CompileResult target, Location loc, String name, boolean keep, boolean define) { var i = target.scope.get(name, true); - if (i == null) return () -> { + if (i == null) return _i -> { if (target.scope.has(name)) throw new SyntaxException(loc, String.format("Cannot access '%s' before initialization", name)); else return Instruction.globSet(name, keep, define); }; - else return () -> Instruction.storeVar(i.index(), keep); + else return _i -> Instruction.storeVar(i.index(), keep); } diff --git a/src/java/me/topchetoeu/jscript/runtime/Frame.java b/src/java/me/topchetoeu/jscript/runtime/Frame.java index c979933..f91ba76 100644 --- a/src/java/me/topchetoeu/jscript/runtime/Frame.java +++ b/src/java/me/topchetoeu/jscript/runtime/Frame.java @@ -420,11 +420,16 @@ public final class Frame { this.argsVal = new ArgumentsValue(this, args); this.captures = func.captures; - for (var i = 0; i < func.body.argsN; i++) { + var i = 0; + + for (; i < func.body.argsN && i < args.length; i++) { this.locals.add(new Value[] { args[i] }); } + for (; i < args.length; i++) { + this.locals.add(new Value[] { Value.UNDEFINED }); + } - for (var i = 0; i < func.body.localsN; i++) { + for (i = 0; i < func.body.localsN; i++) { this.locals.add(new Value[] { Value.UNDEFINED }); } diff --git a/src/java/me/topchetoeu/jscript/runtime/values/functions/CodeFunction.java b/src/java/me/topchetoeu/jscript/runtime/values/functions/CodeFunction.java index 335dcdf..6eb5aa6 100644 --- a/src/java/me/topchetoeu/jscript/runtime/values/functions/CodeFunction.java +++ b/src/java/me/topchetoeu/jscript/runtime/values/functions/CodeFunction.java @@ -30,7 +30,7 @@ public final class CodeFunction extends FunctionValue { } public CodeFunction(Environment env, String name, FunctionBody body, Value[][] captures) { - super(name, body.argsN); + super(name, body.length); this.captures = captures; this.env = env; this.body = body;