GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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