Skip to content

Commit

Permalink
refactor table and element instances to use arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlieTap committed May 19, 2024
1 parent 31bce75 commit 1536489
Show file tree
Hide file tree
Showing 19 changed files with 82 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ReadTableTest {

val functionAddress = functionAddress()
val value = ReferenceValue.Function(functionAddress)
val instance = tableInstance(elements = mutableListOf(value))
val instance = tableInstance(elements = arrayOf(value))
val store = store(tables = mutableListOf(instance))
val address = Address.Table(0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class WriteTableTest {

val functionAddress = functionAddress()
val value = ReferenceValue.Function(functionAddress)
val instance = tableInstance(elements = mutableListOf(ReferenceValue.Null(AbstractHeapType.Func)))
val instance = tableInstance(elements = arrayOf(ReferenceValue.Null(AbstractHeapType.Func)))
val store = store(tables = mutableListOf(instance))
val address = Address.Table(0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal fun ElementAllocatorImpl(
values: List<ReferenceValue>,
): Address.Element {

val instance = ElementInstance(type, values.toMutableList())
val instance = ElementInstance(type, values.toTypedArray())

store.elements.add(instance)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fun TableAllocatorImpl(
reference: ReferenceValue,
): Address.Table {

val elements = MutableList(type.limits.min.toInt()) { reference }
val elements = Array(type.limits.min.toInt()) { reference }
val instance = TableInstance(type, elements)

store.tables.add(instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ElementAllocatorImplTest {

val expected = ElementInstance(
type = refType,
elements = mutableListOf(),
elements = arrayOf(),
)

val address = ElementAllocatorImpl(store, refType, emptyList())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class TableAllocatorImplTest {
val type = tableType(limits = limits)

val refValue = ReferenceValue.Null(AbstractHeapType.Func)
val elements = MutableList<ReferenceValue>(min) {
val elements = Array<ReferenceValue>(min) {
refValue
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal inline fun ElementDropExecutorImpl(
val elementInstance = store.element(elementAddress).bind()

store.elements[elementAddress.address] = elementInstance.copy(
elements = mutableListOf(),
elements = arrayOf(),
dropped = true,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,5 @@ internal fun TableFillExecutorImpl(

if (elementsToFill == 0) return@binding

fillRange.forEach { tableIndex ->
tableInstance.elements[tableIndex] = fillValue
}
tableInstance.elements.fill(fillValue, fillRange.first, fillRange.last + 1)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ package io.github.charlietap.chasm.executor.invoker.instruction.table

import com.github.michaelbull.result.Result
import com.github.michaelbull.result.binding
import com.github.michaelbull.result.fold
import io.github.charlietap.chasm.ast.instruction.TableInstruction
import io.github.charlietap.chasm.executor.invoker.ext.index
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.grow
import io.github.charlietap.chasm.executor.runtime.ext.asRange
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.popReference
Expand All @@ -27,17 +26,26 @@ internal inline fun TableGrowExecutorImpl(
val frame = stack.peekFrame().bind()
val tableAddress = frame.state.module.tableAddress(instruction.tableIdx.index()).bind()
val tableInstance = store.table(tableAddress).bind()
val tableType = tableInstance.type

val tableSize = tableInstance.elements.size
val elementsToAdd = stack.popI32().bind()
val referenceValue = stack.popReference().bind()

val result = tableInstance.grow(elementsToAdd, referenceValue)

result.fold({ newInstance ->
store.tables[tableAddress.address] = newInstance
stack.push(Stack.Entry.Value(NumberValue.I32(tableSize)))
}, {
val proposedLength = (tableSize + elementsToAdd).toUInt()
if (proposedLength !in tableType.limits.asRange()) {
stack.push(Stack.Entry.Value(NumberValue.I32(-1)))
})
return@binding
}

tableInstance.apply {
type = type.copy(
limits = type.limits.copy(
min = proposedLength,
),
)
elements += Array(elementsToAdd) { referenceValue }
}

stack.push(Stack.Entry.Value(NumberValue.I32(tableSize)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,5 @@ internal fun TableInitExecutorImpl(

if (elementsToInitialise == 0) return@binding

for (srcOffset in srcRange) {
tableInstance.elements[tableOffset + srcOffset - srcRange.first] = elementInstance.elements[srcOffset]
}
elementInstance.elements.copyInto(tableInstance.elements, dstRange.first, srcRange.first, srcRange.last + 1)
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class ArrayInitElementExecutorImplTest {
val elementToCopy = i31ReferenceValue()
val elementAddress = elementAddress(0)
val elementInstance = elementInstance(
elements = mutableListOf(
elements = arrayOf(
elementToCopy,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ArrayNewElementExecutorImplTest {
val arrayElem2 = ReferenceValue.I31(118u)

val elementInstance = elementInstance(
elements = mutableListOf(
elements = arrayOf(
referenceValue(),
referenceValue(),
referenceValue(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CallIndirectExecutorImplTest {
val tableIndex = tableIndex(0u)
val tableAddress = tableAddress()
val tableInstance = tableInstance(
elements = mutableListOf(ReferenceValue.Function(functionAddress)),
elements = arrayOf(ReferenceValue.Function(functionAddress)),
)
val elementIndex = 0

Expand Down Expand Up @@ -101,7 +101,7 @@ class CallIndirectExecutorImplTest {
val tableIndex = tableIndex(0u)
val tableAddress = tableAddress()
val tableInstance = tableInstance(
elements = mutableListOf(ReferenceValue.Function(functionAddress)),
elements = arrayOf(ReferenceValue.Function(functionAddress)),
)
val elementIndex = 0

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@file:Suppress("NOTHING_TO_INLINE")

package io.github.charlietap.chasm.executor.runtime.ext

import io.github.charlietap.chasm.ast.type.Limits

inline fun Limits.asRange() = min..(max ?: UInt.MAX_VALUE)
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,12 @@

package io.github.charlietap.chasm.executor.runtime.ext

import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import com.github.michaelbull.result.toResultOr
import io.github.charlietap.chasm.executor.runtime.error.InvocationError
import io.github.charlietap.chasm.executor.runtime.instance.TableInstance
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

inline fun TableInstance.grow(
elementsToAdd: Int,
initialisationValue: ReferenceValue,
): Result<TableInstance, InvocationError> {

val proposedLength = (elementsToAdd + elements.size).toUInt()

val range = type.limits.min..(type.limits.max ?: UInt.MAX_VALUE)
if (proposedLength !in range) {
return Err(InvocationError.TableGrowExceedsLimits(proposedLength))
}

repeat(elementsToAdd) {
elements.add(initialisationValue)
}

val newLimits = type.limits.copy(min = proposedLength)

return Ok(copy(type.copy(limits = newLimits)))
}

inline fun TableInstance.element(
elementIndex: Int,
): Result<ReferenceValue, InvocationError.TableElementLookupFailed> = elements.getOrNull(elementIndex).toResultOr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

data class ElementInstance(
val type: ReferenceType,
val elements: MutableList<ReferenceValue>,
val elements: Array<ReferenceValue>,
val dropped: Boolean = false,
)
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as ElementInstance

if (type != other.type) return false
if (!elements.contentEquals(other.elements)) return false
if (dropped != other.dropped) return false

return true
}

override fun hashCode(): Int {
var result = type.hashCode()
result = 31 * result + elements.contentHashCode()
result = 31 * result + dropped.hashCode()
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ import io.github.charlietap.chasm.ast.type.TableType
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue

data class TableInstance(
val type: TableType,
val elements: MutableList<ReferenceValue>,
)
var type: TableType,
var elements: Array<ReferenceValue>,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as TableInstance

if (type != other.type) return false
if (!elements.contentEquals(other.elements)) return false

return true
}

override fun hashCode(): Int {
var result = type.hashCode()
result = 31 * result + elements.contentHashCode()
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.github.charlietap.chasm.fixture.type.referenceType

fun elementInstance(
type: ReferenceType = referenceType(),
elements: MutableList<ReferenceValue> = mutableListOf(),
elements: Array<ReferenceValue> = arrayOf(),
dropped: Boolean = false,
) = ElementInstance(
type = type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.github.charlietap.chasm.fixture.type.tableType

fun tableInstance(
type: TableType = tableType(),
elements: MutableList<ReferenceValue> = mutableListOf(),
elements: Array<ReferenceValue> = arrayOf(),
) = TableInstance(
type = type,
elements = elements,
Expand Down

0 comments on commit 1536489

Please sign in to comment.