WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

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

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