From bd503ed943f80fc326856b291047bc9ec2fbbaf7 Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:44:58 +0300 Subject: [PATCH] feat: impl new instructions --- .../jscript/runtime/InstructionRunner.java | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/src/java/me/topchetoeu/jscript/runtime/InstructionRunner.java b/src/java/me/topchetoeu/jscript/runtime/InstructionRunner.java index 48ecd51..48fcd01 100644 --- a/src/java/me/topchetoeu/jscript/runtime/InstructionRunner.java +++ b/src/java/me/topchetoeu/jscript/runtime/InstructionRunner.java @@ -118,7 +118,7 @@ public class InstructionRunner { int count = instr.get(0); for (var i = 0; i < count; i++) { - frame.push(frame.peek(count - 1)); + frame.push(frame.peek()); } frame.codePtr++; @@ -172,14 +172,20 @@ public class InstructionRunner { private static Value execLoadFunc(Environment env, Instruction instr, Frame frame) { int id = instr.get(0); String name = instr.get(1); - var captures = new Value[instr.params.length - 2][]; + boolean callable = instr.get(2); + boolean constructible = instr.get(3); + boolean captureThis = instr.get(4); + + var captures = new Value[instr.params.length - 5][]; - for (var i = 2; i < instr.params.length; i++) { - captures[i - 2] = frame.getVar(instr.get(i)); + for (var i = 5; i < instr.params.length; i++) { + captures[i - 5] = frame.getVar(instr.get(i)); } var func = new CodeFunction(env, name, frame.function.body.children[id], captures); - + if (!callable) func.enableCall = false; + if (!constructible) func.enableNew = false; + if (captureThis) func.self = frame.self; frame.push(func); frame.codePtr++; @@ -187,10 +193,32 @@ public class InstructionRunner { } private static Value execLoadMember(Environment env, Instruction instr, Frame frame) { var key = frame.pop(); - var obj = frame.pop(); try { - frame.push(obj.getMember(env, key)); + var top = frame.stackPtr - 1; + frame.stack[top] = frame.stack[top].getMember(env, key); + } + catch (IllegalArgumentException e) { + throw EngineException.ofType(e.getMessage()); + } + frame.codePtr++; + return null; + } + private static Value execLoadMemberInt(Environment env, Instruction instr, Frame frame) { + try { + var top = frame.stackPtr - 1; + frame.stack[top] = frame.stack[top].getMember(env, (int)instr.get(0)); + } + catch (IllegalArgumentException e) { + throw EngineException.ofType(e.getMessage()); + } + frame.codePtr++; + return null; + } + private static Value execLoadMemberStr(Environment env, Instruction instr, Frame frame) { + try { + var top = frame.stackPtr - 1; + frame.stack[top] = frame.stack[top].getMember(env, (String)instr.get(0)); } catch (IllegalArgumentException e) { throw EngineException.ofType(e.getMessage()); @@ -225,6 +253,24 @@ public class InstructionRunner { frame.codePtr++; return null; } + private static Value execStoreMemberStr(Environment env, Instruction instr, Frame frame) { + var val = frame.pop(); + var obj = frame.pop(); + + if (!obj.setMember(env, (String)instr.get(0), val)) throw EngineException.ofSyntax("Can't set member '" + instr.get(0) + "'."); + if ((boolean)instr.get(1)) frame.push(val); + frame.codePtr++; + return null; + } + private static Value execStoreMemberInt(Environment env, Instruction instr, Frame frame) { + var val = frame.pop(); + var obj = frame.pop(); + + if (!obj.setMember(env, (int)instr.get(0), val)) throw EngineException.ofSyntax("Can't set member '" + instr.get(0) + "'."); + if ((boolean)instr.get(1)) frame.push(val); + frame.codePtr++; + return null; + } private static Value execStoreVar(Environment env, Instruction instr, Frame frame) { var val = (boolean)instr.get(1) ? frame.peek() : frame.pop(); int i = instr.get(0); @@ -430,6 +476,21 @@ public class InstructionRunner { frame.codePtr++; return null; } + private static Value execLoadRestArgs(Environment env, Instruction instr, Frame frame) { + int offset = instr.get(0); + var res = new ArrayValue(); + + if (offset < frame.args.length) res.copyFrom(frame.args, instr.get(0), 0, frame.args.length - offset); + + frame.push(res); + frame.codePtr++; + return null; + } + private static Value execLoadCallee(Environment env, Instruction instr, Frame frame) { + frame.push(frame.function); + frame.codePtr++; + return null; + } private static Value execLoadThis(Environment env, Instruction instr, Frame frame) { frame.push(frame.self); frame.codePtr++; @@ -479,14 +540,20 @@ public class InstructionRunner { case LOAD_ARR: return execLoadArr(env, instr, frame); case LOAD_FUNC: return execLoadFunc(env, instr, frame); case LOAD_MEMBER: return execLoadMember(env, instr, frame); + case LOAD_MEMBER_INT: return execLoadMemberInt(env, instr, frame); + case LOAD_MEMBER_STR: return execLoadMemberStr(env, instr, frame); case LOAD_REGEX: return execLoadRegEx(env, instr, frame); case LOAD_GLOB: return execLoadGlob(env, instr, frame); case LOAD_INTRINSICS: return execLoadIntrinsics(env, instr, frame); case LOAD_ARGS: return execLoadArgs(env, instr, frame); + case LOAD_REST_ARGS: return execLoadRestArgs(env, instr, frame); + case LOAD_CALLEE: return execLoadCallee(env, instr, frame); case LOAD_THIS: return execLoadThis(env, instr, frame); case DISCARD: return execDiscard(env, instr, frame); case STORE_MEMBER: return execStoreMember(env, instr, frame); + case STORE_MEMBER_STR: return execStoreMemberStr(env, instr, frame); + case STORE_MEMBER_INT: return execStoreMemberInt(env, instr, frame); case STORE_VAR: return execStoreVar(env, instr, frame); case KEYS: return execKeys(env, instr, frame);