feat: extend the instruction set

This commit is contained in:
TopchetoEU 2024-09-14 14:23:28 +03:00
parent 0b34c68139
commit 55613ef2c9
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
2 changed files with 36 additions and 21 deletions

View File

@ -56,9 +56,10 @@ public class Instruction {
STORE_MEMBER_STR(0x4B), STORE_MEMBER_STR(0x4B),
DEF_PROP(0x50), DEF_PROP(0x50),
KEYS(0x51), DEF_FIELD(0x51),
TYPEOF(0x52), KEYS(0x52),
OPERATION(0x53), TYPEOF(0x53),
OPERATION(0x54),
GLOB_GET(0x60), GLOB_GET(0x60),
GLOB_SET(0x61), GLOB_SET(0x61),
@ -341,8 +342,8 @@ public class Instruction {
return new Instruction(Type.GLOB_DEF, name); return new Instruction(Type.GLOB_DEF, name);
} }
public static Instruction globGet(String name) { public static Instruction globGet(String name, boolean force) {
return new Instruction(Type.GLOB_GET, name); return new Instruction(Type.GLOB_GET, name, force);
} }
public static Instruction globSet(String name, boolean keep, boolean define) { public static Instruction globSet(String name, boolean keep, boolean define) {
return new Instruction(Type.GLOB_SET, name, keep, define); return new Instruction(Type.GLOB_SET, name, keep, define);
@ -435,7 +436,7 @@ public class Instruction {
return new Instruction(Type.STORE_MEMBER_INT, key, false); return new Instruction(Type.STORE_MEMBER_INT, key, false);
} }
public static Instruction storeMember(int key, boolean keep) { public static Instruction storeMember(int key, boolean keep) {
return new Instruction(Type.STORE_MEMBER_STR, key, keep); return new Instruction(Type.STORE_MEMBER_INT, key, keep);
} }
public static Instruction discard() { public static Instruction discard() {
@ -453,8 +454,11 @@ public class Instruction {
return new Instruction(Type.KEYS, own, onlyEnumerable); return new Instruction(Type.KEYS, own, onlyEnumerable);
} }
public static Instruction defProp() { public static Instruction defProp(boolean setter) {
return new Instruction(Type.DEF_PROP); return new Instruction(Type.DEF_PROP, setter);
}
public static Instruction defField() {
return new Instruction(Type.DEF_FIELD);
} }
public static Instruction operation(Operation op) { public static Instruction operation(Operation op) {

View File

@ -58,24 +58,29 @@ public class InstructionRunner {
} }
private static Value execDefProp(Environment env, Instruction instr, Frame frame) { private static Value execDefProp(Environment env, Instruction instr, Frame frame) {
var setterVal = frame.pop(); var val = frame.pop();
var getterVal = frame.pop();
var key = frame.pop(); var key = frame.pop();
var obj = frame.pop(); var obj = frame.pop();
FunctionValue getter, setter; FunctionValue accessor;
if (getterVal == Value.UNDEFINED) getter = null; if (val == Value.UNDEFINED) accessor = null;
else if (getterVal instanceof FunctionValue) getter = (FunctionValue)getterVal; else if (val instanceof FunctionValue func) accessor = func;
else throw EngineException.ofType("Getter must be a function or undefined."); else throw EngineException.ofType("Getter must be a function or undefined.");
if (setterVal == Value.UNDEFINED) setter = null; if ((boolean)instr.get(0)) obj.defineOwnMember(env, key, new PropertyMember(obj, null, accessor, true, true));
else if (setterVal instanceof FunctionValue) setter = (FunctionValue)setterVal; else obj.defineOwnMember(env, key, new PropertyMember(obj, accessor, null, true, true));
else throw EngineException.ofType("Setter must be a function or undefined.");
obj.defineOwnMember(env, key, new PropertyMember(obj, getter, setter, true, true)); frame.codePtr++;
return null;
}
private static Value execDefField(Environment env, Instruction instr, Frame frame) {
var val = frame.pop();
var key = frame.pop();
var obj = frame.pop();
obj.defineOwnMember(env, key, val);
frame.push(obj);
frame.codePtr++; frame.codePtr++;
return null; return null;
} }
@ -449,10 +454,15 @@ public class InstructionRunner {
} }
private static Value exexGlobGet(Environment env, Instruction instr, Frame frame) { private static Value exexGlobGet(Environment env, Instruction instr, Frame frame) {
var name = (String)instr.get(0); var name = (String)instr.get(0);
if ((boolean)instr.get(1)) {
frame.push(Value.global(env).getMember(env, name));
}
else {
var res = Value.global(env).getMemberOrNull(env, name); var res = Value.global(env).getMemberOrNull(env, name);
if (res == null) throw EngineException.ofSyntax(name + " is not defined"); if (res == null) throw EngineException.ofSyntax(name + " is not defined");
else frame.push(res); else frame.push(res);
}
frame.codePtr++; frame.codePtr++;
return null; return null;
@ -576,6 +586,7 @@ public class InstructionRunner {
case KEYS: return execKeys(env, instr, frame); case KEYS: return execKeys(env, instr, frame);
case DEF_PROP: return execDefProp(env, instr, frame); case DEF_PROP: return execDefProp(env, instr, frame);
case DEF_FIELD: return execDefField(env, instr, frame);
case TYPEOF: return execTypeof(env, instr, frame); case TYPEOF: return execTypeof(env, instr, frame);
case DELETE: return execDelete(env, instr, frame); case DELETE: return execDelete(env, instr, frame);