|
|
@ -29,7 +29,7 @@ import me.topchetoeu.j2s.runtime.values.primitives.SymbolValue;
|
|
|
|
import me.topchetoeu.j2s.runtime.values.primitives.VoidValue;
|
|
|
|
import me.topchetoeu.j2s.runtime.values.primitives.VoidValue;
|
|
|
|
import me.topchetoeu.j2s.runtime.values.primitives.numbers.NumberValue;
|
|
|
|
import me.topchetoeu.j2s.runtime.values.primitives.numbers.NumberValue;
|
|
|
|
|
|
|
|
|
|
|
|
public abstract class Value {
|
|
|
|
public interface Value {
|
|
|
|
public static enum State {
|
|
|
|
public static enum State {
|
|
|
|
NORMAL(true, true, true),
|
|
|
|
NORMAL(true, true, true),
|
|
|
|
NON_EXTENDABLE(false, true, true),
|
|
|
|
NON_EXTENDABLE(false, true, true),
|
|
|
@ -76,28 +76,43 @@ public abstract class Value {
|
|
|
|
public abstract StringValue type();
|
|
|
|
public abstract StringValue type();
|
|
|
|
public abstract boolean isPrimitive();
|
|
|
|
public abstract boolean isPrimitive();
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean isNaN() {
|
|
|
|
public default boolean isNaN() {
|
|
|
|
return this == NumberValue.NAN || this instanceof NumberValue num && Double.isNaN(num.getDouble());
|
|
|
|
return this == NumberValue.NAN || this instanceof NumberValue num && Double.isNaN(num.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Value apply(Environment env, Value self, Value ...args) {
|
|
|
|
public default Value apply(Environment env, Value self, Value ...args) {
|
|
|
|
throw EngineException.ofType("Value is not a function");
|
|
|
|
throw EngineException.ofType("Value is not a function");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public Value construct(Environment env, Value target, Value ...args) {
|
|
|
|
public default Value construct(Environment env, Value target, Value ...args) {
|
|
|
|
throw EngineException.ofType("Value is not a constructor");
|
|
|
|
throw EngineException.ofType("Value is not a constructor");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final Value constructNoSelf(Environment env, Value ...args) {
|
|
|
|
public default Value constructNoSelf(Environment env, Value ...args) {
|
|
|
|
return this.construct(env, this, args);
|
|
|
|
return this.construct(env, this, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Value toPrimitive(Environment env);
|
|
|
|
|
|
|
|
public NumberValue toNumber(Environment env);
|
|
|
|
|
|
|
|
public String toString(Environment env);
|
|
|
|
|
|
|
|
public boolean toBoolean();
|
|
|
|
|
|
|
|
|
|
|
|
public abstract Value toPrimitive(Environment env);
|
|
|
|
public Member getOwnMember(Environment env, KeyCache key);
|
|
|
|
public abstract NumberValue toNumber(Environment env);
|
|
|
|
public Set<String> getOwnMembers(Environment env, boolean onlyEnumerable);
|
|
|
|
public abstract String toString(Environment env);
|
|
|
|
public Set<SymbolValue> getOwnSymbolMembers(Environment env, boolean onlyEnumerable);
|
|
|
|
public abstract boolean toBoolean();
|
|
|
|
public boolean defineOwnField(Environment env, KeyCache key, Value val, Boolean writable, Boolean enumerable, Boolean configurable);
|
|
|
|
|
|
|
|
public boolean defineOwnProperty(Environment env, KeyCache key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable);
|
|
|
|
|
|
|
|
public boolean deleteOwnMember(Environment env, KeyCache key);
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean isInstanceOf(Environment env, Value proto) {
|
|
|
|
public ObjectValue getPrototype(Environment env);
|
|
|
|
|
|
|
|
public boolean setPrototype(Environment env, ObjectValue val);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public State getState();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void preventExtensions();
|
|
|
|
|
|
|
|
public void seal();
|
|
|
|
|
|
|
|
public void freeze();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public default boolean isInstanceOf(Environment env, Value proto) {
|
|
|
|
for (var val = getPrototype(env); val != null; val = val.getPrototype(env)) {
|
|
|
|
for (var val = getPrototype(env); val != null; val = val.getPrototype(env)) {
|
|
|
|
if (val.equals(proto)) return true;
|
|
|
|
if (val.equals(proto)) return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -105,91 +120,75 @@ public abstract class Value {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public abstract Member getOwnMember(Environment env, KeyCache key);
|
|
|
|
public default Member getOwnMember(Environment env, Value key) {
|
|
|
|
public abstract Set<String> getOwnMembers(Environment env, boolean onlyEnumerable);
|
|
|
|
|
|
|
|
public abstract Set<SymbolValue> getOwnSymbolMembers(Environment env, boolean onlyEnumerable);
|
|
|
|
|
|
|
|
public abstract boolean defineOwnField(Environment env, KeyCache key, Value val, Boolean writable, Boolean enumerable, Boolean configurable);
|
|
|
|
|
|
|
|
public abstract boolean defineOwnProperty(Environment env, KeyCache key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable);
|
|
|
|
|
|
|
|
public abstract boolean deleteOwnMember(Environment env, KeyCache key);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public abstract ObjectValue getPrototype(Environment env);
|
|
|
|
|
|
|
|
public abstract boolean setPrototype(Environment env, ObjectValue val);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public abstract State getState();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public abstract void preventExtensions();
|
|
|
|
|
|
|
|
public abstract void seal();
|
|
|
|
|
|
|
|
public abstract void freeze();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final Member getOwnMember(Environment env, Value key) {
|
|
|
|
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Member getOwnMember(Environment env, String key) {
|
|
|
|
public default Member getOwnMember(Environment env, String key) {
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Member getOwnMember(Environment env, int key) {
|
|
|
|
public default Member getOwnMember(Environment env, int key) {
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Member getOwnMember(Environment env, double key) {
|
|
|
|
public default Member getOwnMember(Environment env, double key) {
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
return getOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean defineOwnProperty(Environment env, Value key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnProperty(Environment env, Value key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnProperty(Environment env, String key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnProperty(Environment env, String key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnProperty(Environment env, int key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnProperty(Environment env, int key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnProperty(Environment env, double key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnProperty(Environment env, double key, Optional<FunctionValue> get, Optional<FunctionValue> set, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
return defineOwnProperty(env, new KeyCache(key), get, set, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean defineOwnField(Environment env, Value key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnField(Environment env, Value key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, String key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnField(Environment env, String key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, int key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnField(Environment env, int key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, double key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
public default boolean defineOwnField(Environment env, double key, Value val, Boolean writable, Boolean enumerable, Boolean configurable) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val, writable, enumerable, configurable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean defineOwnField(Environment env, KeyCache key, Value val) {
|
|
|
|
public default boolean defineOwnField(Environment env, KeyCache key, Value val) {
|
|
|
|
return defineOwnField(env, key, val, true, true, true);
|
|
|
|
return defineOwnField(env, key, val, true, true, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, Value key, Value val) {
|
|
|
|
public default boolean defineOwnField(Environment env, Value key, Value val) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, String key, Value val) {
|
|
|
|
public default boolean defineOwnField(Environment env, String key, Value val) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, int key, Value val) {
|
|
|
|
public default boolean defineOwnField(Environment env, int key, Value val) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean defineOwnField(Environment env, double key, Value val) {
|
|
|
|
public default boolean defineOwnField(Environment env, double key, Value val) {
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
return defineOwnField(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean deleteOwnMember(Environment env, Value key) {
|
|
|
|
public default boolean deleteOwnMember(Environment env, Value key) {
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteOwnMember(Environment env, String key) {
|
|
|
|
public default boolean deleteOwnMember(Environment env, String key) {
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteOwnMember(Environment env, int key) {
|
|
|
|
public default boolean deleteOwnMember(Environment env, int key) {
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteOwnMember(Environment env, double key) {
|
|
|
|
public default boolean deleteOwnMember(Environment env, double key) {
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
return deleteOwnMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final Value getMemberOrNull(Environment env, KeyCache key) {
|
|
|
|
public default Value getMemberOrNull(Environment env, KeyCache key) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
if (member != null) return member.get(env, this);
|
|
|
|
if (member != null) return member.get(env, this);
|
|
|
@ -197,38 +196,38 @@ public abstract class Value {
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMemberOrNull(Environment env, Value key) {
|
|
|
|
public default Value getMemberOrNull(Environment env, Value key) {
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMemberOrNull(Environment env, String key) {
|
|
|
|
public default Value getMemberOrNull(Environment env, String key) {
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMemberOrNull(Environment env, int key) {
|
|
|
|
public default Value getMemberOrNull(Environment env, int key) {
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMemberOrNull(Environment env, double key) {
|
|
|
|
public default Value getMemberOrNull(Environment env, double key) {
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
return getMemberOrNull(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final Value getMember(Environment env, KeyCache key) {
|
|
|
|
public default Value getMember(Environment env, KeyCache key) {
|
|
|
|
var res = getMemberOrNull(env, key);
|
|
|
|
var res = getMemberOrNull(env, key);
|
|
|
|
if (res != null) return res;
|
|
|
|
if (res != null) return res;
|
|
|
|
else return Value.UNDEFINED;
|
|
|
|
else return Value.UNDEFINED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMember(Environment env, Value key) {
|
|
|
|
public default Value getMember(Environment env, Value key) {
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMember(Environment env, String key) {
|
|
|
|
public default Value getMember(Environment env, String key) {
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMember(Environment env, int key) {
|
|
|
|
public default Value getMember(Environment env, int key) {
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMember(Environment env, double key) {
|
|
|
|
public default Value getMember(Environment env, double key) {
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
return getMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean setMember(Environment env, KeyCache key, Value val) {
|
|
|
|
public default boolean setMember(Environment env, KeyCache key, Value val) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
if (member != null && (member instanceof PropertyMember || obj == this)) {
|
|
|
|
if (member != null && (member instanceof PropertyMember || obj == this)) {
|
|
|
@ -249,20 +248,20 @@ public abstract class Value {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMember(Environment env, Value key, Value val) {
|
|
|
|
public default boolean setMember(Environment env, Value key, Value val) {
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMember(Environment env, String key, Value val) {
|
|
|
|
public default boolean setMember(Environment env, String key, Value val) {
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMember(Environment env, int key, Value val) {
|
|
|
|
public default boolean setMember(Environment env, int key, Value val) {
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMember(Environment env, double key, Value val) {
|
|
|
|
public default boolean setMember(Environment env, double key, Value val) {
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
return setMember(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean setMemberIfExists(Environment env, KeyCache key, Value val) {
|
|
|
|
public default boolean setMemberIfExists(Environment env, KeyCache key, Value val) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
var member = obj.getOwnMember(env, key);
|
|
|
|
if (member != null) {
|
|
|
|
if (member != null) {
|
|
|
@ -276,20 +275,20 @@ public abstract class Value {
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMemberIfExists(Environment env, Value key, Value val) {
|
|
|
|
public default boolean setMemberIfExists(Environment env, Value key, Value val) {
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMemberIfExists(Environment env, String key, Value val) {
|
|
|
|
public default boolean setMemberIfExists(Environment env, String key, Value val) {
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMemberIfExists(Environment env, int key, Value val) {
|
|
|
|
public default boolean setMemberIfExists(Environment env, int key, Value val) {
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean setMemberIfExists(Environment env, double key, Value val) {
|
|
|
|
public default boolean setMemberIfExists(Environment env, double key, Value val) {
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
return setMemberIfExists(env, new KeyCache(key), val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean hasMember(Environment env, KeyCache key, boolean own) {
|
|
|
|
public default boolean hasMember(Environment env, KeyCache key, boolean own) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
for (Value obj = this; obj != null; obj = obj.getPrototype(env)) {
|
|
|
|
if (obj.getOwnMember(env, key) != null) return true;
|
|
|
|
if (obj.getOwnMember(env, key) != null) return true;
|
|
|
|
if (own) return false;
|
|
|
|
if (own) return false;
|
|
|
@ -297,37 +296,37 @@ public abstract class Value {
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean hasMember(Environment env, Value key, boolean own) {
|
|
|
|
public default boolean hasMember(Environment env, Value key, boolean own) {
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean hasMember(Environment env, String key, boolean own) {
|
|
|
|
public default boolean hasMember(Environment env, String key, boolean own) {
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean hasMember(Environment env, int key, boolean own) {
|
|
|
|
public default boolean hasMember(Environment env, int key, boolean own) {
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean hasMember(Environment env, double key, boolean own) {
|
|
|
|
public default boolean hasMember(Environment env, double key, boolean own) {
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
return hasMember(env, new KeyCache(key), own);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final boolean deleteMember(Environment env, KeyCache key) {
|
|
|
|
public default boolean deleteMember(Environment env, KeyCache key) {
|
|
|
|
if (!hasMember(env, key, true)) return true;
|
|
|
|
if (!hasMember(env, key, true)) return true;
|
|
|
|
return deleteOwnMember(env, key);
|
|
|
|
return deleteOwnMember(env, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteMember(Environment env, Value key) {
|
|
|
|
public default boolean deleteMember(Environment env, Value key) {
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteMember(Environment env, String key) {
|
|
|
|
public default boolean deleteMember(Environment env, String key) {
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteMember(Environment env, int key) {
|
|
|
|
public default boolean deleteMember(Environment env, int key) {
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final boolean deleteMember(Environment env, double key) {
|
|
|
|
public default boolean deleteMember(Environment env, double key) {
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
return deleteMember(env, new KeyCache(key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final Set<String> getMembers(Environment env, boolean own, boolean onlyEnumerable) {
|
|
|
|
public default Set<String> getMembers(Environment env, boolean own, boolean onlyEnumerable) {
|
|
|
|
var res = new LinkedHashSet<String>();
|
|
|
|
var res = new LinkedHashSet<String>();
|
|
|
|
var protos = new ArrayList<Value>();
|
|
|
|
var protos = new ArrayList<Value>();
|
|
|
|
|
|
|
|
|
|
|
@ -344,7 +343,7 @@ public abstract class Value {
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Set<SymbolValue> getSymbolMembers(Environment env, boolean own, boolean onlyEnumerable) {
|
|
|
|
public default Set<SymbolValue> getSymbolMembers(Environment env, boolean own, boolean onlyEnumerable) {
|
|
|
|
var res = new LinkedHashSet<SymbolValue>();
|
|
|
|
var res = new LinkedHashSet<SymbolValue>();
|
|
|
|
var protos = new ArrayList<Value>();
|
|
|
|
var protos = new ArrayList<Value>();
|
|
|
|
|
|
|
|
|
|
|
@ -362,24 +361,24 @@ public abstract class Value {
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final Value getMemberPath(Environment env, String ...path) {
|
|
|
|
public default Value getMemberPath(Environment env, String ...path) {
|
|
|
|
var res = this;
|
|
|
|
var res = this;
|
|
|
|
for (var key : path) res = res.getMember(env, key);
|
|
|
|
for (var key : path) res = res.getMember(env, key);
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final Value getMemberPath(Environment env, Value ...path) {
|
|
|
|
public default Value getMemberPath(Environment env, Value ...path) {
|
|
|
|
var res = this;
|
|
|
|
var res = this;
|
|
|
|
for (var key : path) res = res.getMember(env, key);
|
|
|
|
for (var key : path) res = res.getMember(env, key);
|
|
|
|
return res;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public final ObjectValue getMemberDescriptor(Environment env, Value key) {
|
|
|
|
public default ObjectValue getMemberDescriptor(Environment env, Value key) {
|
|
|
|
var member = getOwnMember(env, new KeyCache(key));
|
|
|
|
var member = getOwnMember(env, new KeyCache(key));
|
|
|
|
|
|
|
|
|
|
|
|
if (member != null) return member.descriptor(env, this);
|
|
|
|
if (member != null) return member.descriptor(env, this);
|
|
|
|
else return null;
|
|
|
|
else return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Iterable<Object> toIterable(Environment env) {
|
|
|
|
public default Iterable<Object> toIterable(Environment env) {
|
|
|
|
return () -> {
|
|
|
|
return () -> {
|
|
|
|
if (!(this instanceof FunctionValue)) return Collections.emptyIterator();
|
|
|
|
if (!(this instanceof FunctionValue)) return Collections.emptyIterator();
|
|
|
|
var func = (FunctionValue)this;
|
|
|
|
var func = (FunctionValue)this;
|
|
|
@ -418,29 +417,29 @@ public abstract class Value {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void callWith(Environment env, Iterable<? extends Value> it) {
|
|
|
|
public default void callWith(Environment env, Iterable<? extends Value> it) {
|
|
|
|
for (var el : it) {
|
|
|
|
for (var el : it) {
|
|
|
|
this.apply(env, Value.UNDEFINED, el);
|
|
|
|
this.apply(env, Value.UNDEFINED, el);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public void callWithAsync(Environment env, Iterable<? extends Value> it, boolean async) {
|
|
|
|
public default void callWithAsync(Environment env, Iterable<? extends Value> it, boolean async) {
|
|
|
|
for (var el : it) {
|
|
|
|
for (var el : it) {
|
|
|
|
env.get(EventLoop.KEY).pushMsg(() -> this.apply(env, Value.UNDEFINED, el), true);
|
|
|
|
env.get(EventLoop.KEY).pushMsg(() -> this.apply(env, Value.UNDEFINED, el), true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public List<String> toReadableLines(Environment env, HashSet<ObjectValue> passed) {
|
|
|
|
public default List<String> toReadableLines(Environment env, HashSet<ObjectValue> passed) {
|
|
|
|
return Arrays.asList(toString(env));
|
|
|
|
return Arrays.asList(toString(env));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final String toReadable(Environment ext) {
|
|
|
|
public default String toReadable(Environment ext) {
|
|
|
|
return String.join("\n", toReadableLines(ext, new HashSet<>()));
|
|
|
|
return String.join("\n", toReadableLines(ext, new HashSet<>()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final Value global(Environment env) {
|
|
|
|
public static Value global(Environment env) {
|
|
|
|
return env.initFrom(GLOBAL, () -> new ObjectValue());
|
|
|
|
return env.initFrom(GLOBAL, () -> new ObjectValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final Map<String, Value> intrinsics(Environment env) {
|
|
|
|
public static Map<String, Value> intrinsics(Environment env) {
|
|
|
|
return env.initFrom(INTRINSICS, () -> new HashMap<>());
|
|
|
|
return env.initFrom(INTRINSICS, () -> new HashMap<>());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -457,7 +456,7 @@ public abstract class Value {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final boolean lessOrEqual(Environment env, Value a, Value b) {
|
|
|
|
public static boolean lessOrEqual(Environment env, Value a, Value b) {
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
|
|
|
|
|
|
|
@ -472,7 +471,7 @@ public abstract class Value {
|
|
|
|
else return na.getDouble() <= nb.getDouble();
|
|
|
|
else return na.getDouble() <= nb.getDouble();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final boolean greaterOrEqual(Environment env, Value a, Value b) {
|
|
|
|
public static boolean greaterOrEqual(Environment env, Value a, Value b) {
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
|
|
|
|
|
|
|
@ -487,7 +486,7 @@ public abstract class Value {
|
|
|
|
else return na.getDouble() >= nb.getDouble();
|
|
|
|
else return na.getDouble() >= nb.getDouble();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final boolean less(Environment env, Value a, Value b) {
|
|
|
|
public static boolean less(Environment env, Value a, Value b) {
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
|
|
|
|
|
|
|
@ -502,7 +501,7 @@ public abstract class Value {
|
|
|
|
else return na.getDouble() < nb.getDouble();
|
|
|
|
else return na.getDouble() < nb.getDouble();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final boolean greater(Environment env, Value a, Value b) {
|
|
|
|
public static boolean greater(Environment env, Value a, Value b) {
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
|
|
|
|
|
|
|
@ -518,7 +517,7 @@ public abstract class Value {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final Value add(Environment env, Value a, Value b) {
|
|
|
|
public static Value add(Environment env, Value a, Value b) {
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
a = a.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
b = b.toPrimitive(env);
|
|
|
|
|
|
|
|
|
|
|
@ -534,21 +533,21 @@ public abstract class Value {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final NumberValue subtract(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue subtract(Environment env, Value a, Value b) {
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
|
|
|
|
|
|
|
|
if (na.isInt() && nb.isInt()) return NumberValue.of(na.getInt() - nb.getInt());
|
|
|
|
if (na.isInt() && nb.isInt()) return NumberValue.of(na.getInt() - nb.getInt());
|
|
|
|
else return NumberValue.of(na.getDouble() - nb.getDouble());
|
|
|
|
else return NumberValue.of(na.getDouble() - nb.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue multiply(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue multiply(Environment env, Value a, Value b) {
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
|
|
|
|
|
|
|
|
if (na.isInt() && nb.isInt()) return NumberValue.of(na.getInt() * nb.getInt());
|
|
|
|
if (na.isInt() && nb.isInt()) return NumberValue.of(na.getInt() * nb.getInt());
|
|
|
|
else return NumberValue.of(na.getDouble() * nb.getDouble());
|
|
|
|
else return NumberValue.of(na.getDouble() * nb.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue divide(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue divide(Environment env, Value a, Value b) {
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
|
|
|
|
|
|
|
@ -566,7 +565,7 @@ public abstract class Value {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else return NumberValue.of(na.getDouble() / nb.getDouble());
|
|
|
|
else return NumberValue.of(na.getDouble() / nb.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue modulo(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue modulo(Environment env, Value a, Value b) {
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
var nb = b.toNumber(env);
|
|
|
|
|
|
|
|
|
|
|
@ -579,33 +578,33 @@ public abstract class Value {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else return NumberValue.of(na.getDouble() % nb.getDouble());
|
|
|
|
else return NumberValue.of(na.getDouble() % nb.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue negative(Environment env, Value a) {
|
|
|
|
public static NumberValue negative(Environment env, Value a) {
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
var na = a.toNumber(env);
|
|
|
|
|
|
|
|
|
|
|
|
if (na.isInt()) return NumberValue.of(-na.getInt());
|
|
|
|
if (na.isInt()) return NumberValue.of(-na.getInt());
|
|
|
|
else return NumberValue.of(-na.getDouble());
|
|
|
|
else return NumberValue.of(-na.getDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final NumberValue and(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue and(Environment env, Value a, Value b) {
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() & b.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() & b.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue or(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue or(Environment env, Value a, Value b) {
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() | b.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() | b.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue xor(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue xor(Environment env, Value a, Value b) {
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() ^ b.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() ^ b.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue bitwiseNot(Environment env, Value a) {
|
|
|
|
public static NumberValue bitwiseNot(Environment env, Value a) {
|
|
|
|
return NumberValue.of(~a.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(~a.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final NumberValue shiftLeft(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue shiftLeft(Environment env, Value a, Value b) {
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() << b.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() << b.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue shiftRight(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue shiftRight(Environment env, Value a, Value b) {
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() >> b.toNumber(env).getInt());
|
|
|
|
return NumberValue.of(a.toNumber(env).getInt() >> b.toNumber(env).getInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static final NumberValue unsignedShiftRight(Environment env, Value a, Value b) {
|
|
|
|
public static NumberValue unsignedShiftRight(Environment env, Value a, Value b) {
|
|
|
|
long _a = a.toNumber(env).getLong() & 0xFFFFFFFF;
|
|
|
|
long _a = a.toNumber(env).getLong() & 0xFFFFFFFF;
|
|
|
|
long _b = b.toNumber(env).getLong() & 0xFFFFFFFF;
|
|
|
|
long _b = b.toNumber(env).getLong() & 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
|
@ -615,7 +614,7 @@ public abstract class Value {
|
|
|
|
return NumberValue.of(_a >>> _b);
|
|
|
|
return NumberValue.of(_a >>> _b);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final boolean looseEqual(Environment env, Value a, Value b) {
|
|
|
|
public static boolean looseEqual(Environment env, Value a, Value b) {
|
|
|
|
// In loose equality, null is equivalent to undefined
|
|
|
|
// In loose equality, null is equivalent to undefined
|
|
|
|
if (a instanceof VoidValue || b instanceof VoidValue) return a instanceof VoidValue && b instanceof VoidValue;
|
|
|
|
if (a instanceof VoidValue || b instanceof VoidValue) return a instanceof VoidValue && b instanceof VoidValue;
|
|
|
|
|
|
|
|
|
|
|
@ -637,7 +636,7 @@ public abstract class Value {
|
|
|
|
return a.toString(env).equals(b.toString(env));
|
|
|
|
return a.toString(env).equals(b.toString(env));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static final String errorToReadable(Environment env, RuntimeException err, String prefix) {
|
|
|
|
public static String errorToReadable(Environment env, RuntimeException err, String prefix) {
|
|
|
|
prefix = prefix == null ? "Uncaught" : "Uncaught " + prefix;
|
|
|
|
prefix = prefix == null ? "Uncaught" : "Uncaught " + prefix;
|
|
|
|
if (err instanceof EngineException ee) {
|
|
|
|
if (err instanceof EngineException ee) {
|
|
|
|
if (env == null) env = ee.env;
|
|
|
|
if (env == null) env = ee.env;
|
|
|
|