Skip to content

Commit

Permalink
Bump stack limit to 8k and also include current continuation size and…
Browse files Browse the repository at this point in the history
… escaped iota size in stack limit
  • Loading branch information
vgskye committed Nov 28, 2024
1 parent 4da33f5 commit 73cc6f2
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.Entity
import kotlin.math.max

/**
* The state of a casting VM, containing the stack and all
Expand All @@ -35,6 +36,27 @@ data class CastingImage private constructor(
}
}

private val size: Int
private val depth: Int

init {
var maxChildDepth = 0
var totalSize = 1
for (iota in stack) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
for (iota in parenthesized) {
totalSize += iota.iota.size()
maxChildDepth = max(maxChildDepth, iota.iota.depth())
}
depth = maxChildDepth
size = totalSize
}

fun size(): Int = size
fun depth(): Int = depth

/**
* Returns an empty list if it's too complicated.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ import at.petrak.hexcasting.api.casting.math.HexPattern
import at.petrak.hexcasting.api.casting.mishaps.*
import at.petrak.hexcasting.api.utils.*
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerLevel
import kotlin.math.max

/**
* The virtual machine! This is the glue that determines the next iteration of a [CastingImage], using a
Expand Down Expand Up @@ -52,7 +54,10 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
// get caught and folded into CastResult by evaluate.
val image2 = next.evaluate(continuation.next, world, this).let { result ->
// if stack is unable to be serialized, have the result be an error
if (result.newData != null && IotaType.isTooLargeToSerialize(result.newData.stack)) {
val data = result.newData ?: this.image
val size = data.size() + result.continuation.size()
val depth = max(data.depth(), result.continuation.depth())
if (depth >= HexIotaTypes.MAX_SERIALIZATION_DEPTH || size >= HexIotaTypes.MAX_SERIALIZATION_TOTAL) {
result.copy(
newData = null,
sideEffects = listOf(OperatorSideEffect.DoMishap(MishapStackSize(), Mishap.Context(null, null))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ interface ContinuationFrame {
* Return the number of iotas contained inside this frame, used for determining whether it is valid to serialise.
*/
fun size(): Int
fun depth(): Int

val type: Type<*>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel
import kotlin.math.max

/**
* A list of patterns to be evaluated in sequence.
Expand Down Expand Up @@ -53,7 +54,22 @@ data class FrameEvaluate(val list: SpellList, val isMetacasting: Boolean) : Cont
"isMetacasting" %= isMetacasting
}

override fun size() = list.size()
private val size: Int
private val depth: Int

init {
var maxChildDepth = 0
var totalSize = 1
for (iota in list) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
depth = maxChildDepth
size = totalSize
}

override fun size() = size
override fun depth() = depth

override val type: ContinuationFrame.Type<*> = TYPE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ object FrameFinishEval : ContinuationFrame {
override fun serializeToNBT() = CompoundTag()

override fun size() = 0
override fun depth() = 0

@JvmField
val TYPE: ContinuationFrame.Type<FrameFinishEval> = object : ContinuationFrame.Type<FrameFinishEval> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel
import kotlin.math.max

/**
* A frame representing all the state for a Thoth evaluation.
Expand Down Expand Up @@ -89,7 +90,36 @@ data class FrameForEach(
"accumulator" %= acc.serializeToNBT()
}

override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0)
private val size: Int
private val depth: Int

init {
var maxChildDepth = 0
var totalSize = 1
for (iota in data) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
for (iota in code) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
for (iota in acc) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
if (baseStack != null) {
for (iota in baseStack) {
totalSize += iota.size()
maxChildDepth = max(maxChildDepth, iota.depth())
}
}
depth = maxChildDepth
size = totalSize
}

override fun size() = size
override fun depth() = depth

override val type: ContinuationFrame.Type<*> = TYPE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,27 @@ import at.petrak.hexcasting.api.utils.getList
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.server.level.ServerLevel
import kotlin.math.max

/**
* A continuation during the execution of a spell.
*/
sealed interface SpellContinuation {
object Done : SpellContinuation
object Done : SpellContinuation {
override fun size(): Int = 0
override fun depth(): Int = 0
}

data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : SpellContinuation
data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : SpellContinuation {
override fun size(): Int = frame.size() + next.size()
override fun depth(): Int = max(frame.depth(), next.depth())
}

fun pushFrame(frame: ContinuationFrame): SpellContinuation = NotDone(frame, this)

fun size(): Int
fun depth(): Int

fun serializeToNBT() = NBTBuilder {
TAG_FRAME %= list(getNBTFrames())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,12 @@ public boolean executable() {

@Override
public int size() {
var continuation = this.getContinuation();
var size = 0;
while (continuation instanceof SpellContinuation.NotDone notDone) {
size += 1;
size += notDone.component1().size();
continuation = notDone.component2();
}
return Math.min(this.getContinuation().size(), 1);
}

return Math.min(size, 1);
@Override
public int depth() {
return this.getContinuation().depth() + 1;
}

public static IotaType<ContinuationIota> TYPE = new IotaType<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class HexIotaTypes {
KEY_TYPE = HexAPI.MOD_ID + ":type",
KEY_DATA = HexAPI.MOD_ID + ":data";
public static final int MAX_SERIALIZATION_DEPTH = 256;
public static final int MAX_SERIALIZATION_TOTAL = 1024;
public static final int MAX_SERIALIZATION_TOTAL = 8192;

public static void registerTypes(BiConsumer<IotaType<?>, ResourceLocation> r) {
for (var e : TYPES.entrySet()) {
Expand Down

0 comments on commit 73cc6f2

Please sign in to comment.