Commit b0e2f542 authored by Kunshan Wang's avatar Kunshan Wang

Rebranded to "Mu".

parent dc05de65
============================
MicroVM Design documentation
============================
================
Mu Specification
================
This document aims to provide a detailed description to the MicroVM project,
including its architecture, instruction set and type system.
This document aims to provide a detailed description of Mu, a micro virtual
machine, including its architecture, instruction set and type system.
Contents:
- `Overview <overview>`__
- `µVM Intermediate Representation <uvm-ir>`__
- `µVM IR Binary Form <uvm-ir-binary>`__
- `Intermediate Representation <uvm-ir>`__
- `Intermediate Representation (Binary Form) <uvm-ir-binary>`__
- `Type System <type-system>`__
- `Instruction Set <instruction-set>`__
- `Common Instructions <common-insts>`__
- `Threads and Stacks <threads-stacks>`__
- `µVM Memory and Garbage Collection <uvm-memory>`__
- `Memory and Garbage Collection <uvm-memory>`__
- `Memory Model <memory-model>`__
- `µVM-Client Interface <uvm-client-interface>`__
- `Client Interface <uvm-client-interface>`__
- `Portability and Implementation Advices <portability>`__
Working in progress:
......
......@@ -13,12 +13,12 @@ used with the ``COMMINST`` super instruction. They have:
4. An optional exception clause.
5. A possibly empty (which means optional) keep-alive clause.
*Common instructions* are a mechanism to extend the µVM IR without adding new
*Common instructions* are a mechanism to extend the Mu IR without adding new
instructions or changing the grammar.
NOTE: *Common instructions* were named "intrinsic function" in previous
versions of this document. The name was borrowed from the LLVM. However, the
common instructions in µVM are quite different from the usual concept of
common instructions in Mu are quite different from the usual concept of
intrinsic functions.
Intrinsic functions usually mean a kind a function that is understood
......@@ -30,19 +30,19 @@ instructions or changing the grammar.
tasks that cannot be expressed by the high-level programming language,
including direct raw memory access in Java.
Common instructions only differ from ordinary µVM instructions in that they
Common instructions only differ from ordinary Mu instructions in that they
have a common format and are called by the ``COMMINST`` super instruction.
The purpose is to add more instructions to the µVM IR without having to
The purpose is to add more instructions to the Mu IR without having to
modify the parser.
Common instructions are not µVM functions and cannot be called by the
Common instructions are not Mu functions and cannot be called by the
``CALL`` instruction, nor can it be directly used from the high-level
language that the Client implements. The µVM Client must understand common
instructions because it is the only source of IR code of the µVM. For
language that the client implements. The Mu client must understand common
instructions because it is the only source of IR code of Mu. For
special high-level language functions that cannot be directly implemented in
the high-level programming language, like the methods in the
``java.lang.Thread`` class, the Client must translate those things that are
special in the high-level language to appropriate µVM IR code, which may or
``java.lang.Thread`` class, the client must translate those things that are
special in the high-level language to appropriate Mu IR code, which may or
may not involve common instructions.
This document uses the following notation:
......
This diff is collapsed.
......@@ -2,19 +2,19 @@
Memory Model
============
The µVM memory model basically follows the C11 memory model with a few
modifications to make it suitable for the µVM.
The Mu memory model basically follows the C11 memory model with a few
modifications to make it suitable for Mu.
Overview
========
The µVM does not enforce any strong order, but trusts the Client to correctly
use the atomic and ordering mechanisms provided by the µVM. Many choices of
ordering, from relaxed to sequentially consistent, on each memory operation are
given to the Client. The Client has the freedom to make its choice and has the
responsibility to synchronise their multi-threaded programs.
Mu does not enforce any strong order, but trusts the client to correctly use the
atomic and ordering mechanisms provided by Mu. Many choices of ordering, from
relaxed to sequentially consistent, on each memory operation are given to the
client. The client has the freedom to make its choice and has the responsibility
to synchronise their multi-threaded programs.
The most restricted form of memory accesses are sequentially consistent. The µVM
The most restricted form of memory accesses are sequentially consistent. Mu
guarantees that they are atomic. They follow the well-known acquire-release
memory model and there is a total order of all such memory accesses in all
threads.
......@@ -30,22 +30,22 @@ synchronisation requirements more efficiently than the "acquire" order.
The "relaxed" order only guarantees atomicity but does not enforce any order.
The most unrestricted form of memory access is not atomic. These operations
allows the µVM implementation and the processor to maximise the throughput while
allows the Mu implementation and the processor to maximise the throughput while
relying on the programmer to correctly synchronise their programs.
Notable differences from C11
----------------------------
The program order in the µVM is a total order while the sequenced-before
relationship in C is a partial order, because there are unspecified order of
evaluations in C.
The program order in Mu is a total order while the sequenced-before relationship
in C is a partial order, because there are unspecified order of evaluations in
C.
There is no "atomic type" in µVM. Only operations make a difference between
There is no "atomic type" in Mu. Only operations make a difference between
atomic and non-atomic accesses. Using both atomic and non-atomic operations on
the same memory location is an undefined behaviour in the µVM.
the same memory location is an undefined behaviour in Mu.
The primitives for atomic accesses and fences are provided by the instruction
set of µVM rather than the library. Mutex locks, however, have to be implemented
set of Mu rather than the library. Mutex locks, however, have to be implemented
on top of this memory model.
Notable differences from LLVM
......@@ -77,8 +77,8 @@ memory, initial value, load, store, access and conflict
thread
A thread is the unit of CPU scheduling. In this memory model, threads
include but are not limited to µVM threads. See `<threads-stacks>`__ for the
definition of µVM threads.
include but are not limited to Mu threads. See `<threads-stacks>`__ for the
definition of Mu threads.
stack, stack binding, stack unbinding, swap-stack
See `<threads-stacks>`__
......@@ -92,7 +92,7 @@ Comparison of Terminology
The following table is a approximate comparison and may not strictly apply.
=================== ============================
C µVM
C Mu
=================== ============================
value data value
expression SSA variable
......@@ -137,12 +137,11 @@ futex wake
Wake up threads waiting on a memory location.
external operation
Any other operation that may affect the state outside the µVM.
Any other operation that may affect the state outside Mu.
..
NOTE: Unlike the Java Memory Model, the µVM memory model does not contain
locks.
NOTE: Unlike the Java Memory Model, Mu memory model does not contain locks.
Memory Operations
=================
......@@ -164,14 +163,14 @@ Some instructions and API messages perform memory operations. Specifically,
..
NOTE: Native programs via the Foreign Function Interface can synchronise
with the µVM in an implementation-specific way. But the implementation must
with Mu in an implementation-specific way. But the implementation must
guarantee that the foreign language perform those operations in a way
compatible with the µVM.
compatible with Mu.
For example, there are more than one way to implement loads and stores of
the SEQ_CST order (either put fences in the load or in the store). If the
implementation interfaces with a C implementation (e.g.
gcc+glibc+Linux+x86_64), then the µVM should do the same thing as (or be
gcc+glibc+Linux+x86_64), then Mu should do the same thing as (or be
compatible with) the C program.
Load, store, atomic read-modify-write operations and fences have memory orders,
......@@ -224,23 +223,23 @@ Orders
Program Order
-------------
All evaluations performed by a µVM thread form a total order, in which the
All evaluations performed by a Mu thread form a total order, in which the
operations performed by each evaluation are **sequenced before** operations
performed by its successor.
All operations performed by a µVM Client via a particular Client Agent form a
All operations performed by a Mu client via a particular client agent form a
total order, in which each operation is **sequenced before** its successor.
Specifically, operations performed by trap handlers and undefined function
handlers in the Client are ordered with other operations performed by the µVM
handlers in the client are ordered with other operations performed by the Mu
thread as if they are performed by the ``TRAP``, ``WATCHPOINT``, ``CALL``,
``NEWSTACK`` or other instructions that transfers the control to the handler.
The **program order** contains operations and their "sequenced before"
relations.
NOTE: This means all µVM instructions plus all Client operations done by
the trap handler and undefined function handler in a µVM thread still forms
NOTE: This means all Mu instructions plus all client operations done by
the trap handler and undefined function handler in a Mu thread still forms
a total order.
In C, the program order is a partial order even in a single thread because
......@@ -266,7 +265,7 @@ order M, where the first operation is A and every subsequent operation either is
performed by the same thread that performed the release or is an atomic
read-modify-write operation.
NOTE: In µVM, when a memory location is accessed by both atomic and
NOTE: In Mu, when a memory location is accessed by both atomic and
non-atomic operations, it is an undefined behaviour. So the release sequence
only apply for memory locations only accessed by atomic operations.
......@@ -306,13 +305,12 @@ An evaluation A **synchronises with** another evaluation B if:
NOTE: A thread can be created by the ``@uvm.new_thread`` common instruction
or the ``new_thread`` API message.
NOTE: Since there is no explicit heap memory management in µVM, the
NOTE: Since there is no explicit heap memory management in Mu, the
"synchronises with" relation in C involving ``free`` and ``realloc`` does
not apply in the µVM.
not apply in Mu.
NOTE: The µVM provides very primitive threading support. The "synchronises
with" relations involving ``call_once`` and ``thrd_join`` are not in the
µVM.
NOTE: Mu only provides very primitive threading support. The "synchronises
with" relations involving ``call_once`` and ``thrd_join`` are not in Mu.
NOTE: The "synchronises with" relation between the futex wake and wait is
necessary to ensure the visibility of values written by one thread to be
......@@ -379,7 +377,7 @@ a dependency from* A, if:
would end up that the result is control-dependent on the argument rather
than data dependent.
NOTE: Operations involving ``struct`` types in the µVM may be implemented as
NOTE: Operations involving ``struct`` types in Mu may be implemented as
no-ops. Consider the following::
.typedef @i64 = int<64>
......@@ -393,8 +391,8 @@ a dependency from* A, if:
%y = EXTRACTVALUE <@A 0> %x // %v
%z = EXTRACTVALUE <@A 1> %x // 0
The µVM can alias ``%y`` with ``%v`` in the machine code, but ``%z`` is
always a constant zero.
Mu can alias ``%y`` with ``%v`` in the machine code, but ``%z`` is always a
constant zero.
NOTE: Dependencies may not always be carried across function calls. A
function may return a constant and it is uncertain if any processor respect
......@@ -420,7 +418,7 @@ the following is true:
..
TODO: The "carries a dependency to" relation is not well-defined for the
Client since it may be written in a different language.
client since it may be written in a different language.
The Happens Before Relation
---------------------------
......@@ -543,7 +541,7 @@ operation. The former is sequenced before the latter.
In the evaluation of a ``TRAP`` or ``WATCHPOINT`` instruction, the implied stack
unbinding operation is sequenced before any operations performed by the client.
If the client chooses to return and rebind the stack, the stack binding
operation is sequenced after all operations performed by the Client and the
operation is sequenced after all operations performed by the client and the
implied stack unbinding operation.
Stack binding and unbinding operations are not atomic. If there is a pair of
......
This diff is collapsed.
......@@ -3,41 +3,40 @@ Portability
==============
As both a thin layer over the hardware and an abstraction over concurrency, JIT
compiling and GC, the µVM must strike a balance between portability and the
ability to exploit platform-specific features. Thus the µVM is designed in such
a way that
compiling and GC, Mu must strike a balance between portability and the ability
to exploit platform-specific features. Thus Mu is designed in such a way that
1. There is a basic set of types and instructions that have common and defined
behaviours and reasonably good performance on all platforms.
2. The µVM also includes platform-specific instructions. These instructions are
either defined by this µVM specification or extended by µVM implementations.
2. Mu also includes platform-specific instructions. These instructions are
either defined by this Mu specification or extended by Mu implementations.
In this chapter, **required** features must be implemented by the µVM
In this chapter, **required** features must be implemented by Mu
implementation and **optional** features may or may not be implemented. However,
if an optional feature is implemented, it must behave as specified.
NOTE: Although "behaving as specified", the implementation can still reject
some inputs in a compliant way. For example, if an array type is too large,
the µVM still needs to accept the µVM IR that contains such a type, but may
always refuse to allocate such a type in the memory.
Mu still needs to accept the Mu IR that contains such a type, but may always
refuse to allocate such a type in the memory.
Type System
===========
The ``int`` type of lengths 1, 8, 16, 32, and 64 are required. ``int`` of 6 and
52 bits are required if the µVM also implements the ``tagref64`` type. Other
lengths are optional.
52 bits are required if Mu also implements the ``tagref64`` type. Other lengths
are optional.
Both ``float`` and ``double`` are required.
The vector types ``vector<int<32> 4>``, ``vector<float 4>`` and ``vector<double
2>`` are required. Other vector types are optional.
NOTE: Even though required to be accepted by the µVM, they are not required
to be implemented using hardware-provided vector instructions or vector
registers of the exact same length. They can be implemented totally with
scalar operations and general-purpose registers or memory, or implemented
using different hardware vector sizes, larger or smaller.
NOTE: Even though required to be accepted by Mu, they are not required to be
implemented using hardware-provided vector instructions or vector registers
of the exact same length. They can be implemented totally with scalar
operations and general-purpose registers or memory, or implemented using
different hardware vector sizes, larger or smaller.
Reference types ``ref<T>``, ``iref<T>`` and ``weakref<T>`` are required if ``T``
is implemented. Otherwise optional.
......@@ -45,10 +44,10 @@ is implemented. Otherwise optional.
A struct type ``struct<...>`` are required if it has at most 256 fields and all
of its field types are implemented. Otherwise optional.
An array type ``array<T n>`` is required if T is implemented and n is at most
2^64 Otherwise optional.
An array type ``array<T n>`` is required if T is implemented and n is less than
2^64. Otherwise optional.
NOTE: This implies the µVM must accept arrays of up to 2^64 elements.
NOTE: This implies Mu must accept array types of up to 2^64-1 elements.
However, arrays must be in the memory. Whether such an array can be
successfully allocated is a different story.
......@@ -107,7 +106,7 @@ For shifting instructions ``SHL``, ``LSHR`` and ``ASHR`` for integer type
Conversions instructions are required between any two implemented types that can
be converted. Specifically, given two types T1 and T2 and a conversion operation
CONVOP, if both T1 and T2 are implemented and they satisfied the requirement of
the ``T1`` and ``T2`` parameters of CONVOP (see `instruction-set`__), then the
the ``T1`` and ``T2`` parameters of CONVOP (see `<instruction-set>`__), then the
CONVOP operation converting from T1 to T2 is required.
Binary floating point operations round to nearest and round ties to even.
......@@ -178,7 +177,7 @@ instruction.
Other types are optional for ``CMPXCHG`` and any subset of ``ATOMICRMW``
operations.
One atomic µVM instruction does not necessarily correspond to exactly one
One atomic Mu instruction does not necessarily correspond to exactly one
machine instruction. So some atomic read-modify-write operations can be
implemented using ``CMPXCHG`` or load-link store-conditional constructs.
......@@ -221,6 +220,6 @@ Required when ``tagref64`` is implemented:
* @uvm.tr64.from_int
* @uvm.tr64.from_ref
The µVM implementation may add common instructions.
The Mu implementation may add common instructions.
.. vim: tw=80
......@@ -2,18 +2,18 @@
Threads and Stacks
==================
One unique feature of the µVM is the flexible relation between stacks and
threads. A thread can swap between multiple stacks to achieve light-weighted
context switch. This provides support for language features like co-routines
and green threads.
One unique feature of Mu is the flexible relation between stacks and threads. A
thread can swap between multiple stacks to achieve light-weighted context
switch. This provides support for language features like co-routines and green
threads.
On the other hand, µVM does allow multiple simultaneous threads. µVM threads, by
On the other hand, Mu does allow multiple simultaneous threads. Mu threads, by
design, can be implemented as native OS threads and make use of parallel CPU
resources. µVM also has a memory model. See the `Memory Model <memory-model>`__
resources. Mu also has a memory model. See the `Memory Model <memory-model>`__
chapter for more information.
This chapter discusses µVM threads and µVM stacks. In this chapter, "thread"
means "µVM thread".
This chapter discusses Mu threads and Mu stacks. In this chapter, "thread"
means "Mu thread".
Concepts
========
......@@ -24,19 +24,19 @@ activation. A frame contains the states of all local variables (parameters and
instructions), the program counter and alloca cells (see `<uvm-memory>`__). Each
frame is associated to a version of a function.
NOTE: Because the µVM allows function redefinition, a function may be
redefined and newly created function activations (newly called functions)
use the new definition. But any existing function activations still use the
old definition, thus a frame is only bound to a particular version of a
function, not just a function. This is very important because the µVM cannot
NOTE: Because Mu allows function redefinition, a function may be redefined
and newly created function activations (newly called functions) use the new
definition. But any existing function activations still use the old
definition, thus a frame is only bound to a particular version of a
function, not just a function. This is very important because Mu cannot
magically translate the state of any old function activation to a new one. A
redefined function may even have completely different meaning from the old
one. µVM allows crazy things like redefining a factorial function to a
one. Mu allows crazy things like redefining a factorial function to a
Fibonacci function.
During on-stack replacement, the µVM can tell the Client which version of
which function any frame is executing and the value of KEEPALIVE variables.
The client is responsible for translating the states.
During on-stack replacement, Mu can tell the client which version of which
function any frame is executing and the value of KEEPALIVE variables. The
client is responsible for translating the states.
A **thread** is the unit of CPU scheduling. A thread can be **bound** to a
stack, in which case the thread executes using the stack as its context.
......@@ -80,7 +80,7 @@ create new thread N/A READY<void> -> ACTIVE
swap-stack ACTIVE -> READY<T> or DEAD READY<U> -> ACTIVE
@uvm.kill_stack N/A READY<T> -> DEAD
@uvm.thread_exit ACTIVE -> DEAD N/A
trap to Client ACTIVE -> READY<T> N/A
trap to client ACTIVE -> READY<T> N/A
undefined function ACTIVE N/A
stack-related errors ACTIVE N/A
======================= =============================== =======================
......@@ -88,17 +88,17 @@ stack-related errors ACTIVE N/A
Stack and Thread Creation
=========================
µVM stacks and µVM threads can be created by µVM instructions ``NEWSTACK`` and
``@uvm.new_thread``, or the µVM-Client interface messages ``new_stack`` and
Mu stacks and Mu threads can be created by Mu instructions ``NEWSTACK`` and
``@uvm.new_thread``, or the Mu client interface messages ``new_stack`` and
``new_thread``.
When a stack is created, a µVM function and all of its parameter must be
When a stack is created, a Mu function and all of its parameter must be
provided. The stack will contain a frame created for this function. This frame
is called the **stack-bottom frame** and the function is called the
**stack-bottom function**.
NOTE: The stack-bottom frame is conceptually the last frame in a µVM stack
and returning from that frame has undefined behaviour. But a concrete µVM
NOTE: The stack-bottom frame is conceptually the last frame in a Mu stack
and returning from that frame has undefined behaviour. But a concrete Mu
implementation can still have its own frames or useful data below the
stack-bottom frame. They are implementation-specific details.
......@@ -116,12 +116,12 @@ Thread Termination
==================
A thread is terminated when it executes the ``@uvm.thread_exit`` instruction, or
the Client orders the current thread to terminate in a trap handler.
the client orders the current thread to terminate in a trap handler.
The ``@uvm.thread_exit`` instruction kills the current stack of the current
thread.
The µVM may change the value of ``thread`` type to ``NULL`` if the thread it
Mu may change the value of ``thread`` type to ``NULL`` if the thread it
refers to is terminated.
Binding of Stack and Thread
......@@ -207,13 +207,13 @@ stack enters the **DEAD** state.
If a stack becomes unreachable from roots, the garbage collector may kill the
stack.
The µVM may change the value of ``stack`` type to ``NULL`` if the stack it
The Mu may change the value of ``stack`` type to ``NULL`` if the stack it
refers to is in the **DEAD** state.
On-stack Replacement
====================
The Client can pop and push frames from or to a stack. The ``pop_frame`` API
The client can pop and push frames from or to a stack. The ``pop_frame`` API
message pops the top frame from a stack. The ``push_frame`` message creates a
new frame for a given function and its arguments on the top of a stack.
......@@ -228,19 +228,19 @@ After pushing a frame to a stack, it enters the ``READY<void>`` state and will
continue from the beginning of the function of the frame. Throwing an exception
to such a stack will throw the exception out of the top frame.
NOTE: For the ease of µVM implementation, the new function must continue
NOTE: For the ease of Mu implementation, the new function must continue
from the beginning rather than an arbitrary instruction in the middle.
Continuing from the middle of a function demands too much power from the
code generator.
However, in most OSR scenarios, the desired behaviour is to continue from
the point where the program left out for optimisation. The Client can
the point where the program left out for optimisation. The client can
emulate the behaviour of continuing from the middle of a function by
inserting a "prologue" in the high-level language in the beginning of the
function. For example, in C, the Client can add extra assignment expressions
function. For example, in C, the client can add extra assignment expressions
to initialise local variables to the previous context and use a goto
statement to jump to the location to continue. Then the optimising compiler
can remove unreachable code. As another example, if the Client implements a
can remove unreachable code. As another example, if the client implements a
JVM, it can insert ``Xstore`` instructions and a ``goto`` instruction to
continue from the appropriate bytecode instruction. The optimising compiler
can handle the rest.
......@@ -248,7 +248,7 @@ to such a stack will throw the exception out of the top frame.
Futex
=====
The µVM provides a mechanism similar to the Futex in the Linux kernel for
Mu provides a mechanism similar to the Futex in the Linux kernel for
implementing blocking locks and other synchronisation primitives.
There is a waiting queue for all memory locations that has some integer types.
......@@ -259,17 +259,16 @@ current thread into the waiting queue of a memory location. Both
``@uvm.futex.wake`` and ``@uvm.futex.cmp_requeue`` wakes up threads in a waiting
queue of a memory location.
NOTE: The term *memory location* is defined in the µVM's sense and is
abstract over physical memory or the virtual memory space given by the
operating system. Even if a µVM implementation uses copying or replicating
garbage collectors, the memory location in a heap object remains the same
until the object is collected.
The µVM Futex is designed to be easy to map to the ``futex`` system call on
Linux. With the presence of copying garbage collector, the µVM may
internally perform ``FUTEX_REQUEUE`` or ``FUTEX_CMP_REQUEUE`` operations to
compensate the effect of object movements. It may put barriers around
Futex-related µVM instructions when the GC is concurrently re-queuing
threads.
NOTE: The term *memory location* is defined in Mu's sense and is abstract
over physical memory or the virtual memory space given by the operating
system. Even if a Mu implementation uses copying or replicating garbage
collectors, the memory location in a heap object remains the same until the
object is collected.
The Mu Futex is designed to be easy to map to the ``futex`` system call on
Linux. With the presence of copying garbage collector, Mu may internally
perform ``FUTEX_REQUEUE`` or ``FUTEX_CMP_REQUEUE`` operations to compensate
the effect of object movements. It may put barriers around Futex-related Mu
instructions when the GC is concurrently re-queuing threads.
.. vim: tw=80
......@@ -5,10 +5,10 @@ Type System
Overview
========
The µVM has a comprehensive type system. It is close to the machine level, but
also has reference types for exact garbage collection.
Mu has a comprehensive type system. It is close to the machine level, but also
has reference types for exact garbage collection.
In the µVM IR, a type is created by a (possibly recursive) combination of type
In the Mu IR, a type is created by a (possibly recursive) combination of type
constructors.
By convention, types are written in lower cases. Parameters to types are written
......@@ -20,7 +20,7 @@ constructor.
Type and Data Value
===================
A µVM **type** defines a set where a **data value**, or **value** when
A Mu **type** defines a set where a **data value**, or **value** when
unambiguous, is one of its elements.
A type also has an in-memory format by which its data values can be represented
......@@ -34,7 +34,7 @@ Types and Type Constructors
A **type constructor** represents an **abstract type**. A **concrete type** is
created by applying a type constructor and supplying necessary **parameters**.
The following type constructors are available in the µVM:
The following type constructors are available in Mu:
- int < length >
- float
......@@ -211,11 +211,11 @@ object or memory location.
..
For LLVM users: there is no equivalence in LLVM. µVM guarantees that
all references are identified both in the heap and in the stack and are
subject to garbage collection. The closest counterpart in LLVM is the
pointer type. The µVM does not encourage the use of pointers, though pointer
types will be introduced in µVM in the future.
For LLVM users: there is no equivalence in LLVM. Mu guarantees that all
references are identified both in the heap and in the stack and are subject
to garbage collection. The closest counterpart in LLVM is the pointer type.
Mu does not encourage the use of pointers, though pointer types will be
introduced in Mu in the future.
..
......@@ -308,7 +308,7 @@ of the array.
..
For LLVM users: **An array always has a fixed length**. There is no type for
"array of run-time-determined length" in the µVM type system. The closest
"array of run-time-determined length" in the Mu type system. The closest
counterpart is the ``hybrid`` type.
..
......@@ -400,7 +400,7 @@ Function Types
| 0x0B | sig |
+------+-----+
``func`` is a function reference type. It is an opaque reference to a µVM
``func`` is a function reference type. It is an opaque reference to a Mu
function and is not interchangeable with reference types. *sig* is the signature
of the function it refers to.
......@@ -414,14 +414,14 @@ A ``NULL`` value of a ``func`` type does not refer to any function.
NOTE: The difference between a function signature and the ``func`` is that a
signature can be used in many scenarios, including the foreign function
interface, but a value of the ``func`` type must refer to a µVM function,
not a C function, a Client function, an interpreted high-level language
interface, but a value of the ``func`` type must refer to a Mu function,
not a C function, a client function, an interpreted high-level language
function or anything else.
..
For LLVM users: the ``func`` type in µVM is not a pointer (it may be
implemented under the hood as a pointer to a function, but the Client should
For LLVM users: the ``func`` type in Mu is not a pointer (it may be
implemented under the hood as a pointer to a function, but the client should
not depend on that). It is opaque.
..
......@@ -456,7 +456,7 @@ Opaque Types
| 0x0D |
+------+
``thread`` and ``stack`` are opaque reference types to µVM threads and µVM
``thread`` and ``stack`` are opaque reference types to Mu threads and Mu
stacks, respectively. They are not interchangeable with reference types. Only
some special instructions (e.g. ``NEWSTACK``) or common instructions (e.g.
``@uvm.new_thread``) can operate on them.
......
This diff is collapsed.
==================
µVM IR Binary Form
==================
=========================================
Intermediate Representation (Binary Form)
=========================================
This document describes the binary form of the µVM intermediate representation.
This document describes the binary form of the Mu intermediate representation.
For the text form, see `<uvm-ir>`__.
Overview
========
The µVM IR Binary Form is similar to the `Text Form <uvm-ir>`__ in structure,
The Mu IR Binary Form is similar to the `Text Form <uvm-ir>`__ in structure,
but has notable differences.
Numerical IDs are used exclusively instead of textual names. The binary form
......
===============================
µVM Intermediate Representation
===============================
============================
Intermediate Representation
============================
µVM Intermediate Representation, or (µVM IR), is the language used by µVM to
represent a µVM program. It is the input from the client and can be executed on
the µVM.
Mu Intermediate Representation, or (Mu IR), is the language used by Mu to
represent a Mu program. It is the input from the client and can be executed on
Mu.
The µVM can execute the program in any way, including interpretation, JIT
compiling or even Ahead-of-time compiling.
Mu can execute the program in any way, including interpretation, JIT compiling
or even Ahead-of-time compiling.
µVM IR itself has two defined representations: a text form for human readability
and a binary form for compact encoding. Concrete µVM implementations may
Mu IR itself has two defined representations: a text form for human readability
and a binary form for compact encoding. Concrete Mu implementations may
introduce their own formats as long as they are equivalent.
This document describes the text form and the aspects not specific to the binary
......@@ -24,7 +24,7 @@ For the documents of the type system and the instruction set, see:
Example
=======
Here is an example of µVM IR in the text form::
Here is an example of Mu IR in the text form::
.typedef @i64 = int<64>
.typedef @double = double
......@@ -76,7 +76,7 @@ function or a new version of a function that replaces the old version::
Top-level Structure
===================
A **bundle** is the unit of code the client sends to the µVM. It contains many
A **bundle** is the unit of code the client sends to Mu. It contains many
**top-level definitions**. A top-level definition shall be a **type
definition**, **function signature definition**, **constant definition**,
**global cell definition**, **function definition** or **function declaration**.
......@@ -86,7 +86,7 @@ definition**, **function signature definition**, **constant definition**,
Identifiers and Names
---------------------
Many entities in the µVM are **identified**. An identified entity has an
Many entities in Mu are **identified**. An identified entity has an
identifiers (ID) and optionally a name. An identifier (ID) is a 32-bit integer.
A name is a string starting with a ``@`` or a ``%`` and followed by many
characters in the set: ``[0-9a-zA-Z_-.]``. An ID uniquely identifies an
......@@ -96,7 +96,7 @@ characters in the set: ``[0-9a-zA-Z_-.]``. An ID uniquely identifies an
dictionary would define "entity" as "a thing with distinct and independent
existence".
In the µVM IR text form, names are exclusively used and IDs are automatically
In the Mu IR text form, names are exclusively used and IDs are automatically
generated. In the binary form, IDs are exclusively generated and names can be
introduced via name-binding.
......@@ -106,18 +106,18 @@ introduced via name-binding.
.typedef @i64 = int<64>
.typedef @long = int<64>
In the µVM IR, if ``@i64`` and ``@long`` are declared this way, they can be
In the Mu IR, if ``@i64`` and ``@long`` are declared this way, they can be
used interchangeably. For example, an ``ADD`` instruction can add an
``@i64`` value to a ``@long`` value because both are ``int<64>``.
NOTE: Just because some kinds of entities are identified does not mean all
entities of that kind in a concrete µVM implementation must have IDs and
names. Types are one example. Type definitions in the µVM IR are always
identified, but some µVM instructions may yield values of types that are not
entities of that kind in a concrete Mu implementation must have IDs and
names. Types are one example. Type definitions in the Mu IR are always
identified, but some Mu instructions may yield values of types that are not
defined in the IR. For example, the ``CMPXCHG`` instruction on type *T*
yields a value of type ``struct<T int<1>>`` where the second field indicates
whether the ``CMPXCHG`` operation is successful. The struct type may not be
defined in the IR, but the µVM IR program cannot make use of the result
defined in the IR, but the Mu IR program cannot make use of the result
unless it defines a type for the struct type because the ``EXTRACTVALUE``
instruction takes a type parameter which is the type of the struct value
parameter. For example::
......@@ -140,7 +140,8 @@ Names
A **global name** begins with ``@``. All identified entities can use global
names. Top-level definitions and the version name of functions must use global
names. Global names are valid in the whole µVM, not limited to a single bundle.
names. Global names are valid in a whole Mu instance, not limited to a single
bundle.
Example::
......@@ -211,10 +212,10 @@ Identifiers
~~~~~~~~~~~
All identifiers are global. Every ID must uniquely identify one entity in the
whole µVM.
whole Mu instance.
0 is an invalid ID. IDs in the range of 1-65535 are reserved by the µVM. This
µVM specification only uses 1-32767. 32768-65535 can be used by the µVM
0 is an invalid ID. IDs in the range of 1-65535 are reserved by Mu. The Mu
specification only uses 1-32767. 32768-65535 can be used by the Mu
implementation for extension purposes.
Type Definition
......@@ -364,7 +365,7 @@ A **constant constructor** can be the following:
..
NOTE: The Client must ensure the number (integer or floating point) can be
NOTE: The client must ensure the number (integer or floating point) can be
represented by the type, or it is an error.