Skip to content

Commit

Permalink
ref test bytecode fusion
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlieTap committed Feb 28, 2025
1 parent c52b1fe commit 833542d
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.charlietap.chasm.executor.invoker.dispatch.referencefused

import io.github.charlietap.chasm.executor.invoker.instruction.referencefused.RefTestExecutor
import io.github.charlietap.chasm.executor.runtime.dispatch.DispatchableInstruction
import io.github.charlietap.chasm.executor.runtime.execution.Executor
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction

fun RefTestDispatcher(
instruction: FusedReferenceInstruction.RefTest,
) = RefTestDispatcher(
instruction = instruction,
executor = ::RefTestExecutor,
)

internal inline fun RefTestDispatcher(
instruction: FusedReferenceInstruction.RefTest,
crossinline executor: Executor<FusedReferenceInstruction.RefTest>,
): DispatchableInstruction = { context ->
executor(context, instruction)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.github.charlietap.chasm.executor.invoker.instruction.referencefused

import io.github.charlietap.chasm.executor.invoker.type.TypeOf
import io.github.charlietap.chasm.executor.invoker.type.TypeOfReferenceValue
import io.github.charlietap.chasm.executor.runtime.execution.ExecutionContext
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction
import io.github.charlietap.chasm.type.ReferenceType
import io.github.charlietap.chasm.type.matching.ReferenceTypeMatcher
import io.github.charlietap.chasm.type.matching.TypeMatcher

internal fun RefTestExecutor(
context: ExecutionContext,
instruction: FusedReferenceInstruction.RefTest,
) = RefTestExecutor(
context = context,
instruction = instruction,
referenceTypeMatcher = ::ReferenceTypeMatcher,
typeOfReferenceValue = ::TypeOfReferenceValue,
)

internal inline fun RefTestExecutor(
context: ExecutionContext,
instruction: FusedReferenceInstruction.RefTest,
crossinline referenceTypeMatcher: TypeMatcher<ReferenceType>,
crossinline typeOfReferenceValue: TypeOf<Long, ReferenceType>,
) {
val stack = context.vstack
val store = context.store
val frame = context.cstack.peekFrame()
val moduleInstance = frame.instance

val referenceType = typeOfReferenceValue(instruction.reference(stack), store, moduleInstance)
if (referenceTypeMatcher(referenceType, instruction.referenceType, context)) {
instruction.destination(1L, stack)
} else {
instruction.destination(0L, stack)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.github.charlietap.chasm.executor.runtime.instruction

import io.github.charlietap.chasm.type.ReferenceType

sealed interface FusedReferenceInstruction : LinkedInstruction {

data class RefEq(
Expand All @@ -17,4 +19,10 @@ sealed interface FusedReferenceInstruction : LinkedInstruction {
val destination: StoreOp,
val reference: Long,
) : FusedReferenceInstruction

data class RefTest(
val reference: LoadOp,
val destination: StoreOp,
val referenceType: ReferenceType,
) : FusedReferenceInstruction
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.charlietap.chasm.ir.instruction

import io.github.charlietap.chasm.type.HeapType
import io.github.charlietap.chasm.type.ReferenceType

sealed interface FusedReferenceInstruction : Instruction {

Expand All @@ -19,4 +20,10 @@ sealed interface FusedReferenceInstruction : Instruction {
val destination: FusedDestination,
val type: HeapType,
) : FusedReferenceInstruction

data class RefTest(
val reference: FusedOperand,
val destination: FusedDestination,
val referenceType: ReferenceType,
) : FusedReferenceInstruction
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,40 @@ internal inline fun ReferenceInstructionFuser(

nextIndex
}
is ReferenceInstruction.RefTest -> {
var nextIndex = index

val reference = input.getOrNull(index - 1)?.let(operandFactory)
val destination = input.getOrNull(index + 1).let(destinationFactory)

val instruction = if (reference == null && destination == FusedDestination.ValueStack) {
instruction
} else {
when {
reference == null -> FusedReferenceInstruction.RefTest(
reference = FusedOperand.ValueStack,
destination = destination,
referenceType = instruction.referenceType,
)
else -> {
output.removeLast()
FusedReferenceInstruction.RefTest(
reference = reference,
destination = destination,
referenceType = instruction.referenceType,
)
}
}
}

output.add(instruction)

if (destination != FusedDestination.ValueStack) {
nextIndex++
}

nextIndex
}
else -> {
output.add(instruction)
index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import io.github.charlietap.chasm.executor.invoker.dispatch.Dispatcher
import io.github.charlietap.chasm.executor.invoker.dispatch.referencefused.RefEqDispatcher
import io.github.charlietap.chasm.executor.invoker.dispatch.referencefused.RefIsNullDispatcher
import io.github.charlietap.chasm.executor.invoker.dispatch.referencefused.RefNullDispatcher
import io.github.charlietap.chasm.executor.invoker.dispatch.referencefused.RefTestDispatcher
import io.github.charlietap.chasm.executor.runtime.dispatch.DispatchableInstruction
import io.github.charlietap.chasm.executor.runtime.error.ModuleTrapError
import io.github.charlietap.chasm.executor.runtime.ext.toLong
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction.RefEq
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction.RefIsNull
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction.RefNull
import io.github.charlietap.chasm.executor.runtime.instruction.FusedReferenceInstruction.RefTest
import io.github.charlietap.chasm.executor.runtime.value.ReferenceValue
import io.github.charlietap.chasm.ir.instruction.FusedReferenceInstruction
import io.github.charlietap.chasm.predecoder.LoadFactory
Expand All @@ -30,6 +32,7 @@ internal fun FusedReferenceInstructionPredecoder(
refEqDispatcher = ::RefEqDispatcher,
refIsNullDispatcher = ::RefIsNullDispatcher,
refNullDispatcher = ::RefNullDispatcher,
refTestDispatcher = ::RefTestDispatcher,
)

internal inline fun FusedReferenceInstructionPredecoder(
Expand All @@ -40,6 +43,7 @@ internal inline fun FusedReferenceInstructionPredecoder(
crossinline refEqDispatcher: Dispatcher<RefEq>,
crossinline refIsNullDispatcher: Dispatcher<RefIsNull>,
crossinline refNullDispatcher: Dispatcher<RefNull>,
crossinline refTestDispatcher: Dispatcher<RefTest>,
): Result<DispatchableInstruction, ModuleTrapError> = binding {
when (instruction) {
is FusedReferenceInstruction.RefEq -> {
Expand Down Expand Up @@ -72,5 +76,17 @@ internal inline fun FusedReferenceInstructionPredecoder(
val reference = ReferenceValue.Null(instruction.type).toLong()
refNullDispatcher(RefNull(destination, reference))
}
is FusedReferenceInstruction.RefTest -> {
val reference = loadFactory(context, instruction.reference)
val destination = storeFactory(context, instruction.destination)

refTestDispatcher(
RefTest(
reference = reference,
destination = destination,
referenceType = instruction.referenceType,
),
)
}
}
}

0 comments on commit 833542d

Please sign in to comment.