Commit 794b90c4 authored by Kunshan Wang's avatar Kunshan Wang

Boot image extra info setter.

parent d0db63e6
......@@ -90,10 +90,45 @@ The Python binding is in the `pythonbinding` directory. It depends on the C
binding, so make sure you make the C binding first. The Python binding does not
need to be built.
See the `README.md` files in `cbinding` and `pythonbinding` for more details.
See [cbinding/README.md](cbinding/README.md) and
[pythonbinding/README.md](pythonbinding/README.md) for more details.
## How to run
For the impatient: Execute the following command and see Mu running a factorial
example.
```
sbt 'set fork:=true' 'test:runMain junks.FactorialFromRPython'
```
### C API
The reference implementation implements the [Mu Client
API](https://gitlab.anu.edu.au/mu/mu-spec/blob/master/api.rst) which allows C
programs to control the micro VM and construct and deliver bundles for the micro
VM to execute.
See [cbinding/README.md](cbinding/README.md) for more details.
### Scala API
The micro VM itself is implemented in Scala.
- `uvm.refimpl.MicroVM` is the counterpart of the `MuVM` struct in the [Mu
Client API](https://gitlab.anu.edu.au/mu/mu-spec/blob/master/api.rst). It can
be instantiated with VMConf options explained below.
- `uvm.refimpl.MuCtx` is the counterpart of the `MuCtx` struct in C.
- `uvm.refimpl.MuValue` and its subclasses implement the `MuValue` handles.
As an implementation detail, the micro VM will not start execution until
`MicroVM.execute()` is called. See implementation details below.
The Scala interface is closer to the Scala's style. For example, the
`MuCtx.dumpKeepalives()` method returns a `Seq[MuValue]` rather than writing the
results into a given array. It also does more static type checking than the C
interface.
There is a sample factorial program (generously provided by @johnjiabinzhang) in
the `src/test` directory. To run the program with all dependencies on the
classpath, you need to run it with sbt. Invoke `sbt` to enter the interactive
......@@ -113,6 +148,67 @@ sbt 'set fork:=true' 'test:runMain junks.FactorialFromRPython'
`fork := true` tells sbt to run the program in a different process than the one
running sbt itself.
### Boot Image
The reference implementation can create boot images, a package that contains a
Mu IR bundle and a serialised Mu memory, including the global memory and the
heap.
Boot images can be created using the standard `make_boot_image` method on the
MuVM object. In this reference implementation, the boot image is a zip file. By
convention, boot images have the file-name extension `.muref`.
Before a boot image can be executed, an entry point needs to be specified. Use
the `tools/mar.py` script to set the entry point by ID or name. The entry point
is a Mu function that takes an `int<32>` and a `uptr<uptr<int<8>>>` as
parameters, the same as the `main` function in C.
The `tools/mar.py` script can also specify extra libraries to be loaded when the
micro VM loads the boot image. EXTERN constants will be resolved from these
libraries in the order of those libraries.
The `tools/runmu.sh` script runs the micro VM with the given boot image.
Additional arguments are passed to the entry point.
### Micro VM Configuration
There are some parameters that controls the behaviour of the reference
implementation.
When using the C API, the refimpl-specific
[cbinding/refimpl2-start.h](cbinding/refimpl2-start.h) header provides the
`mu_refimpl_new_ex` function which accepts a C-style string. The options are
encoded as `key=value` pairs, one option per line, with no spaces between the
equal sign.
When using the `tools/runmu.sh` script, the options are specified as
command-line options in the form `--key=value` before the boot image file name.
Options:
*Sizes may have suffixes K, M, G or T. 1K = 1024 bytes. sosSize, losSize and
globalSize must be a multiple of 32768 bytes (32K).*
- **sosSize**: The size of the small object space in bytes.
- **losSize**: The size of the large object space in bytes.
- **globalSize**: The size of the large object space in bytes.
- **stackSize**: The size of each stack in bytes.
- **staticCheck**: Run static checker after each bundle is loaded. Default: true
- **sourceInfo**: Provide line/column info in Mu IR when errors occur. May be
useful for debugging small Mu IR bundles, but will significantly slow down
parsing!!! Enable only if the bundle is small. Default: false
- **extraLibs**: Extra libraries to load when starting the micro VM. This is a
colon-separated list of libraries. Each library has the same syntax of the
`path` argument of the `dlopen` system function.
- **bootImg**: The path to the boot image. Only useful in the C API.
*Log levels can be: ALL, TRACE, DEBUG, INFO, WARN, ERROR, OFF. Case-insensitive.
Setting to WARN should get rid of most logging information, except the serious
ones.*
- **vmLog**: The log level of the micro VM.
- **gcLog**: The log level of the garbage collector.
## Implementation details
This reference implementation aims to be easy to work with, but does not have
......@@ -180,10 +276,8 @@ microVM.execute() // The current JVM thread will run on behalf of the MicroVM.
// However, MicroVM will call theTrapHandler.
```
Only the text-based IR and HAIL are implemented. The binary-based IR and HAIL
script do not have high priority at this point, because our current focus is to
implement a correct Mu VM and the text-based IR is easier for debugging. IR
parsing is also not yet known as the bottleneck.
The refimpl implements the text-based IR and HAIL as well as the IR-builder API
to construct Mu IR ASTs programmatically.
### Garbage collection
......@@ -197,10 +291,10 @@ mark-region small object space and a mark-sweep large object space.
a stack, accessing a NULL reference, etc. But this behaviour is not
guaranteed.
- `int<n>` for n = 1 to 64 are implemented. `vec<T n>` is implemented for all T
that are int, float or double, and all n >= 1. However, only 8, 16, 32, 64-bit
integers, float, double, `vec<int<32> 4>`, `vec<float 4>` and `vec<double 2>`
can be loaded or stored from the memory.
- `int<n>` for n = 1 to 128 are implemented. `vec<T n>` is implemented for all T
that are int, float or double, and all n >= 1. However, only 8, 16, 32, 64,
128-bit integers, float, double, `vec<int<32> 4>`, `vec<float 4>` and
`vec<double 2>` can be loaded or stored from the memory.
- The tagged reference type `tagref64` is fully implemented.
......
......@@ -36,7 +36,8 @@ The `libmurefimpl2start.so` library contains functions (defined in
`refimpl2-start.h`) that starts the JVM and create the Mu instance for you.
Your client invokes the `mu_refimpl2_new()` function which returns a `MuVM*`.
After using, call `mu_refimpl2_close` to close it. The `mu_refimpl2_new_ex`
function provides more options.
function provides more options (see [../README.md](../README.md) for a complete
list of options).
Use the `refimpl2-config` script with the `--istart` flag to indicate your
program will create the Mu reference implementation instance. Such clients need
......
......@@ -4,12 +4,19 @@ The Python binding allows the client to be written in Python. This binding is
based on the `ctypes` module and is tested on Python 2, Python 3, PyPy and
PyPy3.
**PyPy-on-Mu contributors**: If you are working on the PyPy project and need to
construct Mu IR bundles from the interpreter or the JIT compiler themselves, you
should use the RPython binding provided by
[mu-client-pypy](https://gitlab.anu.edu.au/mu/mu-client-pypy). The RPython
binding can use either the C API or the common instructions counterpart when
appropriate. We are actively working on the PyPy project.
It depends on the C binding. You need to build the C binding in the
`../cbinding` directory before using this Python binding.
[../cbinding](../cbinding) directory before using this Python binding.
# How to use
See the docstring in `libmu.py`
See the docstring in [libmu.py](libmu.py)
<!--
vim: tw=80 spell
......
#!/usr/bin/env python3
import argparse
import zipfile
import tempfile
import shutil
parser = argparse.ArgumentParser(
description='''Set additional boot-image metadata.''',
epilog='''Example:
./tools/mar.py -n @foo -l libm.so:/path/to/mylib.so my-boot-img.muref
'''
)
entry_point_group = parser.add_mutually_exclusive_group()
entry_point_group.add_argument('-i', '--entry-point-id',
metavar="MuID",
type=int,
help='set the entry point by ID'
)
entry_point_group.add_argument('-n', '--entry-point-name',
metavar="MuName",
help='set the entry point by name'
)
parser.add_argument('-l', '--extra-libraries',
metavar="colon-separated-libs",
help='''extra libraries to load at boot-image loading time. It is a
colon-separated list of libraries.''')
parser.add_argument('bootimg', help='path to the boot image')
args = parser.parse_args()
with tempfile.NamedTemporaryFile(delete=False) as tf:
tmpfilename = tf.name
with zipfile.ZipFile(tf, 'w', compression=zipfile.ZIP_DEFLATED) as zo:
with zipfile.ZipFile(args.bootimg, "a") as zi:
il = zi.infolist()
entrypoint = None
extralibs = None
for info in il:
name = info.filename
if name == 'entrypoint':
entrypoint = zi.read(info)
elif name == 'extralibs':
extralibs = zi.read(info)
else:
oldcontent = zi.read(info)
zo.writestr(name, oldcontent)
if args.entry_point_id is not None:
entrypoint = "id {}".format(args.entry_point_id).encode("utf8")
if args.entry_point_name is not None:
entrypoint = "name {}".format(args.entry_point_name).encode("utf8")
if args.extra_libraries is not None:
extra_libraries = args.extra_libraries.encode("utf8")
if entrypoint is not None:
zo.writestr("entrypoint", entrypoint)
if extralibs is not None:
zo.writestr("extralibs", extralibs)
shutil.move(tmpfilename, args.bootimg)
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