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.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.6% of users enabled 2FA.

Commit bbd6780c authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Python binding generated

parent 80c594ae
......@@ -38,11 +38,16 @@ _primitive_types = {
def type_is_explicit_ptr(ty):
return ty.endswith("*")
r_handle_ty = re.compile(r'^Mu\w*(Value|Node)$')
r_handle_ty = re.compile(r'^Mu\w*Value$')
def type_is_handle(ty):
return r_handle_ty.match(ty) is not None
r_node_ty = re.compile(r'^Mu\w*(Node|Clause)$')
def type_is_node(ty):
return r_node_ty.match(ty) is not None
def type_is_ptr(ty):
return type_is_explicit_ptr(ty) or type_is_handle(ty)
......@@ -54,40 +59,6 @@ def to_basic_type(typedefs, name):
name = typedefs[name]
return name
_no_conversion = {
"MuID", # It's just Int.
"MuTrapHandler", # It is a function pointer. Handle in Scala.
"MuCPtr", # Intended to be raw pointer. Passed directly.
"MuCFP", # ditto
"MuWPID", # Just Int
"MuCommInst", # Only used in new_comminst, and the builder uses opcode directly.
}
_array_converters = {
"char*" : "readCharArray",
"uint64_t*" : "readLongArray",
"MuFlag*" : "readFlagArray",
}
_special_converters = {
"MuBool" : "intToBoolean",
"MuName" : "readCString",
"MuMemOrd" : "toMemoryOrder",
"MuAtomicRMWOptr" : "toAtomicRMWOptr",
"MuBinOptr" : "toBinOptr",
"MuCmpOptr" : "toCmpOptr",
"MuConvOptr" : "toConvOptr",
"MuCallConv" : "toFlag",
"MuDestKind" : "toDestKind",
}
_special_return_converters = {
"MuBool" : "booleanToInt",
"MuName" : "exposeString",
"MuCtx*" : "exposeMuCtx",
"MuVM*" : "exposeMicroVM",
}
_manually_defined_types = [
"MuCFP",
"MuValuesFreer",
......@@ -113,7 +84,7 @@ def generate_ctypes(ast):
_enums = [
("MuTrapHandlerResult", 'MU_'),
("MuDestKind", 'MU_DEST_'),
#("MuDestKind", 'MU_DEST_'), # removed
("MuBinOptr", 'MU_BINOP_'),
("MuCmpOptr", 'MU_CMP_'),
("MuConvOptr", 'MU_CONV_'),
......@@ -143,8 +114,7 @@ def generate_cenums(ast):
comminst_defs = enums_map["MuCommInst"]
lines.append("common_instruction_opcodes = {")
for d in comminst_defs:
dp, dv = d["pragmas"], d["value"]
muname = [pv for pk, pv in (p.split(":") for p in dp) if pk == "muname"][0]
muname, dv = d["muname"], d["value"]
lines.append(" '{}': {},".format(muname, dv))
lines.append("}")
......@@ -192,6 +162,7 @@ _defined_in_python = {k for k,v in _enums} | {
_mu_structs = {
"MuVM*": "MuVM",
"MuCtx*": "MuCtx",
"MuIRBuilder*": "MuIRBuilder",
}
def to_python_ty(cty):
......@@ -247,24 +218,71 @@ _method_blacklist = {
"new_thread_exc",
"dump_keepalives",
},
"MuIRBuilder": {
"gen_sym",
},
}
def need_array_wrapper(params):
return any("array_sz_param" in param for param in params)
def generate_method(typedefs, strname, meth) -> Tuple[str, str]:
name = meth['name']
params = meth['params'][1:]
ret_ty = meth['ret_ty']
pragmas = meth['pragmas']
param_tys = [p["type"] for p in params]
py_param_tys = [to_python_ty(t) for t in param_tys]
py_ret_ty = to_python_ty(ret_ty)
if name in _method_blacklist[strname]:
name = name + "_"
naw = need_array_wrapper(params)
if name in _method_blacklist[strname] or naw:
stub_name = name + "_"
else:
stub_name = name
stub = """('{}', {}, [{}]),""".format(
stub_name, py_ret_ty, ", ".join(py_param_tys))
if naw:
formals = [p for p in params if not p.get("is_sz_param", False)]
formal_names = [p["name"] for p in formals]
actual_names = [p["name"] for p in params]
asgns = []
for f in formals:
fn = f["name"]
fcty = f["type"]
ary_ind = f.get("array_sz_param", None)
is_optional = f.get("is_optional", False)
if ary_ind != None:
assert(fcty.endswith("*"))
fcty_elem = fcty[:-1]
asgns.append("_actual_{}_ty = C{} * len({})".format(fn,
fcty_elem, fn))
asgns.append("_actual_{} = _actual_{}_ty()".format(fn, fn))
asgns.append("for _i,_v in enumerate({}):".format(fn))
if type_is_handle(fcty):
asgns.append(" _actual_{}[_i] = _v.c_mu_value".format(fn))
else:
asgns.append(" _actual_{}[_i] = _v".format(fn))
asgns.append("_actual_{} = len({})".format(ary_ind, fn))
elif is_optional and (type_is_node(fcty) or fcty == "MuID"):
asgns.append("_actual_{} = 0 if {} is None else {}".format(fn, fn, fn))
else:
asgns.append("_actual_{} = {}".format(fn, fn))
wrapper = """\
def {}(self, {}):
{}
return self.{}({})
""".format(name, ", ".join(formal_names), "\n".join(" "*8+ln for ln in asgns),
stub_name, ", ".join("_actual_"+n for n in actual_names))
else:
wrapper = None
return """('{}', {}, [{}]),""".format(
name, py_ret_ty, ", ".join(py_param_tys))
return stub, wrapper
def generate_stubs_for_struct(ast, name) -> str:
st = [s for s in ast["structs"] if s["name"] == name][0]
......@@ -272,13 +290,16 @@ def generate_stubs_for_struct(ast, name) -> str:
typedefs = ast["typedefs"]
results = []
stubs = []
wrappers = []
for meth in methods:
code = generate_method(typedefs, name, meth)
results.append(code)
stub, wrapper = generate_method(typedefs, name, meth)
stubs.append(stub)
if wrapper is not None:
wrappers.append(wrapper)
return "\n".join(results)
return "\n".join(stubs), "\n".join(wrappers)
def main():
with open(muapi_h_path) as f:
......@@ -289,8 +310,9 @@ def main():
c_types = generate_ctypes(ast)
c_enums = generate_cenums(ast)
muvalues = generate_muvalues(ast)
muvm_stubs = generate_stubs_for_struct(ast, "MuVM")
muctx_stubs = generate_stubs_for_struct(ast, "MuCtx")
muvm_stubs, _ = generate_stubs_for_struct(ast, "MuVM")
muctx_stubs, _ = generate_stubs_for_struct(ast, "MuCtx")
muirbuilder_stubs, muirbuilder_wrappers = generate_stubs_for_struct(ast, "MuIRBuilder")
injectable_files["libmu.py"].inject_many({
"CTYPES": c_types,
......@@ -298,6 +320,8 @@ def main():
"MUVALUE": muvalues,
"MuVM": muvm_stubs,
"MuCtx": muctx_stubs,
"MuIRBuilder": muirbuilder_stubs,
"wrp_MuIRBuilder": muirbuilder_wrappers,
})
if __name__=='__main__':
......
......@@ -15,7 +15,8 @@ injectable_files = injecttools.make_injectable_file_set(_refimpl2_root, [
("cStubs.scala", "src/main/scala/uvm/refimpl/nat/cStubs.scala",
["STUBS"]),
("libmu.py", "pythonbinding/libmu.py",
["CTYPES", "CENUMS", "MUVALUE", "MuVM", "MuCtx"]),
["CTYPES", "CENUMS", "MUVALUE", "MuVM", "MuCtx", "MuIRBuilder",
"wrp_MuIRBuilder"]),
("comminsts.scala", "src/main/scala/uvm/comminsts/comminsts.scala",
["IRBUILDER_COMMINSTS"]),
("internals.scala", "src/main/scala/uvm/refimpl/internals.scala",
......
from __future__ import division, absolute_import, print_function, unicode_literals
import sys
import ctypes, ctypes.util
from libmu import *
libc = ctypes.CDLL(ctypes.util.find_library("c"))
libc.write.restype = ctypes.c_ssize_t
libc.write.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_size_t]
dll = MuRefImpl2StartDLL("../cbinding/libmurefimpl2start.so")
mu = dll.mu_refimpl2_new_ex(
dumpBundle=True
#vmLog="DEBUG"
#vmLog="INFO"
)
with mu.new_context() as ctx:
# Perpare the C function pointers:
puts_addr = ctypes.cast(libc.puts, ctypes.c_void_p).value
print("puts = ", puts_addr, hex(puts_addr))
# Building bundle...
b = ctx.new_ir_builder()
i32 = b.gen_sym("@i32")
i8 = b.gen_sym("@i8")
pi8 = b.gen_sym("@pi8")
puts_sig = b.gen_sym("@puts.sig")
puts_fp = b.gen_sym("@puts.fp")
puts = b.gen_sym("@puts")
b.new_type_int(i32, 32)
b.new_type_int(i8, 8)
b.new_type_uptr(pi8, i8)
b.new_funcsig(puts_sig, [pi8], [i32])
b.new_type_ufuncptr(puts_fp, puts_sig)
b.new_const_int(puts, pi8, puts_addr)
buf = ctypes.create_string_buffer("Hello python!".encode("ascii"))
buf_addr = ctypes.cast(buf, ctypes.c_void_p).value
print("buf_addr = ", buf_addr, hex(buf_addr))
msg = b.gen_sym("@msg")
b.new_const_int(msg, pi8, buf_addr)
mumain_sig = b.gen_sym("@mumain.sig")
mumain = b.gen_sym("@mumain")
fv = b.gen_sym("@mumain.v1")
entry = b.gen_sym("@mumain.v1.entry")
ccall = b.gen_sym("@mumain.v1.entry.ccall")
ccall_r = b.gen_sym("@mumain.v1.entry.ccall_r")
threadexit = b.gen_sym("@mumain.v1.entry.threadedit")
b.new_funcsig(mumain_sig, [], [])
b.new_func(mumain, mumain_sig)
b.new_func_ver(fv, mumain, [entry])
b.new_bb(entry, [], [], 0, [ccall, threadexit])
b.new_ccall(ccall, [ccall_r], MuCallConv.DEFAULT, puts_fp, puts_sig, puts, [msg], None, None)
b.new_comminst(threadexit, [], common_instruction_opcodes["@uvm.thread_exit"],
[], [], [], [], None, None)
b.load()
hmumain = ctx.handle_from_func(mumain)
st = ctx.new_stack(hmumain)
th = ctx.new_thread(st, None, PassValues())
mu.execute()
print("Returned from Mu.")
This diff is collapsed.
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