Skip to content

Commit

Permalink
Wasm testsuite exhaustion (#16)
Browse files Browse the repository at this point in the history
* add check to ensure stack frame depth is capped

* throw error on call stacks greater than 1028
  • Loading branch information
CharlieTap committed Jun 9, 2024
1 parent 4cb170e commit a4275d4
Show file tree
Hide file tree
Showing 52 changed files with 268 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
package io.github.charlietap.chasm.script.command

import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.script.ScriptContext
import io.github.charlietap.chasm.script.action.ActionResult
import io.github.charlietap.chasm.script.action.ActionRunner
import io.github.charlietap.sweet.lib.command.AssertExhaustionCommand

typealias AssertExhaustionCommandRunner = (AssertExhaustionCommand) -> CommandResult
typealias AssertExhaustionCommandRunner = (ScriptContext, AssertExhaustionCommand) -> CommandResult

@Suppress("UNUSED_PARAMETER")
fun AssertExhaustionCommandRunner(
context: ScriptContext,
command: AssertExhaustionCommand,
): CommandResult = AssertExhaustionCommandRunner(
context = context,
command = command,
actionRunner = ::ActionRunner,
)

fun AssertExhaustionCommandRunner(
context: ScriptContext,
command: AssertExhaustionCommand,
actionRunner: ActionRunner,
): CommandResult {
println("ignoring AssertExhaustionCommand")
return CommandResult.Success
return when (val result = actionRunner(context, command, command.action)) {
is ActionResult.Success -> {
CommandResult.Failure(command, "exhaustion command succeeded when it should have failed")
}
is ActionResult.Failure -> {
val error = result.error
if (error is ChasmError.ExecutionError && error.error is InvocationError.CallStackExhausted) {
CommandResult.Success
} else {
CommandResult.Failure(command, result.reason)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private fun CommandRunner(
registerCommandRunner: RegisterCommandRunner,
): CommandResult = when (command) {
is ActionCommand -> actionCommandRunner(context, command)
is AssertExhaustionCommand -> assertExhaustionCommandRunner(command)
is AssertExhaustionCommand -> assertExhaustionCommandRunner(context, command)
is AssertInvalidCommand -> assertInvalidCommandRunner(command)
is AssertMalformedCommand -> assertMalformedCommandRunner(context, command)
is AssertReturnCommand -> assertReturnCommandRunner(context, command)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.popFrame
import io.github.charlietap.chasm.executor.runtime.ext.popInstruction
import io.github.charlietap.chasm.executor.runtime.ext.popLabel
import io.github.charlietap.chasm.executor.runtime.ext.popValue
import io.github.charlietap.chasm.executor.runtime.ext.pushFrame
import io.github.charlietap.chasm.executor.runtime.instance.FunctionInstance
import io.github.charlietap.chasm.executor.runtime.instruction.AdminInstruction
import io.github.charlietap.chasm.executor.runtime.instruction.ModuleInstruction
Expand Down Expand Up @@ -87,7 +88,7 @@ internal inline fun WasmFunctionCallImpl(
),
)

stack.push(frame)
stack.pushFrame(frame).bind()

val label = Stack.Entry.Label(
arity = Arity.Return(type.results.types.size),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import io.github.charlietap.chasm.ast.type.AbstractHeapType
import io.github.charlietap.chasm.executor.runtime.Stack
import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.ext.popReference
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

internal fun AnyConvertExternExecutorImpl(
stack: Stack,
): Result<Unit, InvocationError> = binding {
when (val referenceValue = stack.popReference().bind()) {
is ReferenceValue.Null -> {
stack.push(ReferenceValue.Null(AbstractHeapType.Any))
stack.pushValue(ReferenceValue.Null(AbstractHeapType.Any))
}
is ReferenceValue.Extern -> {
stack.push(referenceValue.referenceValue)
stack.pushValue(referenceValue.referenceValue)
}
else -> Err(InvocationError.UnexpectedReferenceValue).bind<Unit>()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.arrayType
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.runtime.value.NumberValue
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
Expand Down Expand Up @@ -80,35 +80,35 @@ internal fun ArrayCopyExecutorImpl(
if (elementsToCopy == 0) return@binding

if (destinationOffset <= sourceOffset) {
stack.push(destReference)
stack.push(NumberValue.I32(destinationOffset))
stack.push(srcReference)
stack.push(NumberValue.I32(sourceOffset))
stack.pushValue(destReference)
stack.pushValue(NumberValue.I32(destinationOffset))
stack.pushValue(srcReference)
stack.pushValue(NumberValue.I32(sourceOffset))

arrayGetExecutor(store, stack, srcTypeIndex, false).bind()
arraySetExecutor(store, stack, destTypeIndex).bind()

stack.push(destReference)
stack.push(NumberValue.I32(destinationOffset + 1))
stack.push(srcReference)
stack.push(NumberValue.I32(sourceOffset + 1))
stack.pushValue(destReference)
stack.pushValue(NumberValue.I32(destinationOffset + 1))
stack.pushValue(srcReference)
stack.pushValue(NumberValue.I32(sourceOffset + 1))
} else {

stack.push(destReference)
stack.push(NumberValue.I32(destinationOffset + elementsToCopy - 1))
stack.push(srcReference)
stack.push(NumberValue.I32(sourceOffset + elementsToCopy - 1))
stack.pushValue(destReference)
stack.pushValue(NumberValue.I32(destinationOffset + elementsToCopy - 1))
stack.pushValue(srcReference)
stack.pushValue(NumberValue.I32(sourceOffset + elementsToCopy - 1))

arrayGetExecutor(store, stack, srcTypeIndex, false).bind()
arraySetExecutor(store, stack, destTypeIndex).bind()

stack.push(destReference)
stack.push(NumberValue.I32(destinationOffset))
stack.push(srcReference)
stack.push(NumberValue.I32(sourceOffset))
stack.pushValue(destReference)
stack.pushValue(NumberValue.I32(destinationOffset))
stack.pushValue(srcReference)
stack.pushValue(NumberValue.I32(sourceOffset))
}

stack.push(NumberValue.I32(elementsToCopy - 1))
stack.pushValue(NumberValue.I32(elementsToCopy - 1))
ArrayCopyExecutorImpl(
store,
stack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.array
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.popValue
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.runtime.value.NumberValue

Expand Down Expand Up @@ -47,16 +47,16 @@ internal fun ArrayFillExecutorImpl(

if (elementsToFill == 0) return@binding

stack.push(arrayReference)
stack.push(NumberValue.I32(arrayElementOffset))
stack.pushValue(arrayReference)
stack.pushValue(NumberValue.I32(arrayElementOffset))
stack.push(fillValue)

arraySetExecutor(store, stack, typeIndex).bind()

stack.push(arrayReference)
stack.push(NumberValue.I32(arrayElementOffset + 1))
stack.pushValue(arrayReference)
stack.pushValue(NumberValue.I32(arrayElementOffset + 1))
stack.push(fillValue)
stack.push(NumberValue.I32(elementsToFill - 1))
stack.pushValue(NumberValue.I32(elementsToFill - 1))

ArrayFillExecutorImpl(store, stack, typeIndex, arraySetExecutor).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.field
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpanderImpl
Expand Down Expand Up @@ -58,5 +58,5 @@ internal inline fun ArrayGetExecutorImpl(

val unpackedValue = fieldUnpacker(fieldValue, fieldType, signedUnpack).bind()

stack.push(unpackedValue)
stack.pushValue(unpackedValue)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.dataAddress
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.runtime.value.NumberValue
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
Expand Down Expand Up @@ -78,17 +78,17 @@ internal fun ArrayInitDataExecutorImpl(
val byteArray = dataInstance.bytes.sliceArray(sourceOffsetInByteArray until endOffsetInByteArray)
val element = arrayType.fieldType.valueFromBytes(byteArray).bind()

stack.push(arrayReference)
stack.push(NumberValue.I32(destinationOffsetInArray))
stack.push(element)
stack.pushValue(arrayReference)
stack.pushValue(NumberValue.I32(destinationOffsetInArray))
stack.pushValue(element)

arraySetExecutor(store, stack, typeIndex).bind()

stack.push(arrayReference)
stack.pushValue(arrayReference)

stack.push(NumberValue.I32(destinationOffsetInArray + 1))
stack.push(NumberValue.I32(sourceOffsetInByteArray + arrayElementSizeInBytes))
stack.push(NumberValue.I32(elementsToCopy - 1))
stack.pushValue(NumberValue.I32(destinationOffsetInArray + 1))
stack.pushValue(NumberValue.I32(sourceOffsetInByteArray + arrayElementSizeInBytes))
stack.pushValue(NumberValue.I32(elementsToCopy - 1))

ArrayInitDataExecutorImpl(store, stack, typeIndex, dataIndex, definedTypeExpander, arraySetExecutor).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.elementAddress
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.runtime.value.NumberValue
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
Expand Down Expand Up @@ -72,17 +72,17 @@ internal fun ArrayInitElementExecutorImpl(

val element = elementInstance.elements[sourceOffsetInElementSegment]

stack.push(arrayReference)
stack.push(NumberValue.I32(destinationOffsetInArray))
stack.push(element)
stack.pushValue(arrayReference)
stack.pushValue(NumberValue.I32(destinationOffsetInArray))
stack.pushValue(element)

arraySetExecutor(store, stack, typeIndex).bind()

stack.push(arrayReference)
stack.pushValue(arrayReference)

stack.push(NumberValue.I32(destinationOffsetInArray + 1))
stack.push(NumberValue.I32(sourceOffsetInElementSegment + 1))
stack.push(NumberValue.I32(elementsToCopy - 1))
stack.pushValue(NumberValue.I32(destinationOffsetInArray + 1))
stack.pushValue(NumberValue.I32(sourceOffsetInElementSegment + 1))
stack.pushValue(NumberValue.I32(elementsToCopy - 1))

ArrayInitElementExecutorImpl(store, stack, typeIndex, elementIndex, definedTypeExpander, arraySetExecutor).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.github.charlietap.chasm.executor.runtime.Stack
import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.ext.array
import io.github.charlietap.chasm.executor.runtime.ext.popArrayReference
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.runtime.value.NumberValue

Expand All @@ -19,5 +19,5 @@ internal fun ArrayLenExecutorImpl(
val arrayReference = stack.popArrayReference().bind()
val arrayInstance = store.array(arrayReference.address).bind()

stack.push(NumberValue.I32(arrayInstance.fields.size))
stack.pushValue(NumberValue.I32(arrayInstance.fields.size))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.data
import io.github.charlietap.chasm.executor.runtime.ext.dataAddress
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpanderImpl
Expand Down Expand Up @@ -68,7 +68,7 @@ internal inline fun ArrayNewDataExecutorImpl(
val elementBytes = byteArray.sliceArray(i until i + arrayElementSizeInBytes)
val value = arrayType.fieldType.valueFromBytes(elementBytes).bind()

stack.push(value)
stack.pushValue(value)
}

arrayNewFixedExecutor(store, stack, typeIndex, arrayLength.toUInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.arrayType
import io.github.charlietap.chasm.executor.runtime.ext.default
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpander
import io.github.charlietap.chasm.executor.type.expansion.DefinedTypeExpanderImpl
Expand Down Expand Up @@ -46,7 +46,7 @@ internal inline fun ArrayNewDefaultExecutorImpl(
val size = stack.popI32().bind()
val value = arrayType.fieldType.default().bind()
repeat(size) {
stack.push(value)
stack.pushValue(value)
}

arrayNewFixedExecutor(store, stack, typeIndex, size.toUInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import io.github.charlietap.chasm.executor.runtime.ext.element
import io.github.charlietap.chasm.executor.runtime.ext.elementAddress
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popI32
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.store.Store

internal fun ArrayNewElementExecutorImpl(
Expand Down Expand Up @@ -54,7 +54,7 @@ internal inline fun ArrayNewElementExecutorImpl(
elementInstance.elements
.slice(arrayStartOffsetInSegment until arrayEndOffsetInSegment)
.forEach { referenceValue ->
stack.push(referenceValue)
stack.pushValue(referenceValue)
}

arrayNewFixedExecutor(store, stack, typeIndex, arrayLength.toUInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.ext.arrayType
import io.github.charlietap.chasm.executor.runtime.ext.peekFrame
import io.github.charlietap.chasm.executor.runtime.ext.popValue
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.instance.ArrayInstance
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand Down Expand Up @@ -61,5 +61,5 @@ internal inline fun ArrayNewFixedExecutorImpl(
val address = Address.Array(store.arrays.size - 1)
val reference = ReferenceValue.Array(address, instance)

stack.push(reference)
stack.pushValue(reference)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import io.github.charlietap.chasm.ast.type.AbstractHeapType
import io.github.charlietap.chasm.executor.runtime.Stack
import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.ext.popReference
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

internal fun ExternConvertAnyExecutorImpl(
stack: Stack,
): Result<Unit, InvocationError> = binding {
when (val referenceValue = stack.popReference().bind()) {
is ReferenceValue.Null -> {
stack.push(ReferenceValue.Null(AbstractHeapType.Extern))
stack.pushValue(ReferenceValue.Null(AbstractHeapType.Extern))
}
else -> {
stack.push(ReferenceValue.Extern(referenceValue))
stack.pushValue(ReferenceValue.Extern(referenceValue))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.ext.extendSigned
import io.github.charlietap.chasm.executor.runtime.ext.extendUnsigned
import io.github.charlietap.chasm.executor.runtime.ext.popI31Reference
import io.github.charlietap.chasm.executor.runtime.ext.push
import io.github.charlietap.chasm.executor.runtime.ext.pushValue
import io.github.charlietap.chasm.executor.runtime.value.NumberValue
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

Expand Down Expand Up @@ -39,5 +39,5 @@ internal inline fun I31GetExecutorImpl(
i31UnsignedExtender(value)
}

stack.push(NumberValue.I32(extended))
stack.pushValue(NumberValue.I32(extended))
}
Loading

0 comments on commit a4275d4

Please sign in to comment.