package com.oracle.truffle.js.runtime.builtins;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.js.runtime.Boundaries;
import com.oracle.truffle.js.runtime.array.ScriptArray;
public final class JSSlowArgumentsArray extends JSAbstractArgumentsArray {
static final JSSlowArgumentsArray INSTANCE = new JSSlowArgumentsArray();
private JSSlowArgumentsArray() {
}
@TruffleBoundary
@Override
public boolean delete(DynamicObject thisObj, long index, boolean isStrict) {
if (isSealedOrFrozen(thisObj)) {
return true;
}
boolean isMappedArguments = isMappedArguments(thisObj);
boolean indexDisconnected = isMappedArguments && wasIndexDisconnected(thisObj, index);
Object oldValue = indexDisconnected ? null : get(thisObj, index);
boolean wasDeleted;
ScriptArray arrayType = arrayGetArrayType(thisObj);
if (arrayType.hasElement(thisObj, index)) {
arraySetArrayType(thisObj, arrayType.deleteElement(thisObj, index, false));
wasDeleted = true;
} else {
wasDeleted = JSOrdinary.INSTANCE.delete(thisObj, index, isStrict);
}
if (wasDeleted && isMappedArguments && !indexDisconnected) {
disconnectIndex(thisObj, index, oldValue);
}
return wasDeleted;
}
private static boolean isSealedOrFrozen(DynamicObject thisObj) {
ScriptArray array = arrayGetArrayType(thisObj);
return array.isSealed() || array.isFrozen();
}
public static boolean isJSSlowArgumentsObject(DynamicObject obj) {
return isInstance(obj, INSTANCE);
}
@Override
protected DynamicObject makeSlowArray(DynamicObject thisObj) {
assert JSSlowArgumentsArray.isJSSlowArgumentsObject(thisObj);
return thisObj;
}
@TruffleBoundary
@Override
public boolean set(DynamicObject thisObj, long index, Object value, Object receiver, boolean isStrict, Node encapsulatingNode) {
String indexAsString = Boundaries.stringValueOf(index);
if (JSOrdinary.INSTANCE.hasOwnProperty(thisObj, indexAsString)) {
return ordinarySet(thisObj, indexAsString, value, receiver, isStrict, encapsulatingNode);
}
return super.set(thisObj, index, value, receiver, isStrict, encapsulatingNode);
}
@TruffleBoundary
@Override
public Object getOwnHelper(DynamicObject store, Object thisObj, long index, Node encapsulatingNode) {
String indexAsString = Boundaries.stringValueOf(index);
if (JSOrdinary.INSTANCE.hasOwnProperty(store, indexAsString)) {
return JSOrdinary.INSTANCE.getOwnHelper(store, thisObj, indexAsString, encapsulatingNode);
}
return super.getOwnHelper(store, thisObj, index, encapsulatingNode);
}
}