<commit_before>package edu.columbia.cs.psl.phosphor.struct;

import edu.columbia.cs.psl.phosphor.runtime.Taint;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.Arrays;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.HashMap;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.Map;

public final class LoopAwareControlStack<E> {

    private static final int NOT_PUSHED = -1;
    private LoopAwareControlFrame<E> stackTop;
    private LoopAwareControlFrameBuilder<E> frameBuilder;

    public LoopAwareControlStack() {
        stackTop = new LoopAwareControlFrame<>(0, null, null);
        frameBuilder = new LoopAwareControlFrameBuilder<>();
    }

    LoopAwareControlStack(LoopAwareControlStack<E> stack) {
        stackTop = new LoopAwareControlFrame<>(stack.stackTop.invocationLevel, stack.stackTop.argumentConstancyLevels, null);
        stackTop.levelStackMap.putAll(stack.stackTop.levelStackMap);
        frameBuilder = stack.frameBuilder.copy();
    }

    public LoopAwareControlStack<E> startFrame(int invocationLevel, int numArguments) {
        frameBuilder.start(invocationLevel, numArguments);
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgConstant() {
        frameBuilder.setNextArgLevel(0);
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgDependent(int[] dependencies) {
        frameBuilder.setNextArgLevel(getLevel(dependencies));
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgVariant(int levelOffset) {
        frameBuilder.setNextArgLevel(getLevel(levelOffset));
        return this;
    }

    public void pushFrame() {
        stackTop = frameBuilder.build(stackTop);
    }

    public int getLevel(int levelOffset) {
        return stackTop.getLevel(levelOffset);
    }

    public int getLevel(int[] dependencies) {
        return stackTop.getLevel(dependencies);
    }

    public void popFrame() {
        stackTop = stackTop.next;
    }

    public Taint<E> copyTagConstant() {
        return stackTop.copyTag(0);
    }

    public Taint<E> copyTagDependent(int[] dependencies) {
        return stackTop.copyTag(getLevel(dependencies));
    }

    public Taint<E> copyTagVariant(int levelOffset) {
        return stackTop.copyTag(getLevel(levelOffset));
    }

    public void pushConstant(Taint<E> tag, int branchID, int branchesSize) {
        stackTop.push(tag, branchID, branchesSize, 0);
    }

    public void pushDependent(Taint<E> tag, int branchID, int branchesSize, int[] dependencies) {
        stackTop.push(tag, branchID, branchesSize, getLevel(dependencies));
    }

    public void pushVariant(Taint<E> tag, int branchID, int branchesSize, int levelOffset) {
        stackTop.push(tag, branchID, branchesSize, getLevel(levelOffset));
    }

    public void pop(int branchID) {
        stackTop.pop(branchID);
    }

    public void reset() {
        stackTop.reset();
    }

    public void exitLoopLevel(int levelOffset) {
        stackTop.exitLoopLevel(levelOffset);
    }

    private static final class LoopAwareControlFrame<E> {

        private final int invocationLevel;
        private final int[] argumentConstancyLevels;
        private final Map<Integer, Node<E>> levelStackMap;
        private int[] branchLevels;
        private LoopAwareControlFrame<E> next;

        private LoopAwareControlFrame(int invocationLevel, int[] argumentConstancyLevels, LoopAwareControlFrame<E> next) {
            this.next = next;
            this.invocationLevel = invocationLevel;
            this.argumentConstancyLevels = argumentConstancyLevels;
            if(next == null) {
                levelStackMap = new HashMap<>();
            } else {
                levelStackMap = new HashMap<>(next.levelStackMap);
            }
        }

        int getLevel(int levelOffset) {
            return invocationLevel + levelOffset;
        }

        int getLevel(int[] dependencies) {
            if(argumentConstancyLevels == null) {
                return 0;
            } else {
                int max = 0;
                for(int dependency : dependencies) {
                    int value = argumentConstancyLevels[dependency];
                    if(value > max) {
                        max = value;
                    }
                }
                return max;
            }
        }

        Taint<E> copyTag(int level) {
            Taint<E> tag = null;
            for(Integer key : levelStackMap.keySet()) {
                if(key <= level) {
                    tag = Taint.combineTags(tag, levelStackMap.get(key).tag);
                }
            }
            return tag;
        }

        void push(Taint<E> tag, int branchID, int branchesSize, int level) {
            if(branchLevels == null) {
                branchLevels = new int[branchesSize];
                Arrays.fill(branchLevels, NOT_PUSHED);
            }
            if(!levelStackMap.containsKey(level)) {
                levelStackMap.put(level, Node.emptyNode());
            }
            if(branchLevels[branchID] == NOT_PUSHED) {
                branchLevels[branchID] = level;
                Taint<E> combined = Taint.combineTags(tag, levelStackMap.get(level).tag);
                levelStackMap.put(level, new Node<>(combined, levelStackMap.get(level)));
            } else {
                Node<E> r = levelStackMap.get(level);
                r.tag = r.tag.union(tag);
            }
        }

        void pop(int branchID) {
            if(branchLevels != null && branchLevels[branchID] != NOT_PUSHED) {
                levelStackMap.put(branchLevels[branchID], levelStackMap.get(branchLevels[branchID]).next);
                branchLevels[branchID] = NOT_PUSHED;
            }
        }

        void reset() {
            if(next != null) {
                next.reset();
            }
            branchLevels = null;
            levelStackMap.clear();
        }<commit_msg>* Fixed core dump<commit_after>package edu.columbia.cs.psl.phosphor.struct;

import edu.columbia.cs.psl.phosphor.runtime.Taint;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.Arrays;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.HashMap;
import edu.columbia.cs.psl.phosphor.struct.harmony.util.Map;

public final class LoopAwareControlStack<E> {

    private static final int NOT_PUSHED = -1;
    private LoopAwareControlFrame<E> stackTop;
    private LoopAwareControlFrameBuilder<E> frameBuilder;

    public LoopAwareControlStack() {
        stackTop = new LoopAwareControlFrame<>(0, null, null);
        frameBuilder = new LoopAwareControlFrameBuilder<>();
    }

    LoopAwareControlStack(LoopAwareControlStack<E> stack) {
        stackTop = new LoopAwareControlFrame<>(stack.stackTop.invocationLevel, stack.stackTop.argumentConstancyLevels, null);
        stackTop.levelStackMap.putAll(stack.stackTop.levelStackMap);
        frameBuilder = stack.frameBuilder.copy();
    }

    public LoopAwareControlStack<E> startFrame(int invocationLevel, int numArguments) {
        frameBuilder.start(invocationLevel, numArguments);
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgConstant() {
        frameBuilder.setNextArgLevel(0);
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgDependent(int[] dependencies) {
        frameBuilder.setNextArgLevel(getLevel(dependencies));
        return this;
    }

    public LoopAwareControlStack<E> setNextFrameArgVariant(int levelOffset) {
        frameBuilder.setNextArgLevel(getLevel(levelOffset));
        return this;
    }

    public void pushFrame() {
        stackTop = frameBuilder.build(stackTop);
    }

    public int getLevel(int levelOffset) {
        return stackTop.getLevel(levelOffset);
    }

    public int getLevel(int[] dependencies) {
        return stackTop.getLevel(dependencies);
    }

    public void popFrame() {
        stackTop = stackTop.next;
    }

    public Taint<E> copyTagConstant() {
        return stackTop.copyTag(0);
    }

    public Taint<E> copyTagDependent(int[] dependencies) {
        return stackTop.copyTag(getLevel(dependencies));
    }

    public Taint<E> copyTagVariant(int levelOffset) {
        return stackTop.copyTag(getLevel(levelOffset));
    }

    public void pushConstant(Taint<E> tag, int branchID, int branchesSize) {
        stackTop.push(tag, branchID, branchesSize, 0);
    }

    public void pushDependent(Taint<E> tag, int branchID, int branchesSize, int[] dependencies) {
        stackTop.push(tag, branchID, branchesSize, getLevel(dependencies));
    }

    public void pushVariant(Taint<E> tag, int branchID, int branchesSize, int levelOffset) {
        stackTop.push(tag, branchID, branchesSize, getLevel(levelOffset));
    }

    public void pop(int branchID) {
        stackTop.pop(branchID);
    }

    public void reset() {
        stackTop.reset();
    }

    public void exitLoopLevel(int levelOffset) {
        stackTop.exitLoopLevel(levelOffset);
    }

    private static final class LoopAwareControlFrame<E> {

        private final int invocationLevel;
        private final int[] argumentConstancyLevels;
        private final Map<Integer, Node<E>> levelStackMap;
        private int[] branchLevels;
        private LoopAwareControlFrame<E> next;

        private LoopAwareControlFrame(int invocationLevel, int[] argumentConstancyLevels, LoopAwareControlFrame<E> next) {
            this.next = next;
            this.invocationLevel = invocationLevel;
            this.argumentConstancyLevels = argumentConstancyLevels;
            if(next == null) {
                levelStackMap = new HashMap<>();
            } else {
                levelStackMap = new HashMap<>(next.levelStackMap);
            }
        }

        int getLevel(int levelOffset) {
            return invocationLevel + levelOffset;
        }

        int getLevel(int[] dependencies) {
            if(argumentConstancyLevels == null) {
                return 0;
            } else {
                int max = 0;
                for(int dependency : dependencies) {
                    int value = argumentConstancyLevels[dependency];
                    if(value > max) {
                        max = value;
                    }
                }
                return max;
            }
        }

        Taint<E> copyTag(int level) {
            Taint<E> tag = null;
            for(Integer key : levelStackMap.keySet()) {
                if(key <= level) {
                    tag = Taint.combineTags(tag, levelStackMap.get(key).tag);
                }
            }
            return tag;
        }

        void push(Taint<E> tag, int branchID, int branchesSize, int level) {
            if(tag != null && !tag.isEmpty()) {
                if(branchLevels == null) {
                    branchLevels = new int[branchesSize];
                    Arrays.fill(branchLevels, NOT_PUSHED);
                }
                if(!levelStackMap.containsKey(level)) {
                    levelStackMap.put(level, Node.emptyNode());
                }
                if(branchLevels[branchID] == NOT_PUSHED) {
                    branchLevels[branchID] = level;
                    Taint<E> combined = Taint.combineTags(tag, levelStackMap.get(level).tag);
                    levelStackMap.put(level, new Node<>(combined, levelStackMap.get(level)));
                } else {
                    Node<E> r = levelStackMap.get(level);
                    r.tag = r.tag.union(tag);
                }
            }
        }

        void pop(int branchID) {
            if(branchLevels != null && branchLevels[branchID] != NOT_PUSHED) {
                levelStackMap.put(branchLevels[branchID], levelStackMap.get(branchLevels[branchID]).next);
                branchLevels[branchID] = NOT_PUSHED;
            }
        }

        void reset() {
            if(next != null) {
                next.reset();
            }
            branchLevels = null;
            levelStackMap.clear();
        }
{'fraction_non_alphanumeric': 0.09816819317235637, 'fraction_numerical': 0.0011656952539550376, 'mean_word_length': 2.1978168264110756, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3837543', 'n_tokens_mistral': 3533, 'n_tokens_neox': 3321, 'n_words': 638}