Commit 8876d93c authored by Kunshan Wang's avatar Kunshan Wang

c interface

parent 5ac4d9fd
......@@ -122,9 +122,9 @@ typedef MuFlag MuDestKind;
#define MU_DEST_EXCEPT 0x02
#define MU_DEST_TRUE 0x03
#define MU_DEST_FALSE 0x04
#define MU_DEST_DEFAULT 0x04
#define MU_DEST_DISABLED 0x05
#define MU_DEST_ENABLED 0x06
#define MU_DEST_DEFAULT 0x05
#define MU_DEST_DISABLED 0x06
#define MU_DEST_ENABLED 0x07
// Binary operators
typedef MuFlag MuBinOptr;
......@@ -413,10 +413,10 @@ struct MuCtx {
MuChildNode (*get_node )(MuCtx *ctx, MuBundleNode b, MuID id);
// Get the ID of the IR node "node".
MuID (*get_id )(MuCtx *ctx, MuChildNode node);
MuID (*get_id )(MuCtx *ctx, MuBundleNode b, MuChildNode node);
// Set the name of the IR node. MuName is '\0' terminated char*.
void (*set_name )(MuCtx *ctx, MuChildNode node, MuName name);
void (*set_name )(MuCtx *ctx, MuBundleNode b, MuChildNode node, MuName name);
/// Create top-level definitions. When created, they are added to the bundle "b".
......@@ -463,9 +463,9 @@ struct MuCtx {
MuConstNode (*new_const_float )(MuCtx *ctx, MuBundleNode b, MuTypeNode ty, float value);
MuConstNode (*new_const_double )(MuCtx *ctx, MuBundleNode b, MuTypeNode ty, double value);
// new_const_null works for all general reference types, but not uptr or ufuncptr.
MuConstNode (*new_const_null )(MuCtx *ctx, MuBundleNode b);
MuConstNode (*new_const_null )(MuCtx *ctx, MuBundleNode b, MuTypeNode ty);
// new_const_seq works for structs, arrays and vectors. Constants are non-recursive, so there is no populate_list_const.
MuConstNode (*new_const_seq )(MuCtx *ctx, MuBundleNode b, MuConstNode *elems, int nelems);
MuConstNode (*new_const_seq )(MuCtx *ctx, MuBundleNode b, MuTypeNode ty, MuConstNode *elems, int nelems);
// Create global cell
MuGlobalNode (*new_global_cell )(MuCtx *ctx, MuBundleNode b, MuTypeNode ty);
......@@ -515,7 +515,7 @@ struct MuCtx {
MuInstNode (*new_branch )(MuCtx *ctx, MuBBNode bb);
MuInstNode (*new_branch2 )(MuCtx *ctx, MuBBNode bb, MuVarNode cond);
MuInstNode (*new_switch )(MuCtx *ctx, MuBBNode bb, MuVarNode opnd);
MuInstNode (*new_switch )(MuCtx *ctx, MuBBNode bb, MuTypeNode opnd_ty, MuVarNode opnd);
void (*add_switch_dest )(MuCtx *ctx, MuInstNode sw, MuConstNode key, MuBBNode dest, MuVarNode *vars, int nvars);
MuInstNode (*new_call )(MuCtx *ctx, MuBBNode bb, MuFuncSigNode sig, MuVarNode callee, MuVarNode *args, int nargs);
......@@ -543,7 +543,7 @@ struct MuCtx {
MuInstNode (*new_load )(MuCtx *ctx, MuBBNode bb, int is_ptr, MuMemOrd ord, MuTypeNode refty, MuVarNode loc);
MuInstNode (*new_store )(MuCtx *ctx, MuBBNode bb, int is_ptr, MuMemOrd ord, MuTypeNode refty, MuVarNode loc, MuVarNode newval);
MuInstNode (*new_cmpxchg )(MuCtx *ctx, MuBBNode bb, int is_ptr, int is_weak, MuMemOrd ord_succ, MuMemOrd ord_fail, MuTypeNode refty, MuVarNode loc, MuVarNode expected, MuVarNode desired);
MuInstNode (*new_atomicrmw )(MuCtx *ctx, MuBBNode bb, int is_ptr, MuMemOrd ord, MuAtomicRMWOp optr, MuVarNode loc, MuVarNode opnd);
MuInstNode (*new_atomicrmw )(MuCtx *ctx, MuBBNode bb, int is_ptr, MuMemOrd ord, MuAtomicRMWOp optr, MuTypeNode refTy, MuVarNode loc, MuVarNode opnd);
MuInstNode (*new_fence )(MuCtx *ctx, MuBBNode bb, MuMemOrd ord);
MuInstNode (*new_trap )(MuCtx *ctx, MuBBNode bb, MuTypeNode *rettys, int nrettys);
......@@ -553,10 +553,10 @@ struct MuCtx {
MuInstNode (*new_ccall )(MuCtx *ctx, MuBBNode bb, MuCallConv callconv, MuTypeNode callee_ty, MuFuncSigNode sig, MuVarNode callee, MuVarNode *args, int nargs);
MuInstNode (*new_newthread )(MuCtx *ctx, MuBBNode bb, MuVarNode stack, MuVarNode threadlocal);
MuInstNode (*new_swapstack_ret )(MuCtx *ctx, MuBBNode bb, MuVarNode swappee, MuTypeNode *tys, int ntys);
MuInstNode (*new_swapstack_ret )(MuCtx *ctx, MuBBNode bb, MuVarNode swappee, MuTypeNode *ret_tys, int nret_tys);
MuInstNode (*new_swapstack_kill)(MuCtx *ctx, MuBBNode bb, MuVarNode swappee);
void (*set_newstack_pass_values)(MuCtx *ctx, MuInstNode inst, MuTypeNode tys, MuVarNode *vars, int nvars);
void (*set_newstack_pass_values)(MuCtx *ctx, MuInstNode inst, MuTypeNode *tys, MuVarNode *vars, int nvars);
void (*set_newstack_throw_exc )(MuCtx *ctx, MuInstNode inst, MuVarNode exc);
MuInstNode (*new_comminst )(MuCtx *ctx, MuBBNode bb, MuCommInst opcode,
......
......@@ -2,6 +2,8 @@
USAGE: python3 migrate_scripts/irbuildertomuctx.py < src/main/scala/uvm/ir/irbuilder/IRBuilder.scala | xclip -selection c
And then paste the result into src/main/scala/uvm/refimpl/MuCtxIRBuilderPart.scala
Use pbcopy on Mac.
"""
import re
......
"""
Converts MuCtx methods in muapi.h to nativeClientSupport
USAGE: python3 muapitoncs.py < cbinding/muapi.h | xclip -selection c
then paste in function signatures, then paste the result in
src/main/scala/uvm/refimpl/nat/nativeClientSupport.scala
Use pbcopy on Mac.
"""
import sys
import re
r_comment = re.compile(r'//.*$', re.MULTILINE)
r_decl = re.compile(r'(?P<ret>\w+)\s*\(\s*\*\s*(?P<name>\w+)\s*\)\s*\((?P<params>[^)]*)\)\s*;')
r_param = re.compile(r'\s*(?P<type>\w+)\s*(?P<ptr>\*?)\s*(?P<name>\w+)')
r_value_ty = re.compile(r'Mu\w*(Value|Node)')
begin = "/// IR Builder API"
end = "// Common instruction opcodes"
lines = sys.stdin.read().splitlines()
l1 = [n for (n,l) in enumerate(lines) if begin in l][0]
l2 = [n for (n,l) in enumerate(lines) if end in l][0]
text = "\n".join(lines[l1+1:l2])
text = r_comment.sub("", text)
_simple_map = {
"void": "Unit",
"int": "Int",
"long": "Long",
"uint64_t": "Long",
"uint64_t*": "LongPtr",
"float": "Float",
"double": "Double",
}
def conv_ret_ty(ty):
if ty in _simple_map:
ty = _simple_map[ty]
m = r_value_ty.match(ty)
if m is not None:
return (True, "MuValueFak")
else:
return (False, ty)
_special_case = {
"id": "ID",
"uptr": "UPtr",
"ufuncptr": "UFuncPtr",
"iref": "IRef",
"weakref": "WeakRef",
"funcref": "FuncRef",
"tagref64": "TagRef64",
"threadref": "ThreadRef",
"stackref": "StackRef",
"framecursorref": "FrameCursorRef",
"irnoderef": "IRNodeRef",
"funcsig": "FuncSig",
"bb": "BB",
"keepalives": "KeepAlives",
"binop": "BinOp",
"tailcall": "TailCall",
"extractvalue": "ExtractValue",
"insertvalue" : "InsertValue",
"extractelement": "ExtractElement",
"insertelement" : "InsertElement",
"shufflevector" : "ShuffleVector",
"newhybrid" : "NewHybrid",
"allocahybrid" : "AllocaHybrid",
"getiref" : "GetIRef",
"getfieldiref" : "GetFieldIRef",
"getelemiref" : "GetElemIRef",
"shiftiref" : "ShiftIRef",
"getvarpartiref": "GetVarPartIRef",
"cmpxchg" : "CmpXchg",
"atomicrmw" : "AtomicRMW",
"watchpoint" : "WatchPoint",
"wpbranch" : "WPBranch",
"ccall" : "CCall",
"newthread" : "NewThread",
"newstack" : "NewStack",
"swapstack" : "SwapStack",
"comminst" : "CommInst",
}
def toCamelCase(name):
ins = name.split("_")
outs = [ins[0]]
for inn in ins[1:]:
if inn in _special_case:
outs.append(_special_case[inn])
else:
outs.append(inn[0].upper()+inn[1:])
return "".join(outs)
_special_param = {
}
def conv_param_ty(name, ty):
if ty == "MuCtx*":
return "MuCtx"
elif r_value_ty.match(ty) is not None and ty.endswith("*"):
return "MuValueFakArrayPtr"
elif ty == "MuFlag*":
return "MuFlagArrayPtr"
elif name == "threadlocal" and ty == "MuVarNode":
return "Option[MuVarNode]"
elif ty in _special_param:
return _special_param[ty]
elif ty in _simple_map:
return _simple_map[ty]
else:
return ty
def conv_param_val(func, name, ty):
if ty == "MuValueFakArrayPtr":
if func == "set_newstack_pass_values":
lenvar = "nvars"
else:
lenvar = "n" + name
return "readFromValueFakArray({}, {})".format(name, lenvar)
elif ty == "MuFlagArrayPtr":
lenvar = "n" + name
return "readFromFlagArray({}, {})".format(name, lenvar)
elif name in ["is_ptr", "is_weak"]:
return name + " != 0"
else:
return name
_num_params = "nfieldtys nfixedtys nparamtys nrettys nelems nargs nrvs nvars nflags ntys nsigs nret_tys".split()
def forward_call(func, params):
params = [p for p in params if p[0] not in _num_params]
return "ctx.{}({})".format(toCamelCase(func), ", ".join(
conv_param_val(func, n, t) for n,t in params))
for m in r_decl.finditer(text):
name, params, ret = [m.groupdict()[k] for k in "name params ret".split()]
params_out = []
params = params.split(",")
for param in params:
mp = r_param.search(param)
pt, pp, pn = [mp.groupdict()[k] for k in "type ptr name".split()]
pt = conv_param_ty(pn, pt+pp)
params_out.append((pn, pt))
params_out_str = ", ".join("{}: {}".format(pn, pt) for pn, pt in params_out)
is_value, ret = conv_ret_ty(ret)
impl = forward_call(name, params_out[1:])
if is_value:
impl = "exposeMuValue(ctx, {})".format(impl)
print(" def {}({}): {} = {}".format(name, params_out_str, ret, impl))
package uvm.ir.irbuilder
import scala.collection.mutable.ArrayBuffer
import uvm.utils.IDFactory
import uvm._
import uvm.types._
import uvm.ssavariables._
import uvm.comminsts.CommInsts
import uvm.ssavariables._
import uvm.types._
import uvm.utils.IDFactory
object DestKind extends Enumeration {
val NORMAL, EXCEPT, TRUE, FALSE, DEFAULT, DISABLED, ENABLED = Value
......@@ -417,6 +418,11 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
newInst(bb, inst)
}
def newWPBranch(bb: CN[BB], wpid: Int): CN[InstWPBranch] = {
val inst = InstWPBranch(wpid, null, null)
newInst(bb, inst)
}
def newCCall(bb: CN[BB], callConv: Flag, calleeTy: CN[Type], sig: CN[FuncSig], callee: CN[Var], args: Seq[CN[Var]]): CN[InstCCall] = {
val inst = InstCCall(callConv, calleeTy, sig, callee, args, None, Seq())
newInst(bb, inst)
......@@ -438,9 +444,8 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
val inst = InstSwapStack(swappee, curStackClause, null, None, Seq())
newInst(bb, inst)
}
def setNewStackPassValues(inst: CN[Instruction], tys: Seq[CN[Type]], vars: Seq[CN[Var]]): Unit = {
val newStackClause = PassValues(tys, vars)
private def setNewStackClause(inst: CN[Instruction], newStackClause: NewStackAction): Unit = {
inst.obj match {
case i: InstNewThread => i.newStackAction = newStackClause
case i: InstSwapStack => i.newStackAction = newStackClause
......@@ -450,6 +455,16 @@ class IRBuilder(globalBundle: GlobalBundle, idFactory: IDFactory) {
}
}
def setNewStackPassValues(inst: CN[Instruction], tys: Seq[CN[Type]], vars: Seq[CN[Var]]): Unit = {
val newStackClause = PassValues(tys, vars)
setNewStackClause(inst, newStackClause)
}
def setNewStackThrowExc(inst: CN[Instruction], exc: CN[Var]): Unit = {
val newStackClause = ThrowExc(exc)
setNewStackClause(inst, newStackClause)
}
def newCommInst(bb: CN[BB], opcode: Int, flags: Seq[Flag], tys: Seq[CN[Type]], sigs: Seq[CN[FuncSig]], args: Seq[CN[Var]]): CN[InstCommInst] = {
val commInst = CommInsts.get(opcode).getOrElse {
throw new IllegalArgumentException("No such common instruction. opcode: %d 0x%x".format(opcode, opcode))
......
......@@ -576,6 +576,11 @@ trait MuCtxIRBuilderPart {
addHandle(irBuilder.newWatchPoint(bb, wpid, retTys))
}
def newWPBranch(bb: MuBBNode, wpid: Int): MuInstNode = {
require(!bb.isNull, "bb must not be NULL")
addHandle(irBuilder.newWPBranch(bb, wpid))
}
def newCCall(bb: MuBBNode, callConv: Flag, calleeTy: MuTypeNode, sig: MuFuncSigNode, callee: MuVarNode, args: Seq[MuVarNode]): MuInstNode = {
require(!bb.isNull, "bb must not be NULL")
require(!calleeTy.isNull, "calleeTy must not be NULL")
......@@ -611,6 +616,12 @@ trait MuCtxIRBuilderPart {
irBuilder.setNewStackPassValues(inst, tys, vars)
}
def setNewStackThrowExc(inst: MuInstNode, exc: MuVarNode): Unit = {
require(!inst.isNull, "inst must not be NULL")
require(!exc.isNull, "exc must not be NULL")
irBuilder.setNewStackThrowExc(inst, exc)
}
def newCommInst(bb: MuBBNode, opcode: Int, flags: Seq[Flag], tys: Seq[MuTypeNode], sigs: Seq[MuFuncSigNode], args: Seq[MuVarNode]): MuInstNode = {
require(!bb.isNull, "bb must not be NULL")
for((n,i) <- tys.zipWithIndex) require(!n.isNull, "tys[%d] must not be NULL".format(i))
......
......@@ -13,20 +13,18 @@ import com.kenai.jffi.Closure.Buffer
import com.kenai.jffi.{ Type => JType }
import com.typesafe.scalalogging.Logger
import NativeSupport._
import PlatformConstants.WORD_SIZE_BYTES
import PlatformConstants.Word
import PlatformConstants._
import jnr.ffi.ObjectReferenceManager
import jnr.ffi.Pointer
import uvm.refimpl._
import uvm.ssavariables.MemoryOrder
import uvm.ssavariables.AtomicRMWOptr
import uvm.ssavariables.Flag
import uvm.ssavariables.Flag
import uvm.ssavariables._
import com.kenai.jffi.Invoker
import com.kenai.jffi.CallContext
import com.kenai.jffi.HeapInvocationBuffer
import NativeClientSupport._
import uvm.ir.irbuilder.DestKind
object NativeTrapHandler {
val jffiInvoker = Invoker.getInstance
val trapHandlerCallContext = new CallContext(
......@@ -281,12 +279,7 @@ object NativeMuCtx {
def new_thread(ctx: MuCtx, stack: MuStackRefValue, threadLocal: Option[MuRefValue], htr: MuHowToResume, vals: MuValueFakArrayPtr, nvals: Int, exc: MuValueFak): MuValueFak = {
val scalaHtr = htr match {
case MU_REBIND_PASS_VALUES => {
val values = for (i <- 0L until nvals) yield {
val addr = vals + i * WORD_SIZE_BYTES
val valFak = theMemory.getAddress(addr)
val v = getMuValueNotNull(valFak)
v
}
val values = readFromValueFakArray(vals, nvals)
HowToResume.PassValues(values)
}
case MU_REBIND_THROW_EXC => {
......@@ -298,7 +291,7 @@ object NativeMuCtx {
exposeMuValue(ctx, rv)
}
def kill_stack(ctx: MuCtx, stack: MuStackRefValue): Unit = ctx.killStack(stack)
def set_threadlocal(ctx: MuCtx, thread: MuThreadRefValue, threadLocal:MuRefValue): Unit = {
def set_threadlocal(ctx: MuCtx, thread: MuThreadRefValue, threadLocal: MuRefValue): Unit = {
ctx.setThreadlocal(thread, threadLocal)
}
def get_threadlocal(ctx: MuCtx, thread: MuThreadRefValue): MuValueFak = {
......@@ -346,6 +339,100 @@ object NativeMuCtx {
def expose(ctx: MuCtx, func: MuFuncRefValue, call_conv: MuCallConv, cookie: MuIntValue): MuValueFak = exposeMuValue(ctx, ctx.expose(func, call_conv, cookie))
def unexpose(ctx: MuCtx, call_conv: MuCallConv, value: MuUFPValue): Unit = ctx.unexpose(call_conv, value)
// PASTE FROM HERE
def new_bundle(ctx: MuCtx): MuValueFak = exposeMuValue(ctx, ctx.newBundle())
def load_bundle_from_node(ctx: MuCtx, b: MuBundleNode): Unit = ctx.loadBundleFromNode(b)
def abort_bundle_node(ctx: MuCtx, b: MuBundleNode): Unit = ctx.abortBundleNode(b)
def get_node(ctx: MuCtx, b: MuBundleNode, id: MuID): MuValueFak = exposeMuValue(ctx, ctx.getNode(b, id))
def get_id(ctx: MuCtx, b: MuBundleNode, node: MuChildNode): MuID = ctx.getID(b, node)
def set_name(ctx: MuCtx, b: MuBundleNode, node: MuChildNode, name: MuName): Unit = ctx.setName(b, node, name)
def new_type_int(ctx: MuCtx, b: MuBundleNode, len: Int): MuValueFak = exposeMuValue(ctx, ctx.newTypeInt(b, len))
def new_type_float(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeFloat(b))
def new_type_double(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeDouble(b))
def new_type_uptr(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeUPtr(b))
def set_type_uptr(ctx: MuCtx, uptr: MuTypeNode, ty: MuTypeNode): Unit = ctx.setTypeUPtr(uptr, ty)
def new_type_ufuncptr(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeUFuncPtr(b))
def set_type_ufuncptr(ctx: MuCtx, ufuncptr: MuTypeNode, sig: MuFuncSigNode): Unit = ctx.setTypeUFuncPtr(ufuncptr, sig)
def new_type_struct(ctx: MuCtx, b: MuBundleNode, fieldtys: MuValueFakArrayPtr, nfieldtys: Int): MuValueFak = exposeMuValue(ctx, ctx.newTypeStruct(b, readFromValueFakArray(fieldtys, nfieldtys)))
def new_type_hybrid(ctx: MuCtx, b: MuBundleNode, fixedtys: MuValueFakArrayPtr, nfixedtys: Int, varty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeHybrid(b, readFromValueFakArray(fixedtys, nfixedtys), varty))
def new_type_array(ctx: MuCtx, b: MuBundleNode, elemty: MuTypeNode, len: Long): MuValueFak = exposeMuValue(ctx, ctx.newTypeArray(b, elemty, len))
def new_type_vector(ctx: MuCtx, b: MuBundleNode, elemty: MuTypeNode, len: Long): MuValueFak = exposeMuValue(ctx, ctx.newTypeVector(b, elemty, len))
def new_type_void(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeVoid(b))
def new_type_ref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeRef(b))
def set_type_ref(ctx: MuCtx, ref: MuTypeNode, ty: MuTypeNode): Unit = ctx.setTypeRef(ref, ty)
def new_type_iref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeIRef(b))
def set_type_iref(ctx: MuCtx, iref: MuTypeNode, ty: MuTypeNode): Unit = ctx.setTypeIRef(iref, ty)
def new_type_weakref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeWeakRef(b))
def set_type_weakref(ctx: MuCtx, weakref: MuTypeNode, ty: MuTypeNode): Unit = ctx.setTypeWeakRef(weakref, ty)
def new_type_funcref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeFuncRef(b))
def set_type_funcref(ctx: MuCtx, funcref: MuTypeNode, sig: MuFuncSigNode): Unit = ctx.setTypeFuncRef(funcref, sig)
def new_type_tagref64(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeTagRef64(b))
def new_type_threadref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeThreadRef(b))
def new_type_stackref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeStackRef(b))
def new_type_framecursorref(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeFrameCursorRef(b))
def new_type_irnoderef(ctx: MuCtx, b: MuBundleNode): MuValueFak = exposeMuValue(ctx, ctx.newTypeIRNodeRef(b))
def new_funcsig(ctx: MuCtx, b: MuBundleNode, paramtys: MuValueFakArrayPtr, nparamtys: Int, rettys: MuValueFakArrayPtr, nrettys: Int): MuValueFak = exposeMuValue(ctx, ctx.newFuncSig(b, readFromValueFakArray(paramtys, nparamtys), readFromValueFakArray(rettys, nrettys)))
def new_const_int(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode, value: Long): MuValueFak = exposeMuValue(ctx, ctx.newConstInt(b, ty, value))
def new_const_int_ex(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode, values: LongPtr, nvalues: Int): MuValueFak = exposeMuValue(ctx, ctx.newConstIntEx(b, ty, values, nvalues))
def new_const_float(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode, value: Float): MuValueFak = exposeMuValue(ctx, ctx.newConstFloat(b, ty, value))
def new_const_double(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode, value: Double): MuValueFak = exposeMuValue(ctx, ctx.newConstDouble(b, ty, value))
def new_const_null(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newConstNull(b, ty))
def new_const_seq(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode, elems: MuValueFakArrayPtr, nelems: Int): MuValueFak = exposeMuValue(ctx, ctx.newConstSeq(b, ty, readFromValueFakArray(elems, nelems)))
def new_global_cell(ctx: MuCtx, b: MuBundleNode, ty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newGlobalCell(b, ty))
def new_func(ctx: MuCtx, b: MuBundleNode, sig: MuFuncSigNode): MuValueFak = exposeMuValue(ctx, ctx.newFunc(b, sig))
def new_func_ver(ctx: MuCtx, b: MuBundleNode, func: MuFuncNode): MuValueFak = exposeMuValue(ctx, ctx.newFuncVer(b, func))
def new_exp_func(ctx: MuCtx, b: MuBundleNode, func: MuFuncNode, callconv: MuCallConv, cookie: MuConstNode): MuValueFak = exposeMuValue(ctx, ctx.newExpFunc(b, func, callconv, cookie))
def new_bb(ctx: MuCtx, fv: MuFuncVerNode): MuValueFak = exposeMuValue(ctx, ctx.newBB(fv))
def new_nor_param(ctx: MuCtx, bb: MuBBNode, ty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newNorParam(bb, ty))
def new_exc_param(ctx: MuCtx, bb: MuBBNode): MuValueFak = exposeMuValue(ctx, ctx.newExcParam(bb))
def new_inst_res(ctx: MuCtx, inst: MuInstNode): MuValueFak = exposeMuValue(ctx, ctx.newInstRes(inst))
def add_dest(ctx: MuCtx, inst: MuInstNode, kind: MuDestKind, dest: MuBBNode, vars: MuValueFakArrayPtr, nvars: Int): Unit = ctx.addDest(inst, kind, dest, readFromValueFakArray(vars, nvars))
def add_keepalives(ctx: MuCtx, inst: MuInstNode, vars: MuValueFakArrayPtr, nvars: Int): Unit = ctx.addKeepAlives(inst, readFromValueFakArray(vars, nvars))
def new_binop(ctx: MuCtx, bb: MuBBNode, optr: MuBinOptr, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newBinOp(bb, optr, ty, opnd1, opnd2))
def new_cmp(ctx: MuCtx, bb: MuBBNode, optr: MuCmpOptr, ty: MuTypeNode, opnd1: MuVarNode, opnd2: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newCmp(bb, optr, ty, opnd1, opnd2))
def new_conv(ctx: MuCtx, bb: MuBBNode, optr: MuConvOptr, from_ty: MuTypeNode, to_ty: MuTypeNode, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newConv(bb, optr, from_ty, to_ty, opnd))
def new_select(ctx: MuCtx, bb: MuBBNode, cond_ty: MuTypeNode, opnd_ty: MuTypeNode, cond: MuVarNode, if_true: MuVarNode, if_false: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newSelect(bb, cond_ty, opnd_ty, cond, if_true, if_false))
def new_branch(ctx: MuCtx, bb: MuBBNode): MuValueFak = exposeMuValue(ctx, ctx.newBranch(bb))
def new_branch2(ctx: MuCtx, bb: MuBBNode, cond: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newBranch2(bb, cond))
def new_switch(ctx: MuCtx, bb: MuBBNode, opnd_ty: MuTypeNode, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newSwitch(bb, opnd_ty, opnd))
def add_switch_dest(ctx: MuCtx, sw: MuInstNode, key: MuConstNode, dest: MuBBNode, vars: MuValueFakArrayPtr, nvars: Int): Unit = ctx.addSwitchDest(sw, key, dest, readFromValueFakArray(vars, nvars))
def new_call(ctx: MuCtx, bb: MuBBNode, sig: MuFuncSigNode, callee: MuVarNode, args: MuValueFakArrayPtr, nargs: Int): MuValueFak = exposeMuValue(ctx, ctx.newCall(bb, sig, callee, readFromValueFakArray(args, nargs)))
def new_tailcall(ctx: MuCtx, bb: MuBBNode, sig: MuFuncSigNode, callee: MuVarNode, args: MuValueFakArrayPtr, nargs: Int): MuValueFak = exposeMuValue(ctx, ctx.newTailCall(bb, sig, callee, readFromValueFakArray(args, nargs)))
def new_ret(ctx: MuCtx, bb: MuBBNode, rvs: MuValueFakArrayPtr, nrvs: Int): MuValueFak = exposeMuValue(ctx, ctx.newRet(bb, readFromValueFakArray(rvs, nrvs)))
def new_throw(ctx: MuCtx, bb: MuBBNode, exc: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newThrow(bb, exc))
def new_extractvalue(ctx: MuCtx, bb: MuBBNode, strty: MuTypeNode, index: Int, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newExtractValue(bb, strty, index, opnd))
def new_insertvalue(ctx: MuCtx, bb: MuBBNode, strty: MuTypeNode, index: Int, opnd: MuVarNode, newval: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newInsertValue(bb, strty, index, opnd, newval))
def new_extractelement(ctx: MuCtx, bb: MuBBNode, seqty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newExtractElement(bb, seqty, indty, opnd, index))
def new_insertelement(ctx: MuCtx, bb: MuBBNode, seqty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode, newval: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newInsertElement(bb, seqty, indty, opnd, index, newval))
def new_shufflevector(ctx: MuCtx, bb: MuBBNode, vecty: MuTypeNode, maskty: MuTypeNode, vec1: MuVarNode, vec2: MuVarNode, mask: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newShuffleVector(bb, vecty, maskty, vec1, vec2, mask))
def new_new(ctx: MuCtx, bb: MuBBNode, allocty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newNew(bb, allocty))
def new_newhybrid(ctx: MuCtx, bb: MuBBNode, allocty: MuTypeNode, lenty: MuTypeNode, length: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newNewHybrid(bb, allocty, lenty, length))
def new_alloca(ctx: MuCtx, bb: MuBBNode, allocty: MuTypeNode): MuValueFak = exposeMuValue(ctx, ctx.newAlloca(bb, allocty))
def new_allocahybrid(ctx: MuCtx, bb: MuBBNode, allocty: MuTypeNode, lenty: MuTypeNode, length: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newAllocaHybrid(bb, allocty, lenty, length))
def new_getiref(ctx: MuCtx, bb: MuBBNode, refty: MuTypeNode, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newGetIRef(bb, refty, opnd))
def new_getfieldiref(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, refty: MuTypeNode, index: Int, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newGetFieldIRef(bb, is_ptr != 0, refty, index, opnd))
def new_getelemiref(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, refty: MuTypeNode, indty: MuTypeNode, opnd: MuVarNode, index: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newGetElemIRef(bb, is_ptr != 0, refty, indty, opnd, index))
def new_shiftiref(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, refty: MuTypeNode, offty: MuTypeNode, opnd: MuVarNode, offset: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newShiftIRef(bb, is_ptr != 0, refty, offty, opnd, offset))
def new_getvarpartiref(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, refty: MuTypeNode, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newGetVarPartIRef(bb, is_ptr != 0, refty, opnd))
def new_load(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, ord: MuMemOrd, refty: MuTypeNode, loc: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newLoad(bb, is_ptr != 0, ord, refty, loc))
def new_store(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, ord: MuMemOrd, refty: MuTypeNode, loc: MuVarNode, newval: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newStore(bb, is_ptr != 0, ord, refty, loc, newval))
def new_cmpxchg(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, is_weak: Int, ord_succ: MuMemOrd, ord_fail: MuMemOrd, refty: MuTypeNode, loc: MuVarNode, expected: MuVarNode, desired: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newCmpXchg(bb, is_ptr != 0, is_weak != 0, ord_succ, ord_fail, refty, loc, expected, desired))
def new_atomicrmw(ctx: MuCtx, bb: MuBBNode, is_ptr: Int, ord: MuMemOrd, optr: MuAtomicRMWOp, refTy: MuTypeNode, loc: MuVarNode, opnd: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newAtomicRMW(bb, is_ptr != 0, ord, optr, refTy, loc, opnd))
def new_fence(ctx: MuCtx, bb: MuBBNode, ord: MuMemOrd): MuValueFak = exposeMuValue(ctx, ctx.newFence(bb, ord))
def new_trap(ctx: MuCtx, bb: MuBBNode, rettys: MuValueFakArrayPtr, nrettys: Int): MuValueFak = exposeMuValue(ctx, ctx.newTrap(bb, readFromValueFakArray(rettys, nrettys)))
def new_watchpoint(ctx: MuCtx, bb: MuBBNode, wpid: MuWPID, rettys: MuValueFakArrayPtr, nrettys: Int): MuValueFak = exposeMuValue(ctx, ctx.newWatchPoint(bb, wpid, readFromValueFakArray(rettys, nrettys)))
def new_wpbranch(ctx: MuCtx, bb: MuBBNode, wpid: MuWPID): MuValueFak = exposeMuValue(ctx, ctx.newWPBranch(bb, wpid))
def new_ccall(ctx: MuCtx, bb: MuBBNode, callconv: MuCallConv, callee_ty: MuTypeNode, sig: MuFuncSigNode, callee: MuVarNode, args: MuValueFakArrayPtr, nargs: Int): MuValueFak = exposeMuValue(ctx, ctx.newCCall(bb, callconv, callee_ty, sig, callee, readFromValueFakArray(args, nargs)))
def new_newthread(ctx: MuCtx, bb: MuBBNode, stack: MuVarNode, threadlocal: Option[MuVarNode]): MuValueFak = exposeMuValue(ctx, ctx.newNewThread(bb, stack, threadlocal))
def new_swapstack_ret(ctx: MuCtx, bb: MuBBNode, swappee: MuVarNode, ret_tys: MuValueFakArrayPtr, nret_tys: Int): MuValueFak = exposeMuValue(ctx, ctx.newSwapStackRet(bb, swappee, readFromValueFakArray(ret_tys, nret_tys)))
def new_swapstack_kill(ctx: MuCtx, bb: MuBBNode, swappee: MuVarNode): MuValueFak = exposeMuValue(ctx, ctx.newSwapStackKill(bb, swappee))
def set_newstack_pass_values(ctx: MuCtx, inst: MuInstNode, tys: MuValueFakArrayPtr, vars: MuValueFakArrayPtr, nvars: Int): Unit = ctx.setNewStackPassValues(inst, readFromValueFakArray(tys, nvars), readFromValueFakArray(vars, nvars))
def set_newstack_throw_exc(ctx: MuCtx, inst: MuInstNode, exc: MuVarNode): Unit = ctx.setNewStackThrowExc(inst, exc)
def new_comminst(ctx: MuCtx, bb: MuBBNode, opcode: MuCommInst, flags: MuFlagArrayPtr, nflags: Int, tys: MuValueFakArrayPtr, ntys: Int, sigs: MuValueFakArrayPtr, nsigs: Int, args: MuValueFakArrayPtr, nargs: Int): MuValueFak = exposeMuValue(ctx, ctx.newCommInst(bb, opcode, readFromFlagArray(flags, nflags), readFromValueFakArray(tys, ntys), readFromValueFakArray(sigs, nsigs), readFromValueFakArray(args, nargs)))
// PASTE TO HERE
}
/**
......@@ -419,9 +506,192 @@ object NativeMuHelpers {
case MU_UMIN => AtomicRMWOptr.UMIN
}
implicit def intToCallConv(cc: MuCallConv): Flag = cc match {
implicit def intToFlag(cc: MuFlag): Flag = cc match {
case MU_DEFAULT => Flag("#DEFAULT")
case _ => throw new UvmRuntimeException("Unknown flag %d 0x%x".format(cc, cc))
}
def readFromValueFakArray[T <: MuValue](faks: MuValueFakArrayPtr, len: Long): Seq[T] = {
for (i <- 0L until len) yield {
val addr = faks + i * WORD_SIZE_BYTES
val valFak = theMemory.getAddress(addr)
val v = getMuValueNotNull(valFak)
v.asInstanceOf[T]
}
}
def readFromFlagArray(flags: MuValueFakArrayPtr, len: Long): Seq[Flag] = {
val flagVals = for (i <- 0L until len) yield {
val addr = flags + i * 32
val flagVal = theMemory.getInt(addr)
flagVal
}
flagVals.map(intToFlag)
}
implicit class MuCtxExtras(val ctx: MuCtx) extends AnyVal {
def newConstIntEx(b: MuBundleNode, ty: MuTypeNode, values: LongPtr, nvalues: Int): MuConstNode = {
val longs = for (i <- 0L until nvalues.toLong) yield {
val addr = values + i * WORD_SIZE_BYTES
val v = theMemory.getAddress(addr)
v
}
var bi = BigInt(0L)
var power = 0
for (l <- longs) {
bi |= ((BigInt(l) & 0xffffffffffffffffl) << power)
power += WORD_SIZE_BITS.toInt
}
ctx.newConstInt(b, ty, bi)
}
}
val MU_DEST_NORMAL = 0x01L
val MU_DEST_EXCEPT = 0x02L
val MU_DEST_TRUE = 0x03L
val MU_DEST_FALSE = 0x04L
val MU_DEST_DEFAULT = 0x05L
val MU_DEST_DISABLED = 0x06L
val MU_DEST_ENABLED = 0x07L
implicit def intToDestKind(dk: MuDestKind): DestKind.Value = dk match {
case MU_DEST_NORMAL => DestKind.NORMAL
case MU_DEST_EXCEPT => DestKind.EXCEPT
case MU_DEST_TRUE => DestKind.TRUE
case MU_DEST_FALSE => DestKind.FALSE
case MU_DEST_DEFAULT => DestKind.DEFAULT
case MU_DEST_DISABLED => DestKind.DISABLED
case MU_DEST_ENABLED => DestKind.ENABLED
}
val MU_BINOP_ADD = 0x01
val MU_BINOP_SUB = 0x02
val MU_BINOP_MUL = 0x03
val MU_BINOP_SDIV = 0x04
val MU_BINOP_SREM = 0x05
val MU_BINOP_UDIV = 0x06
val MU_BINOP_UREM = 0x07
val MU_BINOP_SHL = 0x08
val MU_BINOP_LSHR = 0x09
val MU_BINOP_ASHR = 0x0A
val MU_BINOP_AND = 0x0B
val MU_BINOP_OR = 0x0C
val MU_BINOP_XOR = 0x0D
val MU_BINOP_FADD = 0xB0
val MU_BINOP_FSUB = 0xB1
val MU_BINOP_FMUL = 0xB2
val MU_BINOP_FDIV = 0xB3
val MU_BINOP_FREM = 0xB4
implicit def intToBinOptr(binop: MuBinOptr): BinOptr.Value = binop match {
case MU_BINOP_ADD => BinOptr.ADD
case MU_BINOP_SUB => BinOptr.SUB
case MU_BINOP_MUL => BinOptr.MUL
case MU_BINOP_SDIV => BinOptr.SDIV
case MU_BINOP_SREM => BinOptr.SREM
case MU_BINOP_UDIV => BinOptr.UDIV
case MU_BINOP_UREM => BinOptr.UREM
case MU_BINOP_SHL => BinOptr.SHL
case MU_BINOP_LSHR => BinOptr.LSHR
case MU_BINOP_ASHR => BinOptr.ASHR
case MU_BINOP_AND => BinOptr.AND
case MU_BINOP_OR => BinOptr.OR
case MU_BINOP_XOR => BinOptr.XOR
case MU_BINOP_FADD => BinOptr.FADD
case MU_BINOP_FSUB => BinOptr.FSUB
case MU_BINOP_FMUL => BinOptr.FMUL
case MU_BINOP_FDIV => BinOptr.FDIV
case MU_BINOP_FREM => BinOptr.FREM
}
val MU_CMP_EQ = 0x20
val MU_CMP_NE = 0x21
val MU_CMP_SGE = 0x22
val MU_CMP_SGT = 0x23
val MU_CMP_SLE = 0x24
val MU_CMP_SLT = 0x25
val MU_CMP_UGE = 0x26
val MU_CMP_UGT = 0x27
val MU_CMP_ULE = 0x28
val MU_CMP_ULT = 0x29
val MU_CMP_FFALSE = 0xC0
val MU_CMP_FTRUE = 0xC1
val MU_CMP_FUNO = 0xC2
val MU_CMP_FUEQ = 0xC3
val MU_CMP_FUNE = 0xC4
val MU_CMP_FUGT = 0xC5
val MU_CMP_FUGE = 0xC6
val MU_CMP_FULT = 0xC7
val MU_CMP_FULE = 0xC8
val MU_CMP_FORD = 0xC9
val MU_CMP_FOEQ = 0xCA
val MU_CMP_FONE = 0xCB
val MU_CMP_FOGT = 0xCC
val MU_CMP_FOGE = 0xCD
val MU_CMP_FOLT = 0xCE
val MU_CMP_FOLE = 0xCF
implicit def intToCmpOptr(cmpop: MuCmpOptr): CmpOptr.Value = cmpop match {
case MU_CMP_EQ => CmpOptr.EQ
case MU_CMP_NE => CmpOptr.NE
case MU_CMP_SGE => CmpOptr.SGE
case MU_CMP_SGT => CmpOptr.SGT
case MU_CMP_SLE => CmpOptr.SLE
case MU_CMP_SLT => CmpOptr.SLT
case MU_CMP_UGE => CmpOptr.UGE
case MU_CMP_UGT => CmpOptr.UGT
case MU_CMP_ULE => CmpOptr.ULE
case MU_CMP_ULT => CmpOptr.ULT
case MU_CMP_FFALSE => CmpOptr.FFALSE
case MU_CMP_FTRUE => CmpOptr.FTRUE
case MU_CMP_FUNO => CmpOptr.FUNO
case MU_CMP_FUEQ => CmpOptr.FUEQ
case MU_CMP_FUNE => CmpOptr.FUNE
case MU_CMP_FUGT => CmpOptr.FUGT
case MU_CMP_FUGE => CmpOptr.FUGE
case MU_CMP_FULT => CmpOptr.FULT
case MU_CMP_FULE => CmpOptr.FULE
case MU_CMP_FORD => CmpOptr.FORD
case MU_CMP_FOEQ => CmpOptr.FOEQ
case MU_CMP_FONE => CmpOptr.FONE
case MU_CMP_FOGT => CmpOptr.FOGT
case MU_CMP_FOGE => CmpOptr.FOGE
case MU_CMP_FOLT => CmpOptr.FOLT
case MU_CMP_FOLE => CmpOptr.FOLE
}