All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.weeaboo.lua2.vm.DeadSlot Maven / Gradle / Ivy

package nl.weeaboo.lua2.vm;

import java.lang.ref.WeakReference;

import javax.annotation.Nullable;

import nl.weeaboo.lua2.io.LuaSerializable;

/**
 * A Slot whose value has been set to nil. The key is kept in a weak reference so that it can be found by
 * next().
 */
@LuaSerializable
final class DeadSlot implements ISlot {

    private final Object key;
    private @Nullable ISlot next;

    DeadSlot(LuaValue key, ISlot next) {
        this.key = LuaTable.isLargeKey(key) ? new WeakReference<>(key) : key;
        this.next = next;
    }

    private LuaValue key() {
        if (key instanceof WeakReference) {
            return (LuaValue)((WeakReference)key).get();
        } else {
            return (LuaValue)key;
        }
    }

    @Override
    public int keyindex(int hashMask) {
        // Not needed: this entry will be dropped during rehash.
        return 0;
    }

    @Override
    public @Nullable IStrongSlot first() {
        return null;
    }

    @Override
    public @Nullable IStrongSlot find(LuaValue key) {
        return null;
    }

    @Override
    public boolean keyeq(LuaValue key) {
        LuaValue k = key();
        return k != null && key.raweq(k);
    }

    @Override
    public @Nullable ISlot rest() {
        return next;
    }

    @Override
    public int arraykey(int max) {
        return -1;
    }

    @Override
    public @Nullable ISlot set(IStrongSlot target, LuaValue value) {
        ISlot next = (this.next != null) ? this.next.set(target, value) : null;
        if (key() != null) {
            // if key hasn't been garbage collected, it is still potentially a valid argument
            // to next(), so we can't drop this entry yet.
            this.next = next;
            return this;
        } else {
            return next;
        }
    }

    @Override
    public ISlot add(ISlot newEntry) {
        return (next != null) ? next.add(newEntry) : newEntry;
    }

    @Override
    public ISlot remove(IStrongSlot target) {
        if (key() != null) {
            if (next != null) {
                next = next.remove(target);
            }
            return this;
        } else {
            ISlot result = next;
            if (result == null) {
                throw new NullPointerException("Unable to remove slot: next is null");
            }
            return result;
        }
    }

    @Override
    public ISlot relink(ISlot rest) {
        return rest;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();
        buf.append("');
        if (next != null) {
            buf.append("; ");
            buf.append(next.toString());
        }
        return buf.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy