package com.oracle.truffle.js.nodes.access;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.Tag;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.js.nodes.JavaScriptNode;
import com.oracle.truffle.js.runtime.JSContext;
import java.util.Set;
public class CompoundWriteElementNode extends WriteElementNode {
@Child private JSWriteFrameSlotNode writeIndexNode;
public static CompoundWriteElementNode create(JavaScriptNode targetNode, JavaScriptNode indexNode, JavaScriptNode valueNode, JSWriteFrameSlotNode writeIndexNode, JSContext context,
boolean isStrict) {
return create(targetNode, indexNode, valueNode, writeIndexNode, context, isStrict, false);
}
private static CompoundWriteElementNode create(JavaScriptNode targetNode, JavaScriptNode indexNode, JavaScriptNode valueNode, JSWriteFrameSlotNode writeIndexNode, JSContext context,
boolean isStrict, boolean writeOwn) {
return new CompoundWriteElementNode(targetNode, indexNode, valueNode, writeIndexNode, context, isStrict, writeOwn);
}
protected CompoundWriteElementNode(JavaScriptNode targetNode, JavaScriptNode indexNode, JavaScriptNode valueNode, JSWriteFrameSlotNode writeIndexNode, JSContext context, boolean isStrict,
boolean writeOwn) {
super(targetNode, indexNode, valueNode, context, isStrict, writeOwn);
this.writeIndexNode = writeIndexNode;
}
@Override
protected Object executeWithTargetAndIndex(VirtualFrame frame, Object target, Object index, Object receiver) {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndex(frame, target, writeIndex(frame, toArrayIndexNode().execute(index)), receiver);
}
@Override
protected Object executeWithTargetAndIndex(VirtualFrame frame, Object target, int index, Object receiver) {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndex(frame, target, writeIndex(frame, index), receiver);
}
@Override
protected int executeWithTargetAndIndexInt(VirtualFrame frame, Object target, Object index, Object receiver) throws UnexpectedResultException {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndexInt(frame, target, writeIndex(frame, toArrayIndexNode().execute(index)), receiver);
}
@Override
protected int executeWithTargetAndIndexInt(VirtualFrame frame, Object target, int index, Object receiver) throws UnexpectedResultException {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndexInt(frame, target, writeIndex(frame, index), receiver);
}
@Override
protected double executeWithTargetAndIndexDouble(VirtualFrame frame, Object target, Object index, Object receiver) throws UnexpectedResultException {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndexDouble(frame, target, writeIndex(frame, toArrayIndexNode().execute(index)), receiver);
}
@Override
protected double executeWithTargetAndIndexDouble(VirtualFrame frame, Object target, int index, Object receiver) throws UnexpectedResultException {
requireObjectCoercible(target, index);
return super.executeWithTargetAndIndexDouble(frame, target, writeIndex(frame, index), receiver);
}
private Object writeIndex(VirtualFrame frame, Object index) {
if (writeIndexNode != null) {
writeIndexNode.executeWrite(frame, index);
}
return index;
}
private int writeIndex(VirtualFrame frame, int index) {
if (writeIndexNode != null) {
writeIndexNode.executeWrite(frame, index);
}
return index;
}
@Override
protected JavaScriptNode copyUninitialized(Set<Class<? extends Tag>> materializedTags) {
return create(cloneUninitialized(targetNode, materializedTags), cloneUninitialized(indexNode, materializedTags), cloneUninitialized(valueNode, materializedTags),
cloneUninitialized(writeIndexNode, materializedTags), getContext(), isStrict(), writeOwn());
}
@Override
protected WriteElementNode createMaterialized(JavaScriptNode newTarget, JavaScriptNode newIndex, JavaScriptNode newValue) {
return CompoundWriteElementNode.create(newTarget, newIndex, newValue, writeIndexNode, getContext(), isStrict(), writeOwn());
}
}