Commit 7f671771 authored by Kunshan Wang's avatar Kunshan Wang

No longer use the uvm.ssavariables.ExposedFunc to hold the address.

parent c726df9c
...@@ -57,8 +57,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE, ...@@ -57,8 +57,7 @@ class MicroVM(heapSize: Word = MicroVM.DEFAULT_HEAP_SIZE,
memoryManager.globalMemory.addGlobalCell(gc) memoryManager.globalMemory.addGlobalCell(gc)
} }
for (ef <- bundle.expFuncNs.all) { for (ef <- bundle.expFuncNs.all) {
val addr = nativeCallHelper.exposeFunc(ef.func, ef.cookie.num.toLong, false) nativeCallHelper.exposeFuncStatic(ef)
ef.addr = addr
} }
// Must allocate the memory and expose the functions before making constants. // Must allocate the memory and expose the functions before making constants.
for (g <- bundle.globalVarNs.all) { for (g <- bundle.globalVarNs.all) {
......
...@@ -131,7 +131,7 @@ class ClientAgent(mutator: Mutator)( ...@@ -131,7 +131,7 @@ class ClientAgent(mutator: Mutator)(
def putExpFunc(id: Int): Handle = { def putExpFunc(id: Int): Handle = {
val ef = microVM.globalBundle.expFuncNs(id) val ef = microVM.globalBundle.expFuncNs(id)
val t = InternalTypePool.funcPtrOf(ef.func.sig) val t = InternalTypePool.funcPtrOf(ef.func.sig)
val box = BoxPointer(ef.addr) val box = BoxPointer(microVM.nativeCallHelper.getStaticExpFuncAddr(ef))
newHandle(t, box) newHandle(t, box)
} }
...@@ -565,7 +565,7 @@ class ClientAgent(mutator: Mutator)( ...@@ -565,7 +565,7 @@ class ClientAgent(mutator: Mutator)(
val c = cookie.vb.asInstanceOf[BoxInt].value.toLong val c = cookie.vb.asInstanceOf[BoxInt].value.toLong
val addr = microVM.nativeCallHelper.exposeFunc(f,c,true) val addr = microVM.nativeCallHelper.exposeFuncDynamic(f,c)
newHandle(InternalTypePool.funcPtrOf(sig), BoxPointer(addr)) newHandle(InternalTypePool.funcPtrOf(sig), BoxPointer(addr))
} }
......
...@@ -35,7 +35,7 @@ class ConstantPool(implicit microVM: MicroVM) { ...@@ -35,7 +35,7 @@ class ConstantPool(implicit microVM: MicroVM) {
case ConstPointer(ty, addr) => BoxPointer(addr) case ConstPointer(ty, addr) => BoxPointer(addr)
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc)) case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
case f:Function => BoxFunc(Some(f)) case f:Function => BoxFunc(Some(f))
case ef:ExposedFunc => BoxPointer(ef.addr) case ef:ExposedFunc => BoxPointer(microVM.nativeCallHelper.getStaticExpFuncAddr(ef))
} }
def getGlobalVarBox(g: GlobalVariable): ValueBox = globalVarBoxes(g) def getGlobalVarBox(g: GlobalVariable): ValueBox = globalVarBoxes(g)
......
...@@ -1141,7 +1141,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator ...@@ -1141,7 +1141,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
val c = boxOf(cookie).asInstanceOf[BoxInt].value.toLong val c = boxOf(cookie).asInstanceOf[BoxInt].value.toLong
val addr = microVM.nativeCallHelper.exposeFunc(f, c, true) val addr = microVM.nativeCallHelper.exposeFuncDynamic(f, c)
boxOf(i).asInstanceOf[BoxPointer].addr = addr boxOf(i).asInstanceOf[BoxPointer].addr = addr
......
...@@ -2,26 +2,26 @@ package uvm.refimpl.nat ...@@ -2,26 +2,26 @@ package uvm.refimpl.nat
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder
import scala.collection.mutable.HashMap
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import com.kenai.jffi.{ Type => JType, Struct => JStruct, Function => JFunction, HeapInvocationBuffer, Invoker } import com.kenai.jffi.{ Type => JType, Struct => JStruct, Function => JFunction, HeapInvocationBuffer, Invoker }
import com.kenai.jffi.CallingConvention
import com.kenai.jffi.Closure
import com.typesafe.scalalogging.Logger import com.typesafe.scalalogging.Logger
import uvm.FuncSig import uvm.FuncSig
import uvm.{ Function => MFunc }
import uvm.refimpl.UvmRefImplException import uvm.refimpl.UvmRefImplException
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.itpr._ import uvm.refimpl.itpr._
import uvm.refimpl.itpr.ValueBox import uvm.refimpl.itpr.ValueBox
import uvm.refimpl.mem.TypeSizes import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.mem.TypeSizes.Word import uvm.refimpl.mem.TypeSizes.Word
import uvm.{ Function => MFunc } import uvm.ssavariables.ExposedFunc
import uvm.types._ import uvm.types._
import uvm.types.{ Type => MType } import uvm.types.{ Type => MType }
import uvm.utils.LazyPool
import uvm.utils.HexDump import uvm.utils.HexDump
import scala.collection.mutable.HashMap import uvm.utils.LazyPool
import com.kenai.jffi.Closure import uvm.refimpl.UvmRefImplException
import com.kenai.jffi.ClosureManager
import com.kenai.jffi.CallingConvention
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.MicroVM
object NativeCallHelper { object NativeCallHelper {
val logger = Logger(LoggerFactory.getLogger(getClass.getName)) val logger = Logger(LoggerFactory.getLogger(getClass.getName))
...@@ -73,12 +73,24 @@ class NativeCallHelper { ...@@ -73,12 +73,24 @@ class NativeCallHelper {
* @param isDynamic true if it is exposed via the "@uvm.native.expose" instruction or the equivalent API call. false * @param isDynamic true if it is exposed via the "@uvm.native.expose" instruction or the equivalent API call. false
* if it is exposed by the ".expose" top-level definintion of the Mu IR. * if it is exposed by the ".expose" top-level definintion of the Mu IR.
*/ */
class DynExpFunc(val muFunc: MFunc, val cookie: Long, val closure: MuCallbackClosure, val closureHandle: Closure.Handle, val isDynamic: Boolean) class ExpFuncRec(val muFunc: MFunc, val cookie: Long, val closure: MuCallbackClosure, val closureHandle: Closure.Handle, val isDynamic: Boolean)
/** /**
* Map each address of closure handle to the DynExpFunc record so that the closure handle can be disposed. * Map each address of closure handle to the DynExpFunc record so that the closure handle can be disposed.
*/ */
val exposedFuncs = new HashMap[Word, DynExpFunc]() val addrToRec = new HashMap[Word, ExpFuncRec]()
/**
* Map each uvm.ssavariables.ExpFunc instance to the DynExpFunc record.
*/
val expFuncToRec = new HashMap[ExposedFunc, ExpFuncRec]()
/**
* Get the address to the statically exposed function (.expose) by the ExposedFunc instance.
*/
def getStaticExpFuncAddr(expFunc: ExposedFunc): Word = {
expFuncToRec(expFunc).closureHandle.getAddress()
}
/** /**
* The current NativeStackKeeper instance that makes the native call. * The current NativeStackKeeper instance that makes the native call.
...@@ -209,13 +221,24 @@ class NativeCallHelper { ...@@ -209,13 +221,24 @@ class NativeCallHelper {
case _: AbstractPointerType => vb.asInstanceOf[BoxPointer].addr = buf.getLong(off) case _: AbstractPointerType => vb.asInstanceOf[BoxPointer].addr = buf.getLong(off)
} }
} }
def exposeFuncStatic(expFunc: ExposedFunc): Word = {
val efr = exposeFunc(expFunc.func, expFunc.cookie.num.toLong, false)
expFuncToRec(expFunc) = efr
efr.closureHandle.getAddress
}
def exposeFuncDynamic(muFunc: MFunc, cookie: Long): Word = {
val efr = exposeFunc(muFunc, cookie, true)
efr.closureHandle.getAddress
}
/** /**
* Expose a Mu function. * Expose a Mu function.
* *
* @return the address of the exposed function (i.e. of the closure handle) * @return the address of the exposed function (i.e. of the closure handle)
*/ */
def exposeFunc(muFunc: MFunc, cookie: Long, isDynamic: Boolean): Word = { private def exposeFunc(muFunc: MFunc, cookie: Long, isDynamic: Boolean): ExpFuncRec = {
val sig = muFunc.sig val sig = muFunc.sig
val jParamTypes = sig.paramTy.map(jffiTypePool.apply) val jParamTypes = sig.paramTy.map(jffiTypePool.apply)
val jRetTy = jffiTypePool(sig.retTy) val jRetTy = jffiTypePool(sig.retTy)
...@@ -224,25 +247,25 @@ class NativeCallHelper { ...@@ -224,25 +247,25 @@ class NativeCallHelper {
val handle = NativeSupport.closureManager.newClosure(clos, jRetTy, jParamTypes.toArray, CallingConvention.DEFAULT) val handle = NativeSupport.closureManager.newClosure(clos, jRetTy, jParamTypes.toArray, CallingConvention.DEFAULT)
val addr = handle.getAddress val addr = handle.getAddress
val dynExpFunc = new DynExpFunc(muFunc, cookie, clos, handle, isDynamic) val efr = new ExpFuncRec(muFunc, cookie, clos, handle, isDynamic)
exposedFuncs(addr) = dynExpFunc addrToRec(addr) = efr
addr efr
} }
def unexposeFunc(addr: Word): Unit = { def unexposeFunc(addr: Word): Unit = {
val dynExpFunc = exposedFuncs.get(addr).getOrElse { val efr = addrToRec.get(addr).getOrElse {
throw new UvmRuntimeException("Attempt to unexpose function %d (0x%x) which has not been exposed.".format(addr, addr)) throw new UvmRuntimeException("Attempt to unexpose function %d (0x%x) which has not been exposed.".format(addr, addr))
} }
if (!dynExpFunc.isDynamic) { if (!efr.isDynamic) {
throw new UvmRuntimeException("Attempt to unexpose a function %d (0x%x) exposed via the '.expose' top-level definition.".format(addr, addr)) throw new UvmRuntimeException("Attempt to unexpose a function %d (0x%x) exposed via the '.expose' top-level definition.".format(addr, addr))
} }
exposedFuncs.remove(addr) addrToRec.remove(addr)
dynExpFunc.closureHandle.dispose() efr.closureHandle.dispose()
} }
/** Handles calling back from C */ /** Handles calling back from C */
......
...@@ -36,10 +36,7 @@ case class ConstPointer(var constTy: Type, var addr: Long) extends Constant ...@@ -36,10 +36,7 @@ case class ConstPointer(var constTy: Type, var addr: Long) extends Constant
case class GlobalCell(var cellTy: Type) extends GlobalVariable case class GlobalCell(var cellTy: Type) extends GlobalVariable
case class ExposedFunc(var func: Function, var callConv: Flag, var cookie: ConstInt) extends GlobalVariable { case class ExposedFunc(var func: Function, var callConv: Flag, var cookie: ConstInt) extends GlobalVariable
/** This value will be supplied when the function is actually exposed. */
var addr: Long = 0L
}
// Local variables: Parameters and Instructions // Local variables: Parameters and Instructions
......
...@@ -133,8 +133,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase { ...@@ -133,8 +133,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
val cb2Ptr = ca.toPointer(cb2) val cb2Ptr = ca.toPointer(cb2)
cb1Ptr should not equal cb2Ptr cb1Ptr should not equal cb2Ptr
val cb1Rec = microVM.nativeCallHelper.exposedFuncs(cb1Ptr) val cb1Rec = microVM.nativeCallHelper.addrToRec(cb1Ptr)
val cb2Rec = microVM.nativeCallHelper.exposedFuncs(cb2Ptr) val cb2Rec = microVM.nativeCallHelper.addrToRec(cb2Ptr)
cb1Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square") cb1Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square")
cb2Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square") cb2Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square")
...@@ -154,8 +154,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase { ...@@ -154,8 +154,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
val cb1Ptr = ca.toPointer(cb1) val cb1Ptr = ca.toPointer(cb1)
val cb2Ptr = ca.toPointer(cb2) val cb2Ptr = ca.toPointer(cb2)
microVM.nativeCallHelper.exposedFuncs should not contain cb1Ptr microVM.nativeCallHelper.addrToRec should not contain cb1Ptr
microVM.nativeCallHelper.exposedFuncs should not contain cb2Ptr microVM.nativeCallHelper.addrToRec should not contain cb2Ptr
TrapRebindPassVoid(st) TrapRebindPassVoid(st)
} }
...@@ -228,7 +228,7 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase { ...@@ -228,7 +228,7 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
callbackCalled shouldBe 2 callbackCalled shouldBe 2
ca.unexpose(Flag("#DEFAULT"), hCB) ca.unexpose(Flag("#DEFAULT"), hCB)
microVM.nativeCallHelper.exposedFuncs should not contain hCBAddr microVM.nativeCallHelper.addrToRec should not contain hCBAddr
ca.close() ca.close()
} }
......
...@@ -81,7 +81,7 @@ class NativeStackKeeperTest extends FlatSpec with Matchers with ExtraMatchers { ...@@ -81,7 +81,7 @@ class NativeStackKeeperTest extends FlatSpec with Matchers with ExtraMatchers {
val mockMuCallbackFunc = new MFunc() val mockMuCallbackFunc = new MFunc()
mockMuCallbackFunc.sig = dtdSig mockMuCallbackFunc.sig = dtdSig
val mockClosAddr = nch.exposeFunc(mockMuCallbackFunc, 42L, true) val mockClosAddr = nch.exposeFuncDynamic(mockMuCallbackFunc, 42L)
mockClosAddr should not be 0 mockClosAddr should not be 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment