use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.
the class OrdinaryObject method setValue.
/**
* 9.1.9 [[Set] (P, V, Receiver)
*
* @param cx
* the execution context
* @param propertyKey
* the property key
* @param value
* the new property value
* @param receiver
* the receiver object
* @return {@code true} on success
*/
protected boolean setValue(ExecutionContext cx, String propertyKey, Object value, Object receiver) {
/* step 1 (implicit) */
/* steps 2-3 */
Property ownDesc = getProperty(cx, propertyKey);
/* step 4 */
if (ownDesc == null) {
ScriptObject parent = getPrototypeOf(cx);
if (parent != null) {
return parent.set(cx, propertyKey, value, receiver);
} else {
ownDesc = new Property(UNDEFINED, true, true, true);
}
} else if (receiver == this && ownDesc.isWritable()) {
// Optimize the common case for own, writable properties
return setPropertyValue(cx, propertyKey, value, ownDesc);
}
/* step 5 */
if (ownDesc.isDataDescriptor()) {
if (!ownDesc.isWritable()) {
return false;
}
if (!Type.isObject(receiver)) {
return false;
}
ScriptObject _receiver = Type.objectValue(receiver);
Property existingDescriptor = _receiver.getOwnProperty(cx, propertyKey);
if (existingDescriptor != null) {
if (existingDescriptor.isAccessorDescriptor() || !existingDescriptor.isWritable()) {
return false;
}
PropertyDescriptor valueDesc = new PropertyDescriptor(value);
return _receiver.defineOwnProperty(cx, propertyKey, valueDesc);
} else {
return CreateDataProperty(cx, _receiver, propertyKey, value);
}
}
/* step 6 */
assert ownDesc.isAccessorDescriptor();
Callable setter = ownDesc.getSetter();
if (setter == null) {
return false;
}
setter.call(cx, receiver, value);
return true;
}
use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.
the class ProxyObject method ownEnumerablePropertyKeys.
/**
* 9.5.12 [[OwnPropertyKeys]] ()
*/
@Override
public Iterator<String> ownEnumerablePropertyKeys(ExecutionContext cx) {
/* steps 1-3 */
ScriptObject handler = getProxyHandler(cx);
/* step 4 */
ScriptObject target = getProxyTarget();
/* steps 5-6 */
Callable trap = GetMethod(cx, handler, "ownKeys");
/* step 7 */
if (trap == null) {
return target.ownEnumerablePropertyKeys(cx);
}
/* step 8 */
Object trapResultArray = trap.call(cx, handler, target);
/* steps 9-25 */
List<?> ownKeys = validateOwnPropertyKeys(cx, target, trapResultArray);
List<String> enumerableKeys = new ArrayList<>();
for (Object key : ownKeys) {
if (key instanceof String) {
enumerableKeys.add((String) key);
}
}
return enumerableKeys.iterator();
}
use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.
the class ProxyObject method validateOwnPropertyKeys.
private List<Object> validateOwnPropertyKeys(ExecutionContext cx, ScriptObject target, Object trapResultArray) {
/* steps 9-10 */
List<Object> trapResult = CreateListFromArrayLike(cx, trapResultArray, EnumSet.of(Type.String, Type.Symbol));
/* steps 11-12 */
boolean extensibleTarget = target.isExtensible(cx);
/* steps 13-15 */
List<?> targetKeys = target.ownPropertyKeys(cx);
/* step 16 */
ArrayList<Object> targetConfigurableKeys = new ArrayList<>();
/* step 17 */
ArrayList<Object> targetNonConfigurableKeys = new ArrayList<>();
/* step 18 */
for (Object key : targetKeys) {
Property desc = target.getOwnProperty(cx, key);
if (desc != null && !desc.isConfigurable()) {
targetNonConfigurableKeys.add(key);
} else {
targetConfigurableKeys.add(key);
}
}
/* step 19 */
if (extensibleTarget && targetNonConfigurableKeys.isEmpty()) {
return trapResult;
}
/* step 20 */
final Integer zero = Integer.valueOf(0);
HashMap<Object, Integer> uncheckedResultKeys = new HashMap<>();
for (Object key : trapResult) {
Integer c = uncheckedResultKeys.put(key, zero);
if (c != null) {
uncheckedResultKeys.put(key, c + 1);
}
}
/* step 21 */
for (Object key : targetNonConfigurableKeys) {
Integer c = uncheckedResultKeys.remove(key);
if (c == null) {
throw newTypeError(cx, Messages.Key.ProxyNotConfigurable);
}
if (c > 0) {
uncheckedResultKeys.put(key, c - 1);
}
}
/* step 22 */
if (extensibleTarget) {
return trapResult;
}
/* step 23 */
for (Object key : targetConfigurableKeys) {
Integer c = uncheckedResultKeys.remove(key);
if (c == null) {
throw newTypeError(cx, Messages.Key.ProxyNotExtensible);
}
if (c > 0) {
uncheckedResultKeys.put(key, c - 1);
}
}
/* step 24 */
if (!uncheckedResultKeys.isEmpty()) {
throw newTypeError(cx, Messages.Key.ProxyAbsentNotExtensible);
}
/* step 25 */
return trapResult;
}
use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.
the class ProxyObject method set.
/**
* 9.5.9 [[Set]] ( P, V, Receiver)
*/
@Override
public boolean set(ExecutionContext cx, String propertyKey, Object value, Object receiver) {
/* step 1 (implicit) */
/* steps 2-4 */
ScriptObject handler = getProxyHandler(cx);
/* step 5 */
ScriptObject target = getProxyTarget();
/* steps 6-7 */
Callable trap = GetMethod(cx, handler, "set");
/* step 8 */
if (trap == null) {
return target.set(cx, propertyKey, value, receiver);
}
/* steps 9-10 */
boolean trapResult = ToBoolean(trap.call(cx, handler, target, propertyKey, value, receiver));
/* step 11 */
if (!trapResult) {
return false;
}
/* steps 12-13 */
Property targetDesc = target.getOwnProperty(cx, propertyKey);
/* steps 14-15 */
return validateSet(cx, value, targetDesc);
}
use of com.github.anba.es6draft.runtime.types.ScriptObject in project es6draft by anba.
the class ProxyObject method setPrototypeOf.
/**
* 9.5.2 [[SetPrototypeOf]] (V)
*/
@Override
public boolean setPrototypeOf(ExecutionContext cx, ScriptObject prototype) {
/* step 1 (implicit) */
/* steps 2-4 */
ScriptObject handler = getProxyHandler(cx);
/* step 5 */
ScriptObject target = getProxyTarget();
/* step 6 */
Callable trap = GetMethod(cx, handler, "setPrototypeOf");
/* step 7 */
if (trap == null) {
return target.setPrototypeOf(cx, prototype);
}
/* step 8 */
Object prototypeValue = prototype != null ? prototype : NULL;
boolean trapResult = ToBoolean(trap.call(cx, handler, target, prototypeValue));
/* step 9 */
if (!trapResult) {
return false;
}
/* step 10 */
boolean extensibleTarget = IsExtensible(cx, target);
/* step 11 */
if (extensibleTarget) {
return true;
}
/* step 12 */
ScriptObject targetProto = target.getPrototypeOf(cx);
/* step 13 */
if (prototype != targetProto) {
throw newTypeError(cx, Messages.Key.ProxySamePrototype);
}
/* step 14 */
return true;
}
Aggregations