To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 6956cb3c authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Hello world example in Python

parent 5ae18741
import sys
import ctypes, ctypes.util
from libmupython2 import *
def slurp(filename):
with open(filename) as t:
return t.read()
prelude_uir = slurp("examples/prelude.uir")
helloworld_uir = slurp("examples/helloworld.uir")
helloworld_hail = slurp("examples/helloworld.hail")
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()
with mu.new_context() as ctx:
# frequently used function
id_of = ctx.id_of
# Load bundles and hail scripts.
ctx.load_bundle(prelude_uir)
ctx.load_bundle(helloworld_uir)
ctx.load_hail(helloworld_hail)
# Perpare the C function pointers:
write_addr = ctypes.cast(libc.write, ctypes.c_void_p).value
print("write_addr = ", write_addr, hex(write_addr))
hwrite_addr = ctx.handle_from_fp(id_of("@write.fp"), write_addr)
hwrite_g = ctx.handle_from_global(id_of("@write.g"))
ctx.store(hwrite_g, hwrite_addr)
# Prepare args.
## new string array
nargs = len(sys.argv)
hnargs = ctx.handle_from_int(nargs, 64)
args = ctx.new_hybrid(id_of("@array_ref_string"), hnargs)
## length
args_ir = ctx.get_iref(args)
args0_ir = ctx.get_field_iref(args_ir, 0)
ctx.store(args0_ir, hnargs)
## elements
argsv_ir = ctx.get_var_part_iref(args_ir)
for i, arg in enumerate(sys.argv):
with DelayedDisposer() as x: ### auto dispose
### new string
arglen = len(arg)
harglen = x << ctx.handle_from_int(arglen, 64)
harg = x << ctx.new_hybrid(id_of("@string"), harglen)
harg_ir = x << ctx.get_iref(harg)
### I ignored the hash
### length
harg1_ir = x << ctx.get_field_iref(harg_ir, 1)
ctx.store(harg1_ir, harglen)
### characters
hargv_ir = x << ctx.get_var_part_iref(harg_ir)
for j, ch in enumerate(arg):
with DelayedDisposer() as y: ### auto dispose
hj = y << ctx.handle_from_int(j, 64)
hargvj_ir = y << ctx.shift_iref(hargv_ir, hj)
hch = y << ctx.handle_from_int(ord(ch), 8)
ctx.store(hargvj_ir, hch)
### add to the array
hi = x << ctx.handle_from_int(i, 64)
argsvi_ir = x << ctx.shift_iref(argsv_ir, hi)
ctx.store(argsvi_ir, harg)
# Create a box to receive the return value from @main.
# Mu stacks cannot return values to the client, so only the memory can be
# used to exchange data.
rvbox = ctx.new_fixed(id_of("@i32"))
_start = ctx.handle_from_func(id_of("@_start"))
st = ctx.new_stack(_start)
th = ctx.new_thread(st, PassValues(args, rvbox))
mu.execute()
rvbox_ir = ctx.get_iref(rvbox)
hrv = ctx.load(rvbox_ir).cast(MuIntValue)
rv = ctx.handle_to_sint(hrv)
print("Returned from Mu. Return value = {}".format(rv))
.newhybrid $hw <@string> 12
.init $hw = {
0
12
{ 0x48 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64 0x21 }
}
.newhybrid $nl <@string> 1
.init $nl = { 0 1 { 0x0a } }
.init @hello_world.g = $hw
.init @newline.g = $nl
.typedef @string = hybrid<
@i64 // hash
@i64 // length
@i8 // bytes
>
.typedef @ref_string = ref<@string>
.global @hello_world.g <@ref_string>
.global @newline.g <@ref_string>
.typedef @array_ref_string = hybrid<
@i64 // length
@ref_string // elements
>
.typedef @ref_array_ref_string = ref<@array_ref_string>
.typedef @iref_ref_string = iref<@ref_string>
.funcsig @_start.sig = (@ref_array_ref_string @refi32) -> ()
.funcdef @_start VERSION %v1 <@_start.sig> {
%entry(<@ref_array_ref_string> %args <@refi32> %rvbox):
%rv = CALL <@main.sig> @main (%args)
%rvbox_ir = GETIREF <@i32> %rvbox
STORE <@i32> %rvbox_ir %rv
COMMINST @uvm.thread_exit
}
.funcsig @main.sig = (@ref_array_ref_string) -> (@i32)
.funcdef @main VERSION %v1 <@main.sig> {
%entry(<@ref_array_ref_string> %args):
%hw = LOAD <@ref_string> @hello_world.g
CALL <@puts.sig> @puts (%hw)
%args_ir = GETIREF <@array_ref_string> %args
%argsf0_ir = GETFIELDIREF <@array_ref_string 0> %args_ir
%argsv_ir = GETVARPARTIREF <@array_ref_string> %args_ir
%len = LOAD <@i64> %argsf0_ir
BRANCH %head(%argsv_ir @I64_0 %len)
%head(<@iref_ref_string> %argsv_ir <@i64> %i <@i64> %len):
%lt = SLT <@i64> %i %len
BRANCH2 %lt %body(%argsv_ir %i %len) %exit()
%body(<@iref_ref_string> %argsv_ir <@i64> %i <@i64> %len):
%elem_ir = SHIFTIREF <@iref_ref_string @i64> %argsv_ir %i
%str_r = LOAD <@ref_string> %elem_ir
CALL <@puts.sig> @puts (%str_r)
%i2 = ADD <@i64> %i @I64_1
BRANCH %head(%argsv_ir %i2 %len)
%exit():
RET @I32_0
}
.typedef @size_t = int<64>
.funcsig @write.sig = (@i32 @ptrvoid @size_t) -> (@size_t)
.typedef @write.fp = ufuncptr<@write.sig>
.global @write.g <@write.fp>
.funcsig @puts.sig = (@ref_string) -> ()
.funcdef @puts VERSION %v1 <@puts.sig> {
%entry(<@ref_string> %str_r):
CALL <@puts.sig> @print (%str_r)
%nl = LOAD <@ref_string> @newline.g
CALL <@puts.sig> @print (%nl)
RET ()
}
.funcsig @print.sig = (@ref_string) -> ()
.funcdef @print VERSION %v1 <@print.sig> {
%entry(<@ref_string> %str_r):
%str_ir = GETIREF <@string> %str_r
%len_ir = GETFIELDIREF <@string 1> %str_ir
%len = LOAD <@i64> %len_ir
%content_ir = GETVARPARTIREF <@string> %str_ir
%content_ptr = COMMINST @uvm.native.pin <@irefi8> (%content_ir)
%content_ptr_v = PTRCAST <@ptri8 @ptrvoid> %content_ptr
%write = LOAD <@write.fp> @write.g
%rv = CCALL #DEFAULT <@write.fp @write.sig> %write (@I32_1 %content_ptr_v %len)
COMMINST @uvm.native.unpin <@irefi8> (%content_ir)
RET ()
}
.typedef @i1 = int<1>
.typedef @i6 = int<6>
.typedef @i8 = int<8>
.typedef @i16 = int<16>
.typedef @i32 = int<32>
.typedef @i52 = int<52>
.typedef @i64 = int<64>
.typedef @float = float
.typedef @double = double
.typedef @void = void
.typedef @thread = threadref
.typedef @stack = stackref
.typedef @tagref64 = tagref64
.typedef @4xi32 = vector <@i32 4>
.typedef @4xfloat = vector <@float 4>
.typedef @2xdouble = vector <@double 2>
.typedef @refi8 = ref<@i8>
.typedef @refi16 = ref<@i16>
.typedef @refi32 = ref<@i32>
.typedef @refi64 = ref<@i64>
.typedef @reffloat = ref<@float>
.typedef @refdouble = ref<@double>
.typedef @irefi8 = iref<@i8>
.typedef @irefi16 = iref<@i16>
.typedef @irefi32 = iref<@i32>
.typedef @irefi64 = iref<@i64>
.typedef @ireffloat = iref<@float>
.typedef @irefdouble= iref<@double>
.typedef @ptrvoid = uptr<@void>
.typedef @ptri8 = uptr<@i8>
.typedef @ptri16 = uptr<@i16>
.typedef @ptri32 = uptr<@i32>
.typedef @ptri64 = uptr<@i64>
.typedef @ptrfloat = uptr<@float>
.typedef @ptrdouble = uptr<@double>
.typedef @ptrptrvoid = uptr<@ptrvoid>
.typedef @weakrefi64 = weakref<@i64>
.typedef @refvoid = ref<@void>
.typedef @irefvoid = iref<@void>
.typedef @weakrefvoid = weakref<@void>
.const @I32_0 <@i32> = 0
.const @I32_1 <@i32> = 1
.const @I64_0 <@i64> = 0
.const @I64_1 <@i64> = 1
.funcsig @v_v = () -> ()
.typedef @frv_v = funcref<@v_v>
.const @NULLREF <@refvoid> = NULL
.const @NULLIREF <@irefvoid> = NULL
.const @NULLFUNC <@frv_v> = NULL
.const @NULLSTACK <@stack> = NULL
.const @NULLREF_I64 <@refi64> = NULL
.const @NULLIREF_I64 <@irefi64> = NULL
......@@ -793,20 +793,28 @@ class DelayedDisposer(object):
def __init__(self):
self.garbages = []
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type != None:
return False
self.delete_all()
return False
def add(self, handle):
self.garbages.append(handle)
if isinstance(handle, MuValue):
self.garbages.append(handle)
else:
for h in handle:
self.add(h)
return handle
def __lshift__(self, rhs):
return self.add(rhs)
def delete_all(self):
if exc_type != None:
return False
for h in reversed(self.garbages):
h.delete();
......
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