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,
memoryManager.globalMemory.addGlobalCell(gc)
}
for (ef <- bundle.expFuncNs.all) {
val addr = nativeCallHelper.exposeFunc(ef.func, ef.cookie.num.toLong, false)
ef.addr = addr
nativeCallHelper.exposeFuncStatic(ef)
}
// Must allocate the memory and expose the functions before making constants.
for (g <- bundle.globalVarNs.all) {
......
......@@ -131,7 +131,7 @@ class ClientAgent(mutator: Mutator)(
def putExpFunc(id: Int): Handle = {
val ef = microVM.globalBundle.expFuncNs(id)
val t = InternalTypePool.funcPtrOf(ef.func.sig)
val box = BoxPointer(ef.addr)
val box = BoxPointer(microVM.nativeCallHelper.getStaticExpFuncAddr(ef))
newHandle(t, box)
}
......@@ -565,7 +565,7 @@ class ClientAgent(mutator: Mutator)(
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))
}
......
......@@ -35,7 +35,7 @@ class ConstantPool(implicit microVM: MicroVM) {
case ConstPointer(ty, addr) => BoxPointer(addr)
case gc:GlobalCell => BoxIRef(0L, microVM.memoryManager.globalMemory.addrForGlobalCell(gc))
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)
......
......@@ -1141,7 +1141,7 @@ class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator
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
......
......@@ -2,26 +2,26 @@ package uvm.refimpl.nat
import java.nio.ByteBuffer
import java.nio.ByteOrder
import scala.collection.mutable.HashMap
import org.slf4j.LoggerFactory
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 uvm.FuncSig
import uvm.{ Function => MFunc }
import uvm.refimpl.UvmRefImplException
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.itpr._
import uvm.refimpl.itpr.ValueBox
import uvm.refimpl.mem.TypeSizes
import uvm.refimpl.mem.TypeSizes.Word
import uvm.{ Function => MFunc }
import uvm.ssavariables.ExposedFunc
import uvm.types._
import uvm.types.{ Type => MType }
import uvm.utils.LazyPool
import uvm.utils.HexDump
import scala.collection.mutable.HashMap
import com.kenai.jffi.Closure
import com.kenai.jffi.ClosureManager
import com.kenai.jffi.CallingConvention
import uvm.refimpl.UvmRuntimeException
import uvm.refimpl.MicroVM
import uvm.utils.LazyPool
import uvm.refimpl.UvmRefImplException
object NativeCallHelper {
val logger = Logger(LoggerFactory.getLogger(getClass.getName))
......@@ -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
* 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.
*/
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.
......@@ -209,13 +221,24 @@ class NativeCallHelper {
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.
*
* @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 jParamTypes = sig.paramTy.map(jffiTypePool.apply)
val jRetTy = jffiTypePool(sig.retTy)
......@@ -224,25 +247,25 @@ class NativeCallHelper {
val handle = NativeSupport.closureManager.newClosure(clos, jRetTy, jParamTypes.toArray, CallingConvention.DEFAULT)
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 = {
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))
}
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))
}
exposedFuncs.remove(addr)
addrToRec.remove(addr)
dynExpFunc.closureHandle.dispose()
efr.closureHandle.dispose()
}
/** Handles calling back from C */
......
......@@ -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 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
}
case class ExposedFunc(var func: Function, var callConv: Flag, var cookie: ConstInt) extends GlobalVariable
// Local variables: Parameters and Instructions
......
......@@ -133,8 +133,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
val cb2Ptr = ca.toPointer(cb2)
cb1Ptr should not equal cb2Ptr
val cb1Rec = microVM.nativeCallHelper.exposedFuncs(cb1Ptr)
val cb2Rec = microVM.nativeCallHelper.exposedFuncs(cb2Ptr)
val cb1Rec = microVM.nativeCallHelper.addrToRec(cb1Ptr)
val cb2Rec = microVM.nativeCallHelper.addrToRec(cb2Ptr)
cb1Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square")
cb2Rec.muFunc shouldBe microVM.globalBundle.funcNs("@square")
......@@ -154,8 +154,8 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
val cb1Ptr = ca.toPointer(cb1)
val cb2Ptr = ca.toPointer(cb2)
microVM.nativeCallHelper.exposedFuncs should not contain cb1Ptr
microVM.nativeCallHelper.exposedFuncs should not contain cb2Ptr
microVM.nativeCallHelper.addrToRec should not contain cb1Ptr
microVM.nativeCallHelper.addrToRec should not contain cb2Ptr
TrapRebindPassVoid(st)
}
......@@ -228,7 +228,7 @@ class UvmInterpreterNativeCallbackTests extends UvmBundleTesterBase {
callbackCalled shouldBe 2
ca.unexpose(Flag("#DEFAULT"), hCB)
microVM.nativeCallHelper.exposedFuncs should not contain hCBAddr
microVM.nativeCallHelper.addrToRec should not contain hCBAddr
ca.close()
}
......
......@@ -81,7 +81,7 @@ class NativeStackKeeperTest extends FlatSpec with Matchers with ExtraMatchers {
val mockMuCallbackFunc = new MFunc()
mockMuCallbackFunc.sig = dtdSig
val mockClosAddr = nch.exposeFunc(mockMuCallbackFunc, 42L, true)
val mockClosAddr = nch.exposeFuncDynamic(mockMuCallbackFunc, 42L)
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