use of com.github.anba.es6draft.runtime.types.PropertyDescriptor in project es6draft by anba.
the class ArgumentsObject method defineProperty.
/**
* 9.4.4.2 [[DefineOwnProperty]] (P, Desc)
*/
@Override
protected boolean defineProperty(ExecutionContext cx, long propertyKey, PropertyDescriptor desc) {
/* step 1 (not applicable) */
/* step 2 */
ParameterMap map = this.parameterMap;
/* step 3 */
boolean isMapped = map != null && map.hasOwnProperty(propertyKey);
/* step 4 */
PropertyDescriptor newArgDesc = desc;
/* step 5 */
if (isMapped && desc.isDataDescriptor()) {
/* step 5.a */
if (!desc.hasValue() && desc.hasWritable() && !desc.isWritable()) {
newArgDesc = desc.clone();
newArgDesc.setValue(map.get(propertyKey));
}
}
/* step 6 */
boolean allowed = ordinaryDefineOwnProperty(cx, propertyKey, newArgDesc);
/* step 7 */
if (!allowed) {
return false;
}
/* step 8 */
if (isMapped) {
if (desc.isAccessorDescriptor()) {
map.delete(propertyKey);
} else {
if (desc.hasValue()) {
map.put(propertyKey, desc.getValue());
}
if (desc.hasWritable() && !desc.isWritable()) {
map.delete(propertyKey);
}
}
}
hasIndexedAccessors |= desc.isAccessorDescriptor();
/* step 9 */
return true;
}
use of com.github.anba.es6draft.runtime.types.PropertyDescriptor 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, Symbol 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.PropertyDescriptor 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.PropertyDescriptor in project es6draft by anba.
the class Properties method createExternalAccessors.
private static <OWNER> void createExternalAccessors(ExecutionContext cx, ScriptObject target, OWNER owner, ObjectLayout layout, Converter converter) {
LinkedHashMap<String, PropertyDescriptor> stringProps = new LinkedHashMap<>();
EnumMap<BuiltinSymbol, PropertyDescriptor> symbolProps = new EnumMap<>(BuiltinSymbol.class);
for (Entry<Accessor, MethodHandle> entry : layout.accessors.entrySet()) {
MethodHandle handle = getInstanceMethodHandle(cx, converter, entry.getValue(), owner);
createExternalAccessor(cx, entry.getKey(), handle, stringProps, symbolProps);
}
defineProperties(cx, target, stringProps, symbolProps);
}
use of com.github.anba.es6draft.runtime.types.PropertyDescriptor in project es6draft by anba.
the class Properties method createExternalAccessor.
private static void createExternalAccessor(ExecutionContext cx, Accessor accessor, MethodHandle mh, LinkedHashMap<String, PropertyDescriptor> stringProps, EnumMap<BuiltinSymbol, PropertyDescriptor> symbolProps) {
Accessor.Type type = accessor.type();
String name = accessor.name();
BuiltinSymbol symbol = accessor.symbol();
Attributes attributes = accessor.attributes();
String functionName = accessorName(type, name, symbol);
int arity = accessorArity(type);
NativeFunction fun = new NativeFunction(cx.getRealm(), functionName, arity, mh);
PropertyDescriptor existing;
if (symbol == BuiltinSymbol.NONE) {
existing = stringProps.get(name);
} else {
existing = symbolProps.get(symbol);
}
PropertyDescriptor desc;
if (existing != null) {
if (attributes.enumerable() != existing.isEnumerable() || attributes.configurable() != existing.isConfigurable()) {
throw new IllegalArgumentException();
}
if (type == Accessor.Type.Getter ? existing.getGetter() != null : existing.getSetter() != null) {
throw new IllegalArgumentException();
}
desc = existing;
} else {
desc = propertyDescriptor(null, null, attributes);
}
if (type == Accessor.Type.Getter) {
desc.setGetter(fun);
} else {
desc.setSetter(fun);
}
if (symbol == BuiltinSymbol.NONE) {
stringProps.put(name, desc);
} else {
symbolProps.put(symbol, desc);
}
}
Aggregations