Skip to content

Commit

Permalink
Wasm testsuite traps (#13)
Browse files Browse the repository at this point in the history
* catch arithmetic traps

* memory and table section guards
  • Loading branch information
CharlieTap authored May 27, 2024
1 parent abff527 commit 34176a6
Show file tree
Hide file tree
Showing 46 changed files with 305 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.github.charlietap.chasm.ChasmResult
import io.github.charlietap.chasm.ChasmResult.Error
import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.global
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -28,7 +28,7 @@ fun readGlobal(
internal fun internalReadGlobal(
store: Store,
address: Address.Global,
): Result<ExecutionValue, ModuleRuntimeError> = binding {
): Result<ExecutionValue, ModuleTrapError> = binding {
val global = store.global(address).bind()
global.value
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.github.charlietap.chasm.ChasmResult
import io.github.charlietap.chasm.ChasmResult.Error
import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.global
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -31,7 +31,7 @@ internal fun internalWriteGlobal(
store: Store,
address: Address.Global,
value: ExecutionValue,
): Result<Unit, ModuleRuntimeError> = binding {
): Result<Unit, ModuleTrapError> = binding {
val global = store.global(address).bind()
global.value = value
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.memory.read.MemoryInstanceByteReader
import io.github.charlietap.chasm.executor.memory.read.MemoryInstanceByteReaderImpl
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.memory
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -34,7 +34,7 @@ internal fun readMemory(
address: Address.Memory,
byteOffsetInMemory: Int,
byteReader: MemoryInstanceByteReader,
): Result<Byte, ModuleRuntimeError> = binding {
): Result<Byte, ModuleTrapError> = binding {
val instance = store.memory(address).bind()
byteReader(instance, byteOffsetInMemory).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.memory.size.MemoryInstanceSizer
import io.github.charlietap.chasm.executor.memory.size.MemoryInstanceSizerImpl
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.memory
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -31,7 +31,7 @@ internal fun sizeMemory(
store: Store,
address: Address.Memory,
sizer: MemoryInstanceSizer,
): Result<Int, ModuleRuntimeError> = binding {
): Result<Int, ModuleTrapError> = binding {
val instance = store.memory(address).bind()
sizer(instance).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.memory.write.MemoryInstanceByteWriter
import io.github.charlietap.chasm.executor.memory.write.MemoryInstanceByteWriterImpl
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.memory
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -37,7 +37,7 @@ internal fun writeMemory(
byteOffsetInMemory: Int,
value: Byte,
byteWriter: MemoryInstanceByteWriter,
): Result<Unit, ModuleRuntimeError> = binding {
): Result<Unit, ModuleTrapError> = binding {
val instance = store.memory(address).bind()
byteWriter(instance, value, byteOffsetInMemory).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.github.charlietap.chasm.ChasmResult
import io.github.charlietap.chasm.ChasmResult.Error
import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.element
import io.github.charlietap.chasm.executor.runtime.ext.table
import io.github.charlietap.chasm.executor.runtime.store.Address
Expand All @@ -32,7 +32,7 @@ internal fun internalReadTable(
store: Store,
address: Address.Table,
elementIndex: Int,
): Result<ReferenceValue, ModuleRuntimeError> = binding {
): Result<ReferenceValue, ModuleTrapError> = binding {
val table = store.table(address).bind()
table.element(elementIndex).bind()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.github.charlietap.chasm.ChasmResult
import io.github.charlietap.chasm.ChasmResult.Error
import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.table
import io.github.charlietap.chasm.executor.runtime.store.Address
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -34,7 +34,7 @@ internal fun internalWriteTable(
address: Address.Table,
elementIndex: Int,
value: ReferenceValue,
): Result<Unit, ModuleRuntimeError> = binding {
): Result<Unit, ModuleTrapError> = binding {
val table = store.table(address).bind()
table.elements[elementIndex] = value
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.charlietap.chasm.error

import io.github.charlietap.chasm.decoder.ModuleDecoderError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.validator.ModuleValidatorError
import kotlin.jvm.JvmInline

Expand All @@ -13,5 +13,5 @@ sealed interface ChasmError {
value class ValidationError(val error: ModuleValidatorError) : ChasmError

@JvmInline
value class ExecutionError(val error: ModuleRuntimeError) : ChasmError
value class ExecutionError(val error: ModuleTrapError) : ChasmError
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.github.charlietap.chasm.ChasmResult
import io.github.charlietap.chasm.ChasmResult.Success
import io.github.charlietap.chasm.decoder.ModuleDecoderError
import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import kotlin.jvm.JvmName

@JvmName("decoderToChasmResult")
Expand All @@ -17,6 +17,6 @@ internal fun <S, E> Result<S, E>.toChasmResult(): ChasmResult<S, ChasmError>

@JvmName("executorToChasmResult")
internal fun <S, E> Result<S, E>.toChasmResult(): ChasmResult<S, ChasmError>
where E : ModuleRuntimeError = fold(::Success) { error ->
where E : ModuleTrapError = fold(::Success) { error ->
return ChasmResult.Error(ChasmError.ExecutionError(error))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.github.charlietap.chasm.embedding.memory
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import io.github.charlietap.chasm.executor.memory.read.MemoryInstanceByteReader
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.fixture.instance.memoryAddress
import io.github.charlietap.chasm.fixture.instance.memoryInstance
import io.github.charlietap.chasm.fixture.store
Expand All @@ -28,7 +28,7 @@ class ReadMemoryTest {
Ok(byte)
}

val expected: Result<Byte, ModuleRuntimeError> = Ok(byte)
val expected: Result<Byte, ModuleTrapError> = Ok(byte)

val actual = readMemory(
store = store,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.github.charlietap.chasm.embedding.memory
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import io.github.charlietap.chasm.executor.memory.size.MemoryInstanceSizer
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.fixture.instance.memoryAddress
import io.github.charlietap.chasm.fixture.instance.memoryInstance
import io.github.charlietap.chasm.fixture.store
Expand All @@ -26,7 +26,7 @@ class SizeMemoryTest {
Ok(size)
}

val expected: Result<Int, ModuleRuntimeError> = Ok(size)
val expected: Result<Int, ModuleTrapError> = Ok(size)

val actual = sizeMemory(
store = store,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.github.charlietap.chasm.embedding.memory
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import io.github.charlietap.chasm.executor.memory.write.MemoryInstanceByteWriter
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.fixture.instance.memoryAddress
import io.github.charlietap.chasm.fixture.instance.memoryInstance
import io.github.charlietap.chasm.fixture.store
Expand All @@ -29,7 +29,7 @@ class WriteMemoryTest {
Ok(Unit)
}

val expected: Result<Unit, ModuleRuntimeError> = Ok(Unit)
val expected: Result<Unit, ModuleTrapError> = Ok(Unit)

val actual = writeMemory(
store = store,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.charlietap.chasm.script.action

import io.github.charlietap.chasm.error.ChasmError
import io.github.charlietap.chasm.executor.runtime.value.ExecutionValue
import io.github.charlietap.sweet.lib.command.Command
import kotlin.jvm.JvmInline
Expand All @@ -12,5 +13,6 @@ sealed interface ActionResult {
data class Failure(
val command: Command,
val reason: String,
val error: ChasmError? = null,
) : ActionResult
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ private fun ActionRunner(
invokeActionRunner: InvokeActionRunner,
getActionRunner: GetActionRunner,
): ActionResult = when (action) {
is InvokeAction -> invokeActionRunner(context, action)
is InvokeAction -> invokeActionRunner(context, command, action)
is GetAction -> getActionRunner(context, command, action)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.github.charlietap.chasm.script.action

import io.github.charlietap.chasm.embedding.global.readGlobal
import io.github.charlietap.chasm.executor.runtime.instance.ExternalValue
import io.github.charlietap.chasm.expect
import io.github.charlietap.chasm.fold
import io.github.charlietap.chasm.script.ScriptContext
import io.github.charlietap.sweet.lib.action.GetAction
import io.github.charlietap.sweet.lib.command.Command
Expand All @@ -22,5 +22,11 @@ fun GetActionRunner(

val result = readGlobal(context.store, global.address)

return ActionResult.Success(listOf(result.expect("Get action failed")))
return result.fold(
{ globalValue ->
ActionResult.Success(listOf(globalValue))
},
) { error ->
ActionResult.Failure(command, "get action returned an error", error)
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
package io.github.charlietap.chasm.script.action

import io.github.charlietap.chasm.embedding.invoke
import io.github.charlietap.chasm.expect
import io.github.charlietap.chasm.fold
import io.github.charlietap.chasm.script.ScriptContext
import io.github.charlietap.chasm.script.action.ActionResult.Success
import io.github.charlietap.chasm.script.value.ValueMapper
import io.github.charlietap.sweet.lib.action.InvokeAction
import io.github.charlietap.sweet.lib.command.Command

typealias InvokeActionRunner = (ScriptContext, InvokeAction) -> ActionResult
typealias InvokeActionRunner = (ScriptContext, Command, InvokeAction) -> ActionResult

fun InvokeActionRunner(
context: ScriptContext,
command: Command,
action: InvokeAction,
) = InvokeActionRunner(
context = context,
command = command,
action = action,
valueMapper = ::ValueMapper,
)

private fun InvokeActionRunner(
context: ScriptContext,
command: Command,
action: InvokeAction,
valueMapper: ValueMapper,
): ActionResult {
return invoke(
val result = invoke(
context.store,
context.instances[action.moduleName]!!,
action.field,
action.args.mapNotNull(valueMapper),
).expect("Invoke failed").let(::Success)
)

return result.fold({ results ->
ActionResult.Success(results)
}) { error ->
ActionResult.Failure(command, "invoke action returned an error", error)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.charlietap.chasm.script.command

import io.github.charlietap.chasm.error.ChasmError
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.AssertTrapCommand

Expand All @@ -15,12 +17,23 @@ fun AssertTrapCommandRunner(
actionRunner = ::ActionRunner,
)

@Suppress("UNUSED_PARAMETER")
private fun AssertTrapCommandRunner(
context: ScriptContext,
command: AssertTrapCommand,
actionRunner: ActionRunner,
): CommandResult {
println("ignoring AssertTrapCommand")
return CommandResult.Success

return when (val result = actionRunner(context, command, command.action)) {
is ActionResult.Success -> {
CommandResult.Failure(command, "expected trap ${command.text} but action succeeded")
}
is ActionResult.Failure -> {

if (result.error is ChasmError.ExecutionError) {
CommandResult.Success
} else {
CommandResult.Failure(command, "expected trap but encountered error ${result.error} with reason ${result.reason}")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package io.github.charlietap.chasm.executor.instantiator

import com.github.michaelbull.result.Result
import io.github.charlietap.chasm.ast.module.Module
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.instance.ExternalValue
import io.github.charlietap.chasm.executor.runtime.instance.ModuleInstance
import io.github.charlietap.chasm.executor.runtime.store.Store

typealias ModuleInstantiator = (Store, Module, List<ExternalValue>) -> Result<ModuleInstance, ModuleRuntimeError>
typealias ModuleInstantiator = (Store, Module, List<ExternalValue>) -> Result<ModuleInstance, ModuleTrapError>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import io.github.charlietap.chasm.executor.invoker.FunctionInvoker
import io.github.charlietap.chasm.executor.invoker.FunctionInvokerImpl
import io.github.charlietap.chasm.executor.runtime.Arity
import io.github.charlietap.chasm.executor.runtime.error.InstantiationError
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.instance.ExternalValue
import io.github.charlietap.chasm.executor.runtime.instance.ModuleInstance
import io.github.charlietap.chasm.executor.runtime.store.Store
Expand All @@ -28,7 +28,7 @@ fun ModuleInstantiatorImpl(
store: Store,
module: Module,
imports: List<ExternalValue>,
): Result<ModuleInstance, ModuleRuntimeError> =
): Result<ModuleInstance, ModuleTrapError> =
ModuleInstantiatorImpl(
store = store,
module = module,
Expand All @@ -51,7 +51,7 @@ internal fun ModuleInstantiatorImpl(
evaluator: ExpressionEvaluator,
tableInitializer: TableInitializer,
memoryInitializer: MemoryInitializer,
): Result<ModuleInstance, ModuleRuntimeError> = binding {
): Result<ModuleInstance, ModuleTrapError> = binding {
// todo module validation

if (module.imports.size != imports.size) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.github.charlietap.chasm.executor.instantiator.classification

import com.github.michaelbull.result.Result
import io.github.charlietap.chasm.executor.runtime.error.ModuleRuntimeError
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.instance.ExternalValue
import io.github.charlietap.chasm.executor.runtime.store.Store

internal typealias ExternalValueClassifier = (Store, ExternalValue) -> Result<ClassifiedExternalValue, ModuleRuntimeError>
internal typealias ExternalValueClassifier = (Store, ExternalValue) -> Result<ClassifiedExternalValue, ModuleTrapError>
Loading

0 comments on commit 34176a6

Please sign in to comment.