Skip to content

Commit 73cc6f2

Browse files
committed
Bump stack limit to 8k and also include current continuation size and escaped iota size in stack limit
1 parent 4da33f5 commit 73cc6f2

File tree

9 files changed

+96
-14
lines changed

9 files changed

+96
-14
lines changed

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingImage.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import net.minecraft.nbt.ListTag
1212
import net.minecraft.nbt.Tag
1313
import net.minecraft.server.level.ServerLevel
1414
import net.minecraft.world.entity.Entity
15+
import kotlin.math.max
1516

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

39+
private val size: Int
40+
private val depth: Int
41+
42+
init {
43+
var maxChildDepth = 0
44+
var totalSize = 1
45+
for (iota in stack) {
46+
totalSize += iota.size()
47+
maxChildDepth = max(maxChildDepth, iota.depth())
48+
}
49+
for (iota in parenthesized) {
50+
totalSize += iota.iota.size()
51+
maxChildDepth = max(maxChildDepth, iota.iota.depth())
52+
}
53+
depth = maxChildDepth
54+
size = totalSize
55+
}
56+
57+
fun size(): Int = size
58+
fun depth(): Int = depth
59+
3860
/**
3961
* Returns an empty list if it's too complicated.
4062
*/

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ import at.petrak.hexcasting.api.casting.math.HexPattern
1515
import at.petrak.hexcasting.api.casting.mishaps.*
1616
import at.petrak.hexcasting.api.utils.*
1717
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds
18+
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
1819
import net.minecraft.nbt.CompoundTag
1920
import net.minecraft.server.level.ServerLevel
21+
import kotlin.math.max
2022

2123
/**
2224
* The virtual machine! This is the glue that determines the next iteration of a [CastingImage], using a
@@ -52,7 +54,10 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
5254
// get caught and folded into CastResult by evaluate.
5355
val image2 = next.evaluate(continuation.next, world, this).let { result ->
5456
// if stack is unable to be serialized, have the result be an error
55-
if (result.newData != null && IotaType.isTooLargeToSerialize(result.newData.stack)) {
57+
val data = result.newData ?: this.image
58+
val size = data.size() + result.continuation.size()
59+
val depth = max(data.depth(), result.continuation.depth())
60+
if (depth >= HexIotaTypes.MAX_SERIALIZATION_DEPTH || size >= HexIotaTypes.MAX_SERIALIZATION_TOTAL) {
5661
result.copy(
5762
newData = null,
5863
sideEffects = listOf(OperatorSideEffect.DoMishap(MishapStackSize(), Mishap.Context(null, null))),

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/ContinuationFrame.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ interface ContinuationFrame {
4646
* Return the number of iotas contained inside this frame, used for determining whether it is valid to serialise.
4747
*/
4848
fun size(): Int
49+
fun depth(): Int
4950

5051
val type: Type<*>
5152

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameEvaluate.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
1313
import net.minecraft.nbt.CompoundTag
1414
import net.minecraft.nbt.Tag
1515
import net.minecraft.server.level.ServerLevel
16+
import kotlin.math.max
1617

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

56-
override fun size() = list.size()
57+
private val size: Int
58+
private val depth: Int
59+
60+
init {
61+
var maxChildDepth = 0
62+
var totalSize = 1
63+
for (iota in list) {
64+
totalSize += iota.size()
65+
maxChildDepth = max(maxChildDepth, iota.depth())
66+
}
67+
depth = maxChildDepth
68+
size = totalSize
69+
}
70+
71+
override fun size() = size
72+
override fun depth() = depth
5773

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

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameFinishEval.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ object FrameFinishEval : ContinuationFrame {
3636
override fun serializeToNBT() = CompoundTag()
3737

3838
override fun size() = 0
39+
override fun depth() = 0
3940

4041
@JvmField
4142
val TYPE: ContinuationFrame.Type<FrameFinishEval> = object : ContinuationFrame.Type<FrameFinishEval> {

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/FrameForEach.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import at.petrak.hexcasting.common.lib.hex.HexIotaTypes
1414
import net.minecraft.nbt.CompoundTag
1515
import net.minecraft.nbt.Tag
1616
import net.minecraft.server.level.ServerLevel
17+
import kotlin.math.max
1718

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

92-
override fun size() = data.size() + code.size() + acc.size + (baseStack?.size ?: 0)
93+
private val size: Int
94+
private val depth: Int
95+
96+
init {
97+
var maxChildDepth = 0
98+
var totalSize = 1
99+
for (iota in data) {
100+
totalSize += iota.size()
101+
maxChildDepth = max(maxChildDepth, iota.depth())
102+
}
103+
for (iota in code) {
104+
totalSize += iota.size()
105+
maxChildDepth = max(maxChildDepth, iota.depth())
106+
}
107+
for (iota in acc) {
108+
totalSize += iota.size()
109+
maxChildDepth = max(maxChildDepth, iota.depth())
110+
}
111+
if (baseStack != null) {
112+
for (iota in baseStack) {
113+
totalSize += iota.size()
114+
maxChildDepth = max(maxChildDepth, iota.depth())
115+
}
116+
}
117+
depth = maxChildDepth
118+
size = totalSize
119+
}
120+
121+
override fun size() = size
122+
override fun depth() = depth
93123

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

Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/SpellContinuation.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,27 @@ import at.petrak.hexcasting.api.utils.getList
55
import net.minecraft.nbt.CompoundTag
66
import net.minecraft.nbt.Tag
77
import net.minecraft.server.level.ServerLevel
8+
import kotlin.math.max
89

910
/**
1011
* A continuation during the execution of a spell.
1112
*/
1213
sealed interface SpellContinuation {
13-
object Done : SpellContinuation
14+
object Done : SpellContinuation {
15+
override fun size(): Int = 0
16+
override fun depth(): Int = 0
17+
}
1418

15-
data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : SpellContinuation
19+
data class NotDone(val frame: ContinuationFrame, val next: SpellContinuation) : SpellContinuation {
20+
override fun size(): Int = frame.size() + next.size()
21+
override fun depth(): Int = max(frame.depth(), next.depth())
22+
}
1623

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

26+
fun size(): Int
27+
fun depth(): Int
28+
1929
fun serializeToNBT() = NBTBuilder {
2030
TAG_FRAME %= list(getNBTFrames())
2131
}

Common/src/main/java/at/petrak/hexcasting/api/casting/iota/ContinuationIota.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,12 @@ public boolean executable() {
5858

5959
@Override
6060
public int size() {
61-
var continuation = this.getContinuation();
62-
var size = 0;
63-
while (continuation instanceof SpellContinuation.NotDone notDone) {
64-
size += 1;
65-
size += notDone.component1().size();
66-
continuation = notDone.component2();
67-
}
61+
return Math.min(this.getContinuation().size(), 1);
62+
}
6863

69-
return Math.min(size, 1);
64+
@Override
65+
public int depth() {
66+
return this.getContinuation().depth() + 1;
7067
}
7168

7269
public static IotaType<ContinuationIota> TYPE = new IotaType<>() {

Common/src/main/java/at/petrak/hexcasting/common/lib/hex/HexIotaTypes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class HexIotaTypes {
2323
KEY_TYPE = HexAPI.MOD_ID + ":type",
2424
KEY_DATA = HexAPI.MOD_ID + ":data";
2525
public static final int MAX_SERIALIZATION_DEPTH = 256;
26-
public static final int MAX_SERIALIZATION_TOTAL = 1024;
26+
public static final int MAX_SERIALIZATION_TOTAL = 8192;
2727

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

0 commit comments

Comments
 (0)