feat: some API improvements
This commit is contained in:
parent
89eea7d62b
commit
c10d071346
@ -22,6 +22,8 @@ import me.topchetoeu.jscript.lib.EnvironmentLib;
|
||||
import me.topchetoeu.jscript.mapping.SourceMap;
|
||||
|
||||
public class Context implements Extensions {
|
||||
public static final Context NULL = new Context(null);
|
||||
|
||||
public final Context parent;
|
||||
public final Environment environment;
|
||||
public final CodeFrame frame;
|
||||
|
@ -71,7 +71,7 @@ public class Environment implements Extensions {
|
||||
return ext.init(COMPILE_FUNC, new NativeFunction("compile", args -> {
|
||||
var source = args.getString(0);
|
||||
var filename = args.getString(1);
|
||||
var env = Values.wrapper(args.convert(2, ObjectValue.class).getMember(args.ctx, Symbol.get("env")), Environment.class);
|
||||
var env = Values.wrapper(Values.getMember(args.ctx, args.get(2), Symbol.get("env")), Environment.class);
|
||||
var isDebug = DebugContext.enabled(args.ctx);
|
||||
var res = new ObjectValue();
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
package me.topchetoeu.jscript.engine;
|
||||
|
||||
import me.topchetoeu.jscript.engine.values.Symbol;
|
||||
|
||||
public abstract class ExtensionStack implements Extensions {
|
||||
protected abstract Extensions[] extensionStack();
|
||||
|
||||
@Override public <T> void add(Symbol key, T obj) {
|
||||
for (var el : extensionStack()) {
|
||||
if (el != null) {
|
||||
el.add(key, obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override public <T> T get(Symbol key) {
|
||||
for (var el : extensionStack()) {
|
||||
if (el != null && el.has(key)) return el.get(key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@Override public boolean has(Symbol key) {
|
||||
for (var el : extensionStack()) {
|
||||
if (el != null && el.has(key)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@Override public boolean remove(Symbol key) {
|
||||
var anyRemoved = false;
|
||||
|
||||
for (var el : extensionStack()) {
|
||||
if (el != null) anyRemoved &= el.remove(key);
|
||||
}
|
||||
|
||||
return anyRemoved;
|
||||
}
|
||||
}
|
@ -124,8 +124,7 @@ public class SimpleDebugger implements Debugger {
|
||||
this.global = frame.function.environment.global.obj;
|
||||
this.local = frame.getLocalScope(true);
|
||||
this.capture = frame.getCaptureScope(true);
|
||||
this.local.setPrototype(frame.ctx, capture);
|
||||
this.capture.setPrototype(frame.ctx, global);
|
||||
Values.makePrototypeChain(frame.ctx, global, capture, local);
|
||||
this.valstack = frame.getValStackScope();
|
||||
|
||||
this.serialized = new JSONMap()
|
||||
@ -841,7 +840,7 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
else {
|
||||
propDesc.set("name", Values.toString(ctx, key));
|
||||
propDesc.set("value", serializeObj(ctx, obj.getMember(ctx, key)));
|
||||
propDesc.set("value", serializeObj(ctx, Values.getMember(ctx, obj, key)));
|
||||
propDesc.set("writable", obj.memberWritable(key));
|
||||
propDesc.set("enumerable", obj.memberEnumerable(key));
|
||||
propDesc.set("configurable", obj.memberConfigurable(key));
|
||||
@ -850,7 +849,7 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
}
|
||||
|
||||
var proto = obj.getPrototype(ctx);
|
||||
var proto = Values.getPrototype(ctx, obj);
|
||||
|
||||
var protoDesc = new JSONMap();
|
||||
protoDesc.set("name", "__proto__");
|
||||
|
@ -1,9 +0,0 @@
|
||||
package me.topchetoeu.jscript.engine.frame;
|
||||
|
||||
public class InstructionResult {
|
||||
public final Object value;
|
||||
|
||||
public InstructionResult(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -7,13 +7,14 @@ import me.topchetoeu.jscript.engine.Context;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
import me.topchetoeu.jscript.engine.values.NativeFunction;
|
||||
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||
import me.topchetoeu.jscript.engine.values.Values;
|
||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||
|
||||
public class GlobalScope implements ScopeRecord {
|
||||
public final ObjectValue obj;
|
||||
|
||||
public boolean has(Context ctx, String name) {
|
||||
return obj.hasMember(ctx, name, false);
|
||||
return Values.hasMember(null, obj, name, false);
|
||||
}
|
||||
public Object getKey(String name) {
|
||||
return name;
|
||||
@ -21,7 +22,7 @@ public class GlobalScope implements ScopeRecord {
|
||||
|
||||
public GlobalScope globalChild() {
|
||||
var obj = new ObjectValue();
|
||||
obj.setPrototype(null, this.obj);
|
||||
Values.setPrototype(null, obj, this.obj);
|
||||
return new GlobalScope(obj);
|
||||
}
|
||||
public LocalScopeRecord child() {
|
||||
@ -29,12 +30,12 @@ public class GlobalScope implements ScopeRecord {
|
||||
}
|
||||
|
||||
public Object define(String name) {
|
||||
if (obj.hasMember(null, name, true)) return name;
|
||||
obj.defineProperty(null, name, null);
|
||||
if (Values.hasMember(Context.NULL, obj, name, false)) return name;
|
||||
obj.defineProperty(Context.NULL, name, null);
|
||||
return name;
|
||||
}
|
||||
public void define(String name, Variable val) {
|
||||
obj.defineProperty(null, name,
|
||||
obj.defineProperty(Context.NULL, name,
|
||||
new NativeFunction("get " + name, args -> val.get(args.ctx)),
|
||||
new NativeFunction("set " + name, args -> { val.set(args.ctx, args.get(0)); return null; }),
|
||||
true, true
|
||||
@ -51,12 +52,12 @@ public class GlobalScope implements ScopeRecord {
|
||||
}
|
||||
|
||||
public Object get(Context ctx, String name) {
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
else return obj.getMember(ctx, name);
|
||||
if (!Values.hasMember(ctx, obj, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
else return Values.getMember(ctx, obj, name);
|
||||
}
|
||||
public void set(Context ctx, String name, Object val) {
|
||||
if (!obj.hasMember(ctx, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
if (!obj.setMember(ctx, name, val, false)) throw EngineException.ofSyntax("The global '" + name + "' is readonly.");
|
||||
if (!Values.hasMember(ctx, obj, name, false)) throw EngineException.ofSyntax("The variable '" + name + "' doesn't exist.");
|
||||
if (!Values.setMember(ctx, obj, name, val)) throw EngineException.ofSyntax("The global '" + name + "' is readonly.");
|
||||
}
|
||||
|
||||
public Set<String> keys() {
|
||||
|
@ -54,6 +54,13 @@ public class ObjectValue {
|
||||
public LinkedHashSet<Object> nonConfigurableSet = new LinkedHashSet<>();
|
||||
public LinkedHashSet<Object> nonEnumerableSet = new LinkedHashSet<>();
|
||||
|
||||
private Property getProperty(Context ctx, Object key) {
|
||||
if (properties.containsKey(key)) return properties.get(key);
|
||||
var proto = getPrototype(ctx);
|
||||
if (proto != null) return proto.getProperty(ctx, key);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public final boolean memberWritable(Object key) {
|
||||
if (state == State.FROZEN) return false;
|
||||
return !values.containsKey(key) || !nonWritableSet.contains(key);
|
||||
@ -159,6 +166,113 @@ public class ObjectValue {
|
||||
|
||||
return (ObjectValue)prototype;
|
||||
}
|
||||
public final boolean setPrototype(PlaceholderProto val) {
|
||||
if (!extensible()) return false;
|
||||
switch (val) {
|
||||
case OBJECT: prototype = OBJ_PROTO; break;
|
||||
case FUNCTION: prototype = FUNC_PROTO; break;
|
||||
case ARRAY: prototype = ARR_PROTO; break;
|
||||
case ERROR: prototype = ERR_PROTO; break;
|
||||
case SYNTAX_ERROR: prototype = SYNTAX_ERR_PROTO; break;
|
||||
case TYPE_ERROR: prototype = TYPE_ERR_PROTO; break;
|
||||
case RANGE_ERROR: prototype = RANGE_ERR_PROTO; break;
|
||||
case NONE: prototype = null; break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A method, used to get the value of a field. If a property is bound to
|
||||
* this key, but not a field, this method should return null.
|
||||
*/
|
||||
protected Object getField(Context ctx, Object key) {
|
||||
if (values.containsKey(key)) return values.get(key);
|
||||
var proto = getPrototype(ctx);
|
||||
if (proto != null) return proto.getField(ctx, key);
|
||||
else return null;
|
||||
}
|
||||
/**
|
||||
* Changes the value of a field, that is bound to the given key. If no field is
|
||||
* bound to this key, a new field should be created with the given value
|
||||
* @return Whether or not the operation was successful
|
||||
*/
|
||||
protected boolean setField(Context ctx, Object key, Object val) {
|
||||
if (val instanceof FunctionValue && ((FunctionValue)val).name.equals("")) {
|
||||
((FunctionValue)val).name = Values.toString(ctx, key);
|
||||
}
|
||||
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Deletes the field bound to the given key.
|
||||
*/
|
||||
protected void deleteField(Context ctx, Object key) {
|
||||
values.remove(key);
|
||||
}
|
||||
/**
|
||||
* Returns whether or not there is a field bound to the given key.
|
||||
* This must ignore properties
|
||||
*/
|
||||
protected boolean hasField(Context ctx, Object key) {
|
||||
return values.containsKey(key);
|
||||
}
|
||||
|
||||
public final Object getMember(Context ctx, Object key, Object thisArg) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if ("__proto__".equals(key)) {
|
||||
var res = getPrototype(ctx);
|
||||
return res == null ? Values.NULL : res;
|
||||
}
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
|
||||
if (prop != null) {
|
||||
if (prop.getter == null) return null;
|
||||
else return prop.getter.call(ctx, Values.normalize(ctx, thisArg));
|
||||
}
|
||||
else return getField(ctx, key);
|
||||
}
|
||||
public final boolean setMember(Context ctx, Object key, Object val, Object thisArg, boolean onlyProps) {
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
if (prop != null) {
|
||||
if (prop.setter == null) return false;
|
||||
prop.setter.call(ctx, Values.normalize(ctx, thisArg), val);
|
||||
return true;
|
||||
}
|
||||
else if (onlyProps) return false;
|
||||
else if (!extensible() && !values.containsKey(key)) return false;
|
||||
else if (key == null) {
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
else if ("__proto__".equals(key)) return setPrototype(ctx, val);
|
||||
else if (nonWritableSet.contains(key)) return false;
|
||||
else return setField(ctx, key, val);
|
||||
}
|
||||
public final boolean hasMember(Context ctx, Object key, boolean own) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key != null && "__proto__".equals(key)) return true;
|
||||
if (hasField(ctx, key)) return true;
|
||||
if (properties.containsKey(key)) return true;
|
||||
if (own) return false;
|
||||
var proto = getPrototype(ctx);
|
||||
return proto != null && proto.hasMember(ctx, key, own);
|
||||
}
|
||||
public final boolean deleteMember(Context ctx, Object key) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (!memberConfigurable(key)) return false;
|
||||
properties.remove(key);
|
||||
nonWritableSet.remove(key);
|
||||
nonEnumerableSet.remove(key);
|
||||
deleteField(ctx, key);
|
||||
return true;
|
||||
}
|
||||
public final boolean setPrototype(Context ctx, Object val) {
|
||||
val = Values.normalize(ctx, val);
|
||||
|
||||
@ -186,111 +300,6 @@ public class ObjectValue {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public final boolean setPrototype(PlaceholderProto val) {
|
||||
if (!extensible()) return false;
|
||||
switch (val) {
|
||||
case OBJECT: prototype = OBJ_PROTO; break;
|
||||
case FUNCTION: prototype = FUNC_PROTO; break;
|
||||
case ARRAY: prototype = ARR_PROTO; break;
|
||||
case ERROR: prototype = ERR_PROTO; break;
|
||||
case SYNTAX_ERROR: prototype = SYNTAX_ERR_PROTO; break;
|
||||
case TYPE_ERROR: prototype = TYPE_ERR_PROTO; break;
|
||||
case RANGE_ERROR: prototype = RANGE_ERR_PROTO; break;
|
||||
case NONE: prototype = null; break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected Property getProperty(Context ctx, Object key) {
|
||||
if (properties.containsKey(key)) return properties.get(key);
|
||||
var proto = getPrototype(ctx);
|
||||
if (proto != null) return proto.getProperty(ctx, key);
|
||||
else return null;
|
||||
}
|
||||
protected Object getField(Context ctx, Object key) {
|
||||
if (values.containsKey(key)) return values.get(key);
|
||||
var proto = getPrototype(ctx);
|
||||
if (proto != null) return proto.getField(ctx, key);
|
||||
else return null;
|
||||
}
|
||||
protected boolean setField(Context ctx, Object key, Object val) {
|
||||
if (val instanceof FunctionValue && ((FunctionValue)val).name.equals("")) {
|
||||
((FunctionValue)val).name = Values.toString(ctx, key);
|
||||
}
|
||||
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
protected void deleteField(Context ctx, Object key) {
|
||||
values.remove(key);
|
||||
}
|
||||
protected boolean hasField(Context ctx, Object key) {
|
||||
return values.containsKey(key);
|
||||
}
|
||||
|
||||
public final Object getMember(Context ctx, Object key, Object thisArg) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if ("__proto__".equals(key)) {
|
||||
var res = getPrototype(ctx);
|
||||
return res == null ? Values.NULL : res;
|
||||
}
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
|
||||
if (prop != null) {
|
||||
if (prop.getter == null) return null;
|
||||
else return prop.getter.call(ctx, Values.normalize(ctx, thisArg));
|
||||
}
|
||||
else return getField(ctx, key);
|
||||
}
|
||||
public final Object getMember(Context ctx, Object key) {
|
||||
return getMember(ctx, key, this);
|
||||
}
|
||||
|
||||
public final boolean setMember(Context ctx, Object key, Object val, Object thisArg, boolean onlyProps) {
|
||||
key = Values.normalize(ctx, key); val = Values.normalize(ctx, val);
|
||||
|
||||
var prop = getProperty(ctx, key);
|
||||
if (prop != null) {
|
||||
if (prop.setter == null) return false;
|
||||
prop.setter.call(ctx, Values.normalize(ctx, thisArg), val);
|
||||
return true;
|
||||
}
|
||||
else if (onlyProps) return false;
|
||||
else if (!extensible() && !values.containsKey(key)) return false;
|
||||
else if (key == null) {
|
||||
values.put(key, val);
|
||||
return true;
|
||||
}
|
||||
else if ("__proto__".equals(key)) return setPrototype(ctx, val);
|
||||
else if (nonWritableSet.contains(key)) return false;
|
||||
else return setField(ctx, key, val);
|
||||
}
|
||||
public final boolean setMember(Context ctx, Object key, Object val, boolean onlyProps) {
|
||||
return setMember(ctx, Values.normalize(ctx, key), Values.normalize(ctx, val), this, onlyProps);
|
||||
}
|
||||
|
||||
public final boolean hasMember(Context ctx, Object key, boolean own) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (key != null && "__proto__".equals(key)) return true;
|
||||
if (hasField(ctx, key)) return true;
|
||||
if (properties.containsKey(key)) return true;
|
||||
if (own) return false;
|
||||
var proto = getPrototype(ctx);
|
||||
return proto != null && proto.hasMember(ctx, key, own);
|
||||
}
|
||||
public final boolean deleteMember(Context ctx, Object key) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
||||
if (!memberConfigurable(key)) return false;
|
||||
properties.remove(key);
|
||||
nonWritableSet.remove(key);
|
||||
nonEnumerableSet.remove(key);
|
||||
deleteField(ctx, key);
|
||||
return true;
|
||||
}
|
||||
|
||||
public final ObjectValue getMemberDescriptor(Context ctx, Object key) {
|
||||
key = Values.normalize(ctx, key);
|
||||
|
@ -281,7 +281,7 @@ public class Values {
|
||||
obj = normalize(ctx, obj); key = normalize(ctx, key);
|
||||
if (obj == null) throw new IllegalArgumentException("Tried to access member of undefined.");
|
||||
if (obj == NULL) throw new IllegalArgumentException("Tried to access member of null.");
|
||||
if (obj instanceof ObjectValue) return object(obj).getMember(ctx, key);
|
||||
if (obj instanceof ObjectValue) return ((ObjectValue)obj).getMember(ctx, key, obj);
|
||||
|
||||
if (obj instanceof String && key instanceof Number) {
|
||||
var i = number(key);
|
||||
@ -307,7 +307,7 @@ public class Values {
|
||||
if (obj == null) throw EngineException.ofType("Tried to access member of undefined.");
|
||||
if (obj == NULL) throw EngineException.ofType("Tried to access member of null.");
|
||||
if (key != null && "__proto__".equals(key)) return setPrototype(ctx, obj, val);
|
||||
if (obj instanceof ObjectValue) return object(obj).setMember(ctx, key, val, false);
|
||||
if (obj instanceof ObjectValue) return ((ObjectValue)obj).setMember(ctx, key, val, obj, false);
|
||||
|
||||
var proto = getPrototype(ctx, obj);
|
||||
return proto.setMember(ctx, key, val, obj, true);
|
||||
@ -340,7 +340,7 @@ public class Values {
|
||||
public static ObjectValue getPrototype(Context ctx, Object obj) {
|
||||
if (obj == null || obj == NULL) return null;
|
||||
obj = normalize(ctx, obj);
|
||||
if (obj instanceof ObjectValue) return object(obj).getPrototype(ctx);
|
||||
if (obj instanceof ObjectValue) return ((ObjectValue)obj).getPrototype(ctx);
|
||||
if (ctx == null) return null;
|
||||
|
||||
if (obj instanceof String) return ctx.get(Environment.STRING_PROTO);
|
||||
@ -352,7 +352,12 @@ public class Values {
|
||||
}
|
||||
public static boolean setPrototype(Context ctx, Object obj, Object proto) {
|
||||
obj = normalize(ctx, obj);
|
||||
return obj instanceof ObjectValue && object(obj).setPrototype(ctx, proto);
|
||||
return obj instanceof ObjectValue && ((ObjectValue)obj).setPrototype(ctx, proto);
|
||||
}
|
||||
public static void makePrototypeChain(Context ctx, Object... chain) {
|
||||
for(var i = 1; i < chain.length; i++) {
|
||||
setPrototype(ctx, chain[i], chain[i - 1]);
|
||||
}
|
||||
}
|
||||
public static List<Object> getMembers(Context ctx, Object obj, boolean own, boolean includeNonEnumerable) {
|
||||
List<Object> res = new ArrayList<>();
|
||||
@ -367,7 +372,7 @@ public class Values {
|
||||
|
||||
while (proto != null) {
|
||||
res.addAll(proto.keys(includeNonEnumerable));
|
||||
proto = proto.getPrototype(ctx);
|
||||
proto = getPrototype(ctx, proto);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +405,7 @@ public class Values {
|
||||
var res = new ObjectValue();
|
||||
try {
|
||||
var proto = Values.getMember(ctx, func, "prototype");
|
||||
res.setPrototype(ctx, proto);
|
||||
setPrototype(ctx, res, proto);
|
||||
|
||||
var ret = call(ctx, func, res, args);
|
||||
|
||||
@ -569,11 +574,11 @@ public class Values {
|
||||
private void loadNext() {
|
||||
if (next == null) value = null;
|
||||
else if (consumed) {
|
||||
var curr = object(next.call(ctx, iterator));
|
||||
var curr = next.call(ctx, iterator);
|
||||
if (curr == null) { next = null; value = null; }
|
||||
if (toBoolean(curr.getMember(ctx, "done"))) { next = null; value = null; }
|
||||
if (toBoolean(Values.getMember(ctx, curr, "done"))) { next = null; value = null; }
|
||||
else {
|
||||
this.value = curr.getMember(ctx, "value");
|
||||
this.value = Values.getMember(ctx, curr, "value");
|
||||
consumed = false;
|
||||
}
|
||||
}
|
||||
|
@ -298,8 +298,8 @@ public class NativeWrapperProvider implements WrappersProvider {
|
||||
var parentProto = getProto(parent);
|
||||
var parentConstr = getConstr(parent);
|
||||
|
||||
if (parentProto != null) proto.setPrototype(null, parentProto);
|
||||
if (parentConstr != null) constr.setPrototype(null, parentConstr);
|
||||
if (parentProto != null) Values.setPrototype(Context.NULL, proto, parentProto);
|
||||
if (parentConstr != null) Values.setPrototype(Context.NULL, constr, parentConstr);
|
||||
}
|
||||
|
||||
public ObjectValue getProto(Class<?> clazz) {
|
||||
|
@ -58,8 +58,8 @@ public class JSON {
|
||||
|
||||
var res = new JSONMap();
|
||||
|
||||
for (var el : ((ObjectValue)val).keys(false)) {
|
||||
var jsonEl = fromJs(ctx, ((ObjectValue)val).getMember(ctx, el), prev);
|
||||
for (var el : Values.getMembers(ctx, val, false, false)) {
|
||||
var jsonEl = fromJs(ctx, Values.getMember(ctx, val, el), prev);
|
||||
if (jsonEl == null) continue;
|
||||
if (el instanceof String || el instanceof Number) res.put(el.toString(), jsonEl);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import me.topchetoeu.jscript.Reading;
|
||||
import me.topchetoeu.jscript.engine.Context;
|
||||
import me.topchetoeu.jscript.engine.Environment;
|
||||
import me.topchetoeu.jscript.engine.scope.GlobalScope;
|
||||
import me.topchetoeu.jscript.engine.values.FunctionValue;
|
||||
@ -208,7 +209,7 @@ public class Internals {
|
||||
env.add(Environment.TYPE_ERR_PROTO, wp.getProto(TypeErrorLib.class));
|
||||
env.add(Environment.RANGE_ERR_PROTO, wp.getProto(RangeErrorLib.class));
|
||||
|
||||
wp.getProto(ObjectLib.class).setPrototype(null, null);
|
||||
Values.setPrototype(Context.NULL, wp.getProto(ObjectLib.class), null);
|
||||
env.add(Environment.REGEX_CONSTR, wp.getConstr(RegExpLib.class));
|
||||
|
||||
return env;
|
||||
|
@ -26,7 +26,7 @@ public class ObjectLib {
|
||||
@Expose(target = ExposeTarget.STATIC)
|
||||
public static ObjectValue __create(Arguments args) {
|
||||
var obj = new ObjectValue();
|
||||
obj.setPrototype(args.ctx, args.get(0));
|
||||
Values.setPrototype(args.ctx, obj, args.get(0));
|
||||
|
||||
if (args.n() >= 1) {
|
||||
var newArgs = new Object[args.n()];
|
||||
@ -53,7 +53,7 @@ public class ObjectLib {
|
||||
if (hasGet || hasSet) throw EngineException.ofType("Cannot specify a value and accessors for a property.");
|
||||
if (!obj.defineProperty(
|
||||
args.ctx, key,
|
||||
attrib.getMember(args.ctx, "value"),
|
||||
Values.getMember(args.ctx, attrib, "value"),
|
||||
Values.toBoolean(Values.getMember(args.ctx, attrib, "writable")),
|
||||
Values.toBoolean(Values.getMember(args.ctx, attrib, "configurable")),
|
||||
Values.toBoolean(Values.getMember(args.ctx, attrib, "enumerable"))
|
||||
|
Loading…
Reference in New Issue
Block a user