Skip to content

Commit

Permalink
prevent boxing in throw ref
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlieTap committed Jan 30, 2025
1 parent 8b754b9 commit a4a9b88
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import io.github.charlietap.chasm.executor.runtime.exception.ExceptionHandler
import io.github.charlietap.chasm.executor.runtime.exception.InvocationException
import io.github.charlietap.chasm.executor.runtime.execution.ExecutionContext
import io.github.charlietap.chasm.executor.runtime.ext.exception
import io.github.charlietap.chasm.executor.runtime.ext.popReference
import io.github.charlietap.chasm.executor.runtime.ext.isNullableReference
import io.github.charlietap.chasm.executor.runtime.ext.toExceptionAddress
import io.github.charlietap.chasm.executor.runtime.ext.toLong
import io.github.charlietap.chasm.executor.runtime.instruction.ControlInstruction
import io.github.charlietap.chasm.executor.runtime.stack.ControlStack
Expand All @@ -37,21 +38,21 @@ internal inline fun ThrowRefExecutor(
val cstack = context.cstack
val store = context.store

val ref = stack.popReference()
val ref = stack.pop()

val exceptionRef = if (ref is ReferenceValue.Null) {
val exceptionAddress = if (ref.isNullableReference()) {
throw InvocationException(InvocationError.UnexpectedReferenceValue)
} else {
ref as ReferenceValue.Exception
ref.toExceptionAddress()
}

val instance = store.exception(exceptionRef.address)
val instance = store.exception(exceptionAddress)
val address = instance.tagAddress

val handler = jumpToHandlerInstruction(cstack)

if (handler.instructions.isEmpty()) {
stack.push(ReferenceValue.Exception(exceptionRef.address).toLong())
stack.push(ReferenceValue.Exception(exceptionAddress).toLong())
cstack.push(ThrowRefDispatcher(ControlInstruction.ThrowRef))
} else {

Expand Down Expand Up @@ -83,7 +84,7 @@ internal inline fun ThrowRefExecutor(
catchHandler is CatchHandler.CatchRef && tagMatches -> {
instance.fields.reverse()
stack.push(instance.fields)
stack.push(exceptionRef.toLong())
stack.push(ref)
cstack.push(
breakDispatcher(ControlInstruction.Br(catchHandler.labelIndex)),
)
Expand All @@ -94,7 +95,7 @@ internal inline fun ThrowRefExecutor(
)
}
catchHandler is CatchHandler.CatchAllRef -> {
stack.push(exceptionRef.toLong())
stack.push(ref)
cstack.push(
breakDispatcher(ControlInstruction.Br(catchHandler.labelIndex)),
)
Expand All @@ -105,7 +106,7 @@ internal inline fun ThrowRefExecutor(
cstack.push(handler)
val instruction = handlerDispatcher(handler)
cstack.push(instruction)
stack.push(exceptionRef.toLong())
stack.push(ref)
cstack.push(ThrowRefDispatcher(ControlInstruction.ThrowRef))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ sealed interface InvocationError : ModuleTrapError {

data object ReferenceValueExpected : InvocationError

data object ExceptionReferenceExpected : InvocationError

data object FunctionReferenceExpected : InvocationError

data object StructReferenceExpected : InvocationError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ inline fun Long.toArrayAddress(): Address.Array {
return Address.Array(address)
}

inline fun Long.toExceptionAddress(): Address.Exception {
val typeId = this and RV_TYPE_MASK
if (typeId != RV_TYPE_EXCEPTION) {
throw InvocationException(InvocationError.ExceptionReferenceExpected)
}
val address = (this shr RV_SHIFT_BITS).toInt()
return Address.Exception(address)
}

inline fun Long.toFunctionAddress(): Address.Function {
val typeId = this and RV_TYPE_MASK
if (typeId != RV_TYPE_FUNCTION) {
Expand Down

0 comments on commit a4a9b88

Please sign in to comment.