feat: extend the instruction set
This commit is contained in:
parent
0b34c68139
commit
55613ef2c9
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user