api.rst 44 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1 2 3
===================
Mu Client Interface
===================
Kunshan Wang's avatar
Kunshan Wang committed
4

Kunshan Wang's avatar
Kunshan Wang committed
5 6
A C header is available here: `<muapi.h>`__

Kunshan Wang's avatar
Kunshan Wang committed
7 8 9
Overview
========

Kunshan Wang's avatar
Kunshan Wang committed
10 11 12 13 14 15 16 17
This chapter defines the **Mu Client Interface**, or "the API", the interfaces
for the client to load bundles and manipulate the state of Mu, including
creating stacks and threads, allocating objects, accessing memory and
manipulating stacks and frames.

It is defined in the C programming language. A C header is available here:
`<muapi.h>`__. Clients can also be written in other languages via language
bindings, which is beyond this specification.
Kunshan Wang's avatar
Kunshan Wang committed
18

Kunshan Wang's avatar
Kunshan Wang committed
19 20 21 22 23 24
    **Tools available**: A Python script `muapiparser.py
    <scripts/muapiparser.py>`__ is available. It parses the `<muapi.h>`__ header
    and generates a JSON-like tree. Language binding developers can use this
    script to automatically generate interfaces to higher-level languages.

Most API functions are also available in the form of `instructions
25 26
<instruction-set.rst>`__ (such as ``refcast`` and ``REFCAST``) or `common
instructions <common-insts.rst>`__ (such as ``new_stack`` and
Kunshan Wang's avatar
Kunshan Wang committed
27 28
``@uvm.new_stack``). See their respective chapters.

Kunshan Wang's avatar
Kunshan Wang committed
29 30 31
Starting Up and Shutting Down
=============================

Kunshan Wang's avatar
Kunshan Wang committed
32
How to start a Mu micro VM instance or a client is implementation-specific.
Kunshan Wang's avatar
Kunshan Wang committed
33

Kunshan Wang's avatar
Kunshan Wang committed
34 35 36 37
The Mu specification defines some types for using with common instructions, such
as ``@uvm.meta.byteref``. These types are always available. Whether other types,
signatures, constants, global cells or functions are already defined, declared
or exposed, or whether any Mu objects, stacks or Mu threads already created is
Kunshan Wang's avatar
Kunshan Wang committed
38
implementation-specific.
Kunshan Wang's avatar
Kunshan Wang committed
39

Kunshan Wang's avatar
Kunshan Wang committed
40 41
How to stop a Mu micro VM and/or a client is implementation-specific. Stopping
the micro VM implies stopping all Mu threads in it.
Kunshan Wang's avatar
Kunshan Wang committed
42

Kunshan Wang's avatar
Kunshan Wang committed
43 44 45 46 47
The Mu Micro VM and Client Contexts
===================================

Mu IDs and names are represented as::

48 49 50 51
    // C-style '\0'-terminated string
    typedef char *MuCString;

    // Identifiers and names of Mu
Kunshan Wang's avatar
Kunshan Wang committed
52 53 54 55 56 57 58 59
    typedef uint32_t MuID;
    typedef char *MuName;

A Mu instance is represented as a pointer to the struct ``MuVM``::

    typedef struct MuVM MuVM;

    struct MuVM {
Kunshan Wang's avatar
Kunshan Wang committed
60 61 62 63 64 65
        void   *header;   // Refer to internal stuff

        MuCtx* (*new_context     )(MuVM *mvm);
        MuID   (*id_of           )(MuVM *mvm, MuName name);
        MuName (*name_of         )(MuVM *mvm, MuID id);
        void   (*set_trap_handler)(MuVM *mvm, MuTrapHandler trap_handler, MuCPtr userdata);
66 67

        void   (*make_boot_image)(MuVM *mvm, MuID* whitelist, MuArraySize whitelist_sz, MuCString output_file);
Kunshan Wang's avatar
Kunshan Wang committed
68 69
    };

70 71
.. _client-context:

Kunshan Wang's avatar
Kunshan Wang committed
72 73 74 75 76 77 78 79 80 81
The client interacts with Mu for almost all tasks through **client contexts**,
or simply **context** when unambiguous.

    NOTE: In older versions of the spec, it was called "client agent".

A client context is represented as a pointer to the struct ``MuCtx``::

    typedef struct MuCtx MuCtx;

    struct MuCtx {
Kunshan Wang's avatar
Kunshan Wang committed
82 83 84 85 86 87 88
        void   *header;   // Refer to internal stuff

        MuID   (*id_of        )(MuCtx *ctx, MuName name);
        MuName (*name_of      )(MuCtx *ctx, MuID id);
        void   (*close_context)(MuCtx *ctx);
        void   (*load_bundle  )(MuCtx *ctx, char *buf, MuArraySize sz);
        void   (*load_hail    )(MuCtx *ctx, char *buf, MuArraySize sz);
Kunshan Wang's avatar
Kunshan Wang committed
89 90
        ...
    };
Kunshan Wang's avatar
Kunshan Wang committed
91 92
    
The full list of member function pointers is listed in the header `<muapi.h>`__.
Kunshan Wang's avatar
Kunshan Wang committed
93 94 95 96

Both the ``MuVM`` and the ``MuCtx`` struct contain many function pointer fields.
Each function pointer must be called with the ``MuVM`` or ``MuCtx`` pointer as
its first argument.
Kunshan Wang's avatar
Kunshan Wang committed
97

Kunshan Wang's avatar
Kunshan Wang committed
98 99
    NOTE: This design is inspired by JNI. Exposing API functions as struct
    members rather than as global C functions has two advantages:
Kunshan Wang's avatar
Kunshan Wang committed
100

Kunshan Wang's avatar
Kunshan Wang committed
101 102
    1. A client can use multiple Mu implementations at the same time. Each
       implementation should provide its own structures.
Kunshan Wang's avatar
Kunshan Wang committed
103

Kunshan Wang's avatar
Kunshan Wang committed
104 105 106 107 108 109
    2. The client does not refer to any symbol in other dynamic libraries. So
       the client does not need to link against any binary libraries at compile
       time. This makes the client less coupled with a particular Mu
       implementation. It also allows the Mu micro VM to provide its API
       functions at the run time (JIT compile its own API functions, or even
       implementing the API in Mu IR itself).
Kunshan Wang's avatar
Kunshan Wang committed
110

Kunshan Wang's avatar
Kunshan Wang committed
111 112 113 114 115 116 117 118
The Mu instance is shared by all client threads, and its member functions can be
called by any client thread without additional synchronisation. A client context
can only be used by one client thread at a time.

    NOTE: Client contexts are supposed to hold thread-local states similar to
    what a Mu thread holds. For example, implementations may reserve blocks of
    heap memory in client contexts so that memory allocation will not always
    require global locks. This trick is used by many garbage collectors that
Kunshan Wang's avatar
Kunshan Wang committed
119 120
    support parallel mutators, for example, `Immix
    <http://users.cecs.anu.edu.au/~steveb/downloads/pdf/immix-pldi-2008.pdf>`__.
Kunshan Wang's avatar
Kunshan Wang committed
121 122 123 124

It holds Mu values for the client. The values are referred by the client via
opaque **handles**. Those handles are defined as::

Kunshan Wang's avatar
Kunshan Wang committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    // Top value type.
    typedef void *MuValue;                // Any Mu value

    // Abstract value type.
    typedef MuValue MuSeqValue;           // array or vector
    typedef MuValue MuGenRefValue;        // ref, iref, funcref, threadref, stackref, framecursorref, irnoderef

    // concrete value types
    typedef MuValue MuIntValue;           // int<n>
    typedef MuValue MuFloatValue;         // float
    typedef MuValue MuDoubleValue;        // double
    typedef MuValue MuUPtrValue;          // uptr
    typedef MuValue MuUFPValue;           // ufuncptr

    typedef MuSeqValue MuStructValue;     // struct<...>
    typedef MuSeqValue MuArrayValue;      // array<T l>
    typedef MuSeqValue MuVectorValue;     // vector<T l>

    typedef MuGenRefValue MuRefValue;           // ref<T>
    typedef MuGenRefValue MuIRefValue;          // iref<T>
    typedef MuGenRefValue MuTagRef64Value;      // tagref64
    typedef MuGenRefValue MuFuncRefValue;       // funcref<sig>
    typedef MuGenRefValue MuThreadRefValue;     // threadref
    typedef MuGenRefValue MuStackRefValue;      // stackref
    typedef MuGenRefValue MuFCRefValue;         // framecursorref
    typedef MuGenRefValue MuIRNodeRefValue;     // irnoderef
Kunshan Wang's avatar
Kunshan Wang committed
151 152

Each handle can only hold a Mu value of the type shown in the comments above.
Kunshan Wang's avatar
Kunshan Wang committed
153 154 155 156
Since the C programming language does not support user-defined type hierarchies,
they are not checked by the C compiler, but the users must only pass appropriate
handles to the appropriate API functions.

Kunshan Wang's avatar
Kunshan Wang committed
157
Handles have reference semantics: a handle refers to a value the client context
Kunshan Wang's avatar
Kunshan Wang committed
158
holds.  Handles can be copied as if they are pointers in C, and the resulting
Kunshan Wang's avatar
Kunshan Wang committed
159
handles refer to the same value held by a context.
Kunshan Wang's avatar
Kunshan Wang committed
160 161 162

A handle is only valid within a client context. They must only be accessed with
API functions that operates on the same context the handle is in. Handles are
Kunshan Wang's avatar
Kunshan Wang committed
163 164 165 166
valid until either the value held by the context is explicitly deleted, or the
client context is closed (explained later). Specifically, like SSA variables in
the IR, a handle of general reference types always refer to the same object,
location or other entities.  This means a handle can keep Mu heap objects alive.
Kunshan Wang's avatar
Kunshan Wang committed
167 168 169 170 171

..

    NOTE: The decision of using opaque handles serves two purposes. Both
    purposes are inspired by the Lua C API and JNI.
Kunshan Wang's avatar
Kunshan Wang committed
172
    
Kunshan Wang's avatar
Kunshan Wang committed
173 174 175 176 177 178
    1. To segregate the type system of Mu and the client. The type system of C
       is very different from Mu. For example, C does not have portable vector
       types. It does not support ``int<n>`` for n other than 8, 16, 32, 64 or
       128. General reference types ``ref``, ``iref``, ``funcref``,
       ``threadref`` and ``stackref`` have no C counterparts, either, and their
       representations are specific to Mu implementations.
Kunshan Wang's avatar
Kunshan Wang committed
179 180

    2. To simplify garbage collection. By recording all references held by the
Kunshan Wang's avatar
Kunshan Wang committed
181
       client, Mu can easily identify all roots. Making the representation
Kunshan Wang's avatar
Kunshan Wang committed
182 183
       of handles implementation-specific gives the client many choices, for
       instance:
Kunshan Wang's avatar
Kunshan Wang committed
184

Kunshan Wang's avatar
Kunshan Wang committed
185
       1. Handles can be raw pointers and all client-held references are pinned.
Kunshan Wang's avatar
Kunshan Wang committed
186
       2. Handles are indices in an indirection table. Since all memory accesses
Kunshan Wang's avatar
Kunshan Wang committed
187
          are done via one indirection, the Mu GC can still move objects.
188

Kunshan Wang's avatar
Kunshan Wang committed
189 190 191
    Lua 4.0, introduced a stack-based API to pass values to/from the C program.
    That stack is unnecessary for Mu because Mu is not a stack-based VM. The API
    is also not designed to frequently exchange data frequently with the client
192
    (see the (unsafe) `Native Interface <native-interface.rst>`__ for a more
Kunshan Wang's avatar
Kunshan Wang committed
193
    efficient (and less safe) interface).
194 195 196

..

Kunshan Wang's avatar
Kunshan Wang committed
197
    For Lua users: The client context is the counterpart of ``lua_State``. Both
Kunshan Wang's avatar
Kunshan Wang committed
198
    maintain a registry of values in order to segregate Lua or Mu types and
Kunshan Wang's avatar
Kunshan Wang committed
199
    garbage collection from the C or client world. However, Mu client context
Kunshan Wang's avatar
Kunshan Wang committed
200
    can also access the Mu memory (heap, stack or global) which is shared
Kunshan Wang's avatar
Kunshan Wang committed
201
    between multiple client context as well as multiple Mu Threads running
Kunshan Wang's avatar
Kunshan Wang committed
202
    concurrently in the same Mu instance. In Lua, ``lua_State`` instances are
203 204 205 206
    isolated.

..

Kunshan Wang's avatar
Kunshan Wang committed
207
    For JNI users: The client context is the counterpart of the context of a JNI
208
    invocation or an "attached" native thread, where there is a registry of Java
Kunshan Wang's avatar
Kunshan Wang committed
209 210 211 212 213
    references. Mu handles are like local references, and the Mu API does not
    have global references. For that need, consider using global cells
    (``.global`` in the IR) to store shared values and use the appropriate
    atomic access and memory order.

Kunshan Wang's avatar
Kunshan Wang committed
214 215 216 217 218 219 220 221 222 223 224 225
Convention
==========

In this document, parameters of type ``MuVM*``, ``MuCtx*`` and all subtypes of
``MuValue`` must no be the C ``NULL`` pointer, or a handle to a Mu ``NULL``
general reference value, unless explicitly stated otherwise. API functions will
not return C ``NULL`` pointers unless explicitly stated otherwise.

    NOTE: This is the billion dollar mistake. Language bindings of high-level
    languages are encouraged to use the ``Option[T]`` type or equivalent, if
    available.

Kunshan Wang's avatar
Kunshan Wang committed
226 227 228
MuVM Functions
==============

Kunshan Wang's avatar
Kunshan Wang committed
229 230
In the following functions, the first argument ``mvm`` must be the same
``MuVM*`` pointer to the ``MuVM`` structure that contains the function pointer.
Kunshan Wang's avatar
Kunshan Wang committed
231

Kunshan Wang's avatar
Kunshan Wang committed
232
::
Kunshan Wang's avatar
Kunshan Wang committed
233

Kunshan Wang's avatar
Kunshan Wang committed
234
    MuCtx* (*new_context)(MuVM *mvm);
Kunshan Wang's avatar
Kunshan Wang committed
235

Kunshan Wang's avatar
Kunshan Wang committed
236
The ``newcontext`` function creates a new client context.
237

Kunshan Wang's avatar
Kunshan Wang committed
238
    For Lua users: This is similar to ``lua_newstate``, but multiple client
239
    contexts share the Mu memory and can be used concurrently.
240

Kunshan Wang's avatar
Kunshan Wang committed
241
::
Kunshan Wang's avatar
Kunshan Wang committed
242

Kunshan Wang's avatar
Kunshan Wang committed
243 244
    MuID    (*id_of  )(MuVM *mvm, MuName name);
    MuName  (*name_of)(MuVM *mvm, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
245

Kunshan Wang's avatar
Kunshan Wang committed
246 247 248
The ``id_of`` function looks up the corresponding ID by a name. The ``name_of``
function looks up the name by an ID. Looking up names or IDs that do not exist
has undefined behaviour.
Kunshan Wang's avatar
Kunshan Wang committed
249

Kunshan Wang's avatar
Kunshan Wang committed
250
::
251

Kunshan Wang's avatar
Kunshan Wang committed
252
    void    (*set_trap_handler      )(MuVM *mvm, MuTrapHandler trap_handler, MuCPtr userdata);
253

254 255 256
The ``set_trap_handler`` function sets the handler for traps. This overrides the
trap handler registered by the ``@uvm.meta.set_trap_handler`` instruction. See
the *Trap Handling* section below for more information.
Kunshan Wang's avatar
Kunshan Wang committed
257

Kunshan Wang's avatar
Kunshan Wang committed
258 259 260
``userdata`` will be passed to the handlers as the last element when they are
called.

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
.. _make-boot-image:

::

    void    (*make_boot_image)(MuVM *mvm, MuID* whitelist, MuArraySize whitelist_sz, MuCString output_file);

The ``make_boot_image`` function creates a boot image which contains all
top-level definitions specified by ``whitelist``, which is an array of IDs. The
length of the array is ``whitelist_sz``. All heap objects reachable from any
global cells in the white-list are also in the boot image. The contents of the
global cells and reachable heap objects are preserved. It is an error if any
threads, stacks, frame cursors or IR Nodes are reachable from the global cells
in the white-list. The process of creating boot image is not atomic. Both
concurrent modifications of the memory reachable from the white-listed global
cells, and concurrent bundle loading, have undefined behaviours.

The IDs and the names of the entities are preserved in the boot image.

The boot image is written to the file specified by ``output_file``, a
``'\0'``-terminated C string.  The format of the boot image is
implementation-defined.

Micro VM implementations may only allow the ``make_boot_image`` function to be
used in certain modes, enabled in implementation-specified manners.

    NOTE: When building boot images, the micro VM implementation may need to
    keep more information about the IR than usual. In usual occasions, the micro
    VM may freely discard information (such as the type information not helpful
    for GC) for space efficiency; but they need to be preserved when scanning
    the heap for values other than references.
    
    For example, an implementation may only enable this function if the VM is
    started with the ``--enable-boot-image-building`` flag. In this case, it
    will record more type information in the object layout.

Kunshan Wang's avatar
Kunshan Wang committed
296 297
MuCtx Functions
===============
Kunshan Wang's avatar
Kunshan Wang committed
298

Kunshan Wang's avatar
Kunshan Wang committed
299 300 301
In the following functions, the first argument ``ctx`` must be the same
``MuCtx*`` pointer to the ``MuCtx`` structure that contains the function
pointer.
Kunshan Wang's avatar
Kunshan Wang committed
302

Kunshan Wang's avatar
Kunshan Wang committed
303 304
Basic functions
---------------
Kunshan Wang's avatar
Kunshan Wang committed
305

Kunshan Wang's avatar
Kunshan Wang committed
306
::
Kunshan Wang's avatar
Kunshan Wang committed
307

Kunshan Wang's avatar
Kunshan Wang committed
308 309
    MuID        (*id_of  )(MuCtx *ctx, MuName name);
    MuName      (*name_of)(MuCtx *ctx, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
310

Kunshan Wang's avatar
Kunshan Wang committed
311 312 313
They are the same as the ``MuVM`` functions. More often than not (such as trap
handling), a client function only has access to a ``MuCtx*`` pointer rather than
a ``MuVM*`` pointer.
Kunshan Wang's avatar
Kunshan Wang committed
314

Kunshan Wang's avatar
Kunshan Wang committed
315
::
Kunshan Wang's avatar
Kunshan Wang committed
316

Kunshan Wang's avatar
Kunshan Wang committed
317
    void        (*close_context)(MuCtx *ctx);
Kunshan Wang's avatar
Kunshan Wang committed
318

Kunshan Wang's avatar
Kunshan Wang committed
319 320 321 322 323 324
The ``close_context`` function closes the current client context. After calling
this function, this ``MuCtx*`` may no longer point to a valid ``MuCtx``
structure and, thus, must not be used again. All values held by this context are
released. Specifically, all values of reference type are cleared so they no
longer strongly refer to objects and keep them alive. All handles created from
this context become invalid.
Kunshan Wang's avatar
Kunshan Wang committed
325

Kunshan Wang's avatar
Kunshan Wang committed
326 327
Implementations may release additional resources, such as context-specific
(thread-local) memory allocation pools.
Kunshan Wang's avatar
Kunshan Wang committed
328

Kunshan Wang's avatar
Kunshan Wang committed
329 330
Bundle and HAIL loading
-----------------------
Kunshan Wang's avatar
Kunshan Wang committed
331

Kunshan Wang's avatar
Kunshan Wang committed
332
::
Kunshan Wang's avatar
Kunshan Wang committed
333

Kunshan Wang's avatar
Kunshan Wang committed
334 335 336 337
    typedef uintptr_t MuArraySize;

    void        (*load_bundle)(MuCtx *ctx, char *buf, MuArraySize sz);
    void        (*load_hail  )(MuCtx *ctx, char *buf, MuArraySize sz);
Kunshan Wang's avatar
Kunshan Wang committed
338

Kunshan Wang's avatar
Kunshan Wang committed
339 340
The ``load_bundle`` function loads a Mu IR bundle, and the ``load_hail``
function loads a HAIL script. The content is held in the memory pointed to by
341
``buf``, and ``sz`` is the length of the content in bytes.
Kunshan Wang's avatar
Kunshan Wang committed
342

343 344 345 346 347
These two functions exist for legacy reasons, and are optional. Implementations
may choose not to implement these two functions, document this behaviour, and
advise the client programmers to use the `IR builder API <irbuilder.rst>`__
instead.

Kunshan Wang's avatar
Kunshan Wang committed
348 349
Concurrency: The content of the bundle or the effect of the HAIL script is fully
visible to other evaluations in the client that *happen after* this call.
Kunshan Wang's avatar
Kunshan Wang committed
350

Kunshan Wang's avatar
Kunshan Wang committed
351
..
Kunshan Wang's avatar
Kunshan Wang committed
352

Kunshan Wang's avatar
Kunshan Wang committed
353
    For Lua users: This is similar to ``lua_load``, but a Mu bundle itself is
Kunshan Wang's avatar
Kunshan Wang committed
354
    not an executable thing like a Lua top-level function.
355

Kunshan Wang's avatar
Kunshan Wang committed
356 357 358 359
    For JVM users: This is similar to class loading. ``load_bundle`` loads the
    code and some Mu-level constants, but some Java-level constants, such as
    Strings, may be mapped to heap objects in Mu, and can be created and
    initialised using HAIL.
Kunshan Wang's avatar
Kunshan Wang committed
360

Kunshan Wang's avatar
Kunshan Wang committed
361 362
Converting values to/from handles
---------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
363

Kunshan Wang's avatar
Kunshan Wang committed
364
::
365

Kunshan Wang's avatar
Kunshan Wang committed
366 367 368 369 370 371 372 373 374 375 376 377 378 379
    // Convert from C values to Mu values
    MuIntValue      (*handle_from_sint8  )(MuCtx *ctx, int8_t     num, int len);
    MuIntValue      (*handle_from_uint8  )(MuCtx *ctx, uint8_t    num, int len);
    MuIntValue      (*handle_from_sint16 )(MuCtx *ctx, int16_t    num, int len);
    MuIntValue      (*handle_from_uint16 )(MuCtx *ctx, uint16_t   num, int len);
    MuIntValue      (*handle_from_sint32 )(MuCtx *ctx, int32_t    num, int len);
    MuIntValue      (*handle_from_uint32 )(MuCtx *ctx, uint32_t   num, int len);
    MuIntValue      (*handle_from_sint64 )(MuCtx *ctx, int64_t    num, int len);
    MuIntValue      (*handle_from_uint64 )(MuCtx *ctx, uint64_t   num, int len);
    MuIntValue      (*handle_from_uint64s)(MuCtx *ctx, uint64_t *nums, MuArraySize nnums, int len);
    MuFloatValue    (*handle_from_float  )(MuCtx *ctx, float      num);
    MuDoubleValue   (*handle_from_double )(MuCtx *ctx, double     num);
    MuUPtrValue     (*handle_from_ptr    )(MuCtx *ctx, MuID mu_type, MuCPtr ptr);
    MuUFPValue      (*handle_from_fp     )(MuCtx *ctx, MuID mu_type, MuCFP fp);
380

Kunshan Wang's avatar
Kunshan Wang committed
381
where ``MuCPtr`` and ``MuCFP`` are convenient definitions for C types::
Kunshan Wang's avatar
Kunshan Wang committed
382

Kunshan Wang's avatar
Kunshan Wang committed
383
    typedef void *MuCPtr;
Kunshan Wang's avatar
Kunshan Wang committed
384 385
    typedef void _MuCFP_Func();
    typedef _MuCFP_Func* MuCFP;     // it is void(*)()
Kunshan Wang's avatar
Kunshan Wang committed
386

Kunshan Wang's avatar
Kunshan Wang committed
387 388 389
The ``handle_from_XintYY`` functions convert C integers to Mu int values.  ``X``
can be ``s`` or ``u``, means the C value is signed or unsigned, respectively.
``YY`` is the number of bits in the C value.
Kunshan Wang's avatar
Kunshan Wang committed
390

Kunshan Wang's avatar
Kunshan Wang committed
391 392 393 394
The ``handle_from_uint64s`` function converts an array of ``uint64_t`` values
into a single Mu int value. ``nums`` points to the array and ``nnums`` is the
length of the array. Lower 64-bit words are stored in lower indices (little
endian).
Kunshan Wang's avatar
Kunshan Wang committed
395

Kunshan Wang's avatar
Kunshan Wang committed
396 397 398 399
The ``len`` parameter is the length of the Mu int value, i.e. the ``n`` in
``int<n>``. If the length of the C value is different from the Mu type, it will
be truncated or extended. It is sign-extended for signed C types or
zero-extended for unsigned C types.
Kunshan Wang's avatar
Kunshan Wang committed
400

Kunshan Wang's avatar
Kunshan Wang committed
401
Other functions are:
402

Kunshan Wang's avatar
Kunshan Wang committed
403
* ``handle_from_float``:    Convert a C ``float`` value to a Mu ``float`` value.
404 405 406

* ``handle_from_double``:   Convert a C ``double`` value to a Mu ``double``
  value.
Kunshan Wang's avatar
Kunshan Wang committed
407

Kunshan Wang's avatar
Kunshan Wang committed
408 409
* ``handle_from_ptr``:      Convert a C object pointer to a Mu pointer value.
  The Mu type is ``mu_type`` which must be ``uptr<T>`` for some type ``T``.
410

Kunshan Wang's avatar
Kunshan Wang committed
411 412 413
* ``handle_from_fp``:       Convert a C function pointer to a Mu function
  pointer value. The Mu type is ``mu_type`` which must be ``ufuncptr<sig>`` for
  some signature ``sig``.
414

415 416
..

Kunshan Wang's avatar
Kunshan Wang committed
417 418 419 420
    For Lua users: These are the counterpart of ``lua_pushnumber``,
    ``lua_pushboolean``, ``lua_pushinteger``, ``lua_pushstring`` and so on. But
    Mu has much fewer primitive data types. Strings usually cannot be created
    this way since they are not primitive values.
421

Kunshan Wang's avatar
Kunshan Wang committed
422 423
    For JNI users: These are similar to the ``NewLocalReference`` function, but
    Mu handles can refer to not just reference types.
424

Kunshan Wang's avatar
Kunshan Wang committed
425
::
426

Kunshan Wang's avatar
Kunshan Wang committed
427 428 429 430 431 432 433 434 435 436 437 438
    int8_t      (*handle_to_sint8 )(MuCtx *ctx, MuIntValue    opnd);
    uint8_t     (*handle_to_uint8 )(MuCtx *ctx, MuIntValue    opnd);
    int16_t     (*handle_to_sint16)(MuCtx *ctx, MuIntValue    opnd);
    uint16_t    (*handle_to_uint16)(MuCtx *ctx, MuIntValue    opnd);
    int32_t     (*handle_to_sint32)(MuCtx *ctx, MuIntValue    opnd);
    uint32_t    (*handle_to_uint32)(MuCtx *ctx, MuIntValue    opnd);
    int64_t     (*handle_to_sint64)(MuCtx *ctx, MuIntValue    opnd);
    uint64_t    (*handle_to_uint64)(MuCtx *ctx, MuIntValue    opnd);
    float       (*handle_to_float )(MuCtx *ctx, MuFloatValue  opnd);
    double      (*handle_to_double)(MuCtx *ctx, MuDoubleValue opnd);
    MuCPtr      (*handle_to_ptr   )(MuCtx *ctx, MuUPtrValue   opnd);
    MuCFP       (*handle_to_fp    )(MuCtx *ctx, MuUFPValue    opnd);
439

Kunshan Wang's avatar
Kunshan Wang committed
440
The ``handle_to_XXX`` functions convert Mu values to C values. Specifically:
441

Kunshan Wang's avatar
Kunshan Wang committed
442 443 444 445 446
The ``handle_to_XintYY`` functions convert Mu int values to C integers. ``X``
can be ``s`` or ``u``, means the C value is signed or unsigned, respectively.
``YY`` is the number of bits in the C value. If the length of the Mu value is
different from the C type, it will be truncated or extended. It is sign-extended
for signed C types or zero-extended for unsigned C types.
447

Kunshan Wang's avatar
Kunshan Wang committed
448
Other functions are:
Kunshan Wang's avatar
Kunshan Wang committed
449

Kunshan Wang's avatar
Kunshan Wang committed
450
* ``handle_to_float``: Convert a Mu ``float`` value to a C ``float`` value.
451

Kunshan Wang's avatar
Kunshan Wang committed
452 453 454
* ``handle_to_double``: Convert a Mu ``double`` value to a C ``double`` value.
  
* ``handle_to_ptr``: Convert a Mu ``uptr<T>`` value to a C ``void*`` value.
455

Kunshan Wang's avatar
Kunshan Wang committed
456 457
* ``handle_to_fp``: Convert a Mu ``ufuncptr<sig>`` value to a C ``void(*)()``
  value.
458 459 460

..

Kunshan Wang's avatar
Kunshan Wang committed
461 462 463
    For Lua users: These are the counterpart of ``lua_tonumber``,
    ``lua_toboolean``, ``lua_tostring`` and so on. But Mu has much fewer
    primitive data types.
464

Kunshan Wang's avatar
Kunshan Wang committed
465 466
    For JNI users: Primitive types in JNI do not need to be converted. They are
    not held by handles and they are already compatible with C data types.
467

Kunshan Wang's avatar
Kunshan Wang committed
468 469
Create handles from Mu global variables
---------------------------------------
470

Kunshan Wang's avatar
Kunshan Wang committed
471
::
472

Kunshan Wang's avatar
Kunshan Wang committed
473 474 475 476
    MuValue         (*handle_from_const )(MuCtx *ctx, MuID id);
    MuIRefValue     (*handle_from_global)(MuCtx *ctx, MuID id);
    MuFuncRefValue  (*handle_from_func  )(MuCtx *ctx, MuID id);
    MuValue         (*handle_from_expose)(MuCtx *ctx, MuID id);
477

Kunshan Wang's avatar
Kunshan Wang committed
478 479
These instructions create handles which has the same value as the Mu global
variables whose ID is ``id``. Specifically,
480

Kunshan Wang's avatar
Kunshan Wang committed
481 482 483 484
* ``handle_from_const``: Creates a handle from a Mu constant.
* ``handle_from_global``: Creates a handle from a Mu global cell.
* ``handle_from_func``: Creates a handle from a Mu function.
* ``handle_from_expose``: Creates a handle from an exposed function.
485

486
..
487

Kunshan Wang's avatar
Kunshan Wang committed
488 489 490
    For Lua users: In Lua, global variables are top-level and they may refer to
    values or functions. These API functions are similar to the
    ``lua_getglobal`` function.
491

Kunshan Wang's avatar
Kunshan Wang committed
492 493 494 495 496
    For JNI users: This is similar to the ``GetStaticObjectField``,
    ``GetStaticFieldID`` or ``GetStaticMethodID`` which allows the C program to
    access fields (including final fields) or methods. Mu does not support OOP
    directly, so methods may be just Mu functions that take objects as
    arguments.
497

Kunshan Wang's avatar
Kunshan Wang committed
498 499
Deleting values held by the context
-----------------------------------
500

Kunshan Wang's avatar
Kunshan Wang committed
501
::
502

Kunshan Wang's avatar
Kunshan Wang committed
503
    void        (*delete_value)(MuCtx *ctx, MuValue opnd);
504

Kunshan Wang's avatar
Kunshan Wang committed
505 506 507
Delete a value held by the context. After calling this function, the handle
``opnd`` cannot be used. If it was copied in C by assignment, all copies refer
to the same value held by the context, and they all become invalid.
508

509 510 511 512 513 514
..

    For Lua users: This is similar to the ``lua_pop`` function.

    For JNI users: This is similar to the ``DeleteLocalRef`` routine.

Kunshan Wang's avatar
Kunshan Wang committed
515 516
Reference type comparison
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
517

Kunshan Wang's avatar
Kunshan Wang committed
518
::
Kunshan Wang's avatar
Kunshan Wang committed
519

Kunshan Wang's avatar
Kunshan Wang committed
520 521 522 523
    typedef int MuBool;

    MuBool      (*ref_eq )(MuCtx *ctx, MuGenRefValue lhs, MuGenRefValue rhs);
    MuBool      (*ref_ult)(MuCtx *ctx, MuIRefValue lhs,   MuIRefValue rhs);
Kunshan Wang's avatar
Kunshan Wang committed
524

Kunshan Wang's avatar
Kunshan Wang committed
525 526 527
The ``ref_eq`` function compares two values of general reference type for
equality according to the semantics of the ``EQ`` instruction. Both ``lhs`` and
``rhs`` must have the same general reference type.
Kunshan Wang's avatar
Kunshan Wang committed
528

Kunshan Wang's avatar
Kunshan Wang committed
529 530 531
The ``ref_ult`` function compares two internal reference ``lhs`` and ``rhs`` for
"less-than" according to the semantics of the ``ULT`` instruction. Both ``lhs``
and ``rhs`` must have the same internal reference type.
Kunshan Wang's avatar
Kunshan Wang committed
532

Kunshan Wang's avatar
Kunshan Wang committed
533
The return value is 1 for true and 0 for false.
Kunshan Wang's avatar
Kunshan Wang committed
534 535 536

..

Kunshan Wang's avatar
Kunshan Wang committed
537 538
    For Lua users: ``ref_eq`` is equivalent to the ``lua_rawequal`` function for
    reference types.
539

Kunshan Wang's avatar
Kunshan Wang committed
540
    For JNI users: ``ref_eq`` is equivalent to the ``IsSameObject`` function.
541

Kunshan Wang's avatar
Kunshan Wang committed
542 543
Aggregate type operations
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
544

Kunshan Wang's avatar
Kunshan Wang committed
545
::
Kunshan Wang's avatar
Kunshan Wang committed
546

Kunshan Wang's avatar
Kunshan Wang committed
547 548
    MuValue     (*extract_value)(MuCtx *ctx, MuStructValue str, int index);
    MuValue     (*insert_value )(MuCtx *ctx, MuStructValue str, int index, MuValue newval);
Kunshan Wang's avatar
Kunshan Wang committed
549 550
    MuValue     (*extract_element)(MuCtx *ctx, MuSeqValue str, MuIntValue index);
    MuSeqValue  (*insert_element )(MuCtx *ctx, MuSeqValue str, MuIntValue index, MuValue newval);
Kunshan Wang's avatar
Kunshan Wang committed
551

Kunshan Wang's avatar
Kunshan Wang committed
552
These functions manipulates values of composite types. Specifically,
Kunshan Wang's avatar
Kunshan Wang committed
553

Kunshan Wang's avatar
Kunshan Wang committed
554 555
* ``extract_value`` returns the value of a field at ``index`` in a struct value
  ``str``.
Kunshan Wang's avatar
Kunshan Wang committed
556

Kunshan Wang's avatar
Kunshan Wang committed
557 558 559 560 561
* ``insert_value`` returns a new struct value which is the same as ``str``
  except the field at ``index`` is replaced with ``newval``.
  
* ``extract_element`` returns the value of an element at ``index`` in an array
  or vector value ``seq``.
Kunshan Wang's avatar
Kunshan Wang committed
562

Kunshan Wang's avatar
Kunshan Wang committed
563 564
* ``insert_element`` returns a new array or vector value which is the same as
  ``seq`` except the element at ``index`` is replaced with ``newval``.
Kunshan Wang's avatar
Kunshan Wang committed
565

Kunshan Wang's avatar
Kunshan Wang committed
566 567 568
``str`` must have struct type. ``seq`` must have array or vector type.
``newval`` must have the type of the field at ``index``, or the element type.
``index`` can be any integer type and is considered unsigned.
Kunshan Wang's avatar
Kunshan Wang committed
569 570 571

..

Kunshan Wang's avatar
Kunshan Wang committed
572 573 574 575 576
    For Lua users: ``extract_value`` and ``insert_value`` are similar to the
    ``lua_getfield`` and the ``lua_setfield`` functions, but Mu struct fields
    are statically typed. ``extract_element`` and ``insert_element`` are similar
    to ``lua_gettable`` and ``lua_settable`` with numerical indices, but Mu has
    arrays and vectors as value types.
Kunshan Wang's avatar
Kunshan Wang committed
577

Kunshan Wang's avatar
Kunshan Wang committed
578 579 580 581 582 583 584
    For JNI users: ``extract_value`` and ``insert_value`` are similar
    ``Get<type>Field`` and ``Set<type>Field``. ``extract_element`` and
    ``insert_element`` are similar to the ``GetObjectArrayElement`` and
    ``SetObjectArrayElement`` if accessing arrays of references. These Mu
    functions work with value types. The ``pin`` and ``unpin`` Mu API function
    are similar to ``Get<PrimitiveType>ArrayElemets`` and
    ``Release<PrimitiveType>ArrayElements`` when the array is in the heap.
Kunshan Wang's avatar
Kunshan Wang committed
585

Kunshan Wang's avatar
Kunshan Wang committed
586 587
Heap memory allocation
======================
Kunshan Wang's avatar
Kunshan Wang committed
588

Kunshan Wang's avatar
Kunshan Wang committed
589
::
Kunshan Wang's avatar
Kunshan Wang committed
590

Kunshan Wang's avatar
Kunshan Wang committed
591 592
    MuRefValue  (*new_fixed )(MuCtx *ctx, MuID mu_type);
    MuRefValue  (*new_hybrid)(MuCtx *ctx, MuID mu_type, MuIntValue length);
593
    
Kunshan Wang's avatar
Kunshan Wang committed
594 595
``new_fixed`` allocates an object in the heap which has ``mu_type`` type.
``mu_type`` must be a fixed-length type.
Kunshan Wang's avatar
Kunshan Wang committed
596

Kunshan Wang's avatar
Kunshan Wang committed
597 598
``new_hybrid`` allocates an object in the heap which has ``mu_type`` type.
``my_type`` must be a hybrid. ``length`` is the length of the variable part.
Kunshan Wang's avatar
Kunshan Wang committed
599

Kunshan Wang's avatar
Kunshan Wang committed
600 601 602
The return value is the object reference of the allocated object, or ``NULL`` (A
``NULL`` pointer in C, which means it does not return a handle. It is not a
handle to a ``NULL`` Mu reference.) when the allocation failed.
Kunshan Wang's avatar
Kunshan Wang committed
603 604 605

..

Kunshan Wang's avatar
Kunshan Wang committed
606 607 608 609 610
    For Lua users: They are similar to the ``lua_newtable`` or
    ``lua_createtable`` function, but Mu can allocate many different types on
    the heap. In this sense, it is also similar to ``lua_newuserdata``, but the
    allocated Mu object has associated metadata to identify references in the
    object.
Kunshan Wang's avatar
Kunshan Wang committed
611

Kunshan Wang's avatar
Kunshan Wang committed
612 613
    For JNI users: They are similar to the ``AllocObject`` and the
    ``New<xxx>Array`` routines. Mu is not aware of "initialiser".
Kunshan Wang's avatar
Kunshan Wang committed
614

Kunshan Wang's avatar
Kunshan Wang committed
615 616
Cast between general reference types
------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
617

Kunshan Wang's avatar
Kunshan Wang committed
618
::
Kunshan Wang's avatar
Kunshan Wang committed
619

Kunshan Wang's avatar
Kunshan Wang committed
620
    MuValue     (*refcast)(MuCtx *ctx, MuValue opnd, MuID new_type);
Kunshan Wang's avatar
Kunshan Wang committed
621

Kunshan Wang's avatar
Kunshan Wang committed
622 623 624
``refcast`` casts a value of general reference types to a new type ``new_type``.
The rules on the old type and the new type and the resulting value follow the
same rules as the ``REFCAST`` instruction.
Kunshan Wang's avatar
Kunshan Wang committed
625

Kunshan Wang's avatar
Kunshan Wang committed
626 627
Memory addressing
-----------------
Kunshan Wang's avatar
Kunshan Wang committed
628

Kunshan Wang's avatar
Kunshan Wang committed
629
::
Kunshan Wang's avatar
Kunshan Wang committed
630

Kunshan Wang's avatar
Kunshan Wang committed
631 632 633 634 635
    MuIRefValue     (*get_iref           )(MuCtx *ctx, MuRefValue opnd);
    MuIRefValue     (*get_field_iref     )(MuCtx *ctx, MuIRefValue opnd, int field);
    MuIRefValue     (*get_elem_iref      )(MuCtx *ctx, MuIRefValue opnd, MuIntValue index);
    MuIRefValue     (*shift_iref         )(MuCtx *ctx, MuIRefValue opnd, MuIntValue offset);
    MuIRefValue     (*get_var_part_iref  )(MuCtx *ctx, MuIRefValue opnd);
Kunshan Wang's avatar
Kunshan Wang committed
636

Kunshan Wang's avatar
Kunshan Wang committed
637 638
* ``get_iref`` converts an object reference into an internal reference to the
  memory location of the whole object.
Kunshan Wang's avatar
Kunshan Wang committed
639

Kunshan Wang's avatar
Kunshan Wang committed
640
* ``get_field_iref`` gets an iref to the ``field``-th field of the struct
641
  or of the fixed part of a hybrid referred by the iref ``opnd``.
Kunshan Wang's avatar
Kunshan Wang committed
642

Kunshan Wang's avatar
Kunshan Wang committed
643 644
* ``get_elem_iref`` gets an iref to the ``index``-th element of the array or
  vector referred by the iref ``opnd``.
Kunshan Wang's avatar
Kunshan Wang committed
645

646 647
* ``shift_iref`` assumes ``opnd`` refers to an element in a memory array
  (including arrays, vectors and the variable part of hybrids in the memory, see
648
  `Mu and the Memory <memory.rst>`__). It returns the iref of ``opnd`` moved by
649
  ``offset`` (forward if positive, backward if negative).
Kunshan Wang's avatar
Kunshan Wang committed
650

Kunshan Wang's avatar
Kunshan Wang committed
651 652
* ``get_var_part_iref`` gets an iref to the 0-th element of the variable part of
  the hybrid referred by iref ``opnd``.
Kunshan Wang's avatar
Kunshan Wang committed
653

Kunshan Wang's avatar
Kunshan Wang committed
654
``index`` and ``offset`` can be any integer types, and are considered signed.
Kunshan Wang's avatar
Kunshan Wang committed
655

Kunshan Wang's avatar
Kunshan Wang committed
656 657
Memory accessing
----------------
Kunshan Wang's avatar
Kunshan Wang committed
658

Kunshan Wang's avatar
Kunshan Wang committed
659
::
Kunshan Wang's avatar
Kunshan Wang committed
660

Kunshan Wang's avatar
Kunshan Wang committed
661 662 663
    MuValue     (*load     )(MuCtx *ctx, MuMemOrd ord, MuIRefValue loc);
    void        (*store    )(MuCtx *ctx, MuMemOrd ord, MuIRefValue loc, MuValue newval);
    MuValue     (*cmpxchg  )(MuCtx *ctx, MuMemOrd ord_succ, MuMemOrd ord_fail,
Kunshan Wang's avatar
Kunshan Wang committed
664 665 666
                        MuBool weak, MuIRefValue loc, MuValue expected, MuValue desired,
                        MuBool *is_succ);
    MuValue     (*atomicrmw)(MuCtx *ctx, MuMemOrd ord, MuAtomicRMWOptr op,
Kunshan Wang's avatar
Kunshan Wang committed
667 668
                        MuIRefValue loc, MuValue opnd);
    void        (*fence    )(MuCtx *ctx, MuMemOrd ord);
Kunshan Wang's avatar
Kunshan Wang committed
669

Kunshan Wang's avatar
Kunshan Wang committed
670
where::
Kunshan Wang's avatar
Kunshan Wang committed
671

Kunshan Wang's avatar
Kunshan Wang committed
672
    typedef uint32_t MuFlag;
Kunshan Wang's avatar
Kunshan Wang committed
673

Kunshan Wang's avatar
Kunshan Wang committed
674 675 676 677 678 679 680 681 682
    // Memory orders
    typedef MuFlag MuMemOrd;
    #define MU_ORD_NOT_ATOMIC   ((MuMemOrd)0x00)
    #define MU_ORD_RELAXED      ((MuMemOrd)0x01)
    #define MU_ORD_CONSUME      ((MuMemOrd)0x02)
    #define MU_ORD_ACQUIRE      ((MuMemOrd)0x03)
    #define MU_ORD_RELEASE      ((MuMemOrd)0x04)
    #define MU_ORD_ACQ_REL      ((MuMemOrd)0x05)
    #define MU_ORD_SEQ_CST      ((MuMemOrd)0x06)
Kunshan Wang's avatar
Kunshan Wang committed
683

Kunshan Wang's avatar
Kunshan Wang committed
684
    // Operations for the atomicrmw API function
Kunshan Wang's avatar
Kunshan Wang committed
685 686 687 688 689 690 691 692 693 694 695 696
    typedef MuFlag MuAtomicRMWOptr;
    #define MU_ARMW_XCHG    ((MuAtomicRMWOptr)0x00)
    #define MU_ARMW_ADD     ((MuAtomicRMWOptr)0x01)
    #define MU_ARMW_SUB     ((MuAtomicRMWOptr)0x02)
    #define MU_ARMW_AND     ((MuAtomicRMWOptr)0x03)
    #define MU_ARMW_NAND    ((MuAtomicRMWOptr)0x04)
    #define MU_ARMW_OR      ((MuAtomicRMWOptr)0x05)
    #define MU_ARMW_XOR     ((MuAtomicRMWOptr)0x06)
    #define MU_ARMW_MAX     ((MuAtomicRMWOptr)0x07)
    #define MU_ARMW_MIN     ((MuAtomicRMWOptr)0x08)
    #define MU_ARMW_UMAX    ((MuAtomicRMWOptr)0x09)
    #define MU_ARMW_UMIN    ((MuAtomicRMWOptr)0x0A)
Kunshan Wang's avatar
Kunshan Wang committed
697

Kunshan Wang's avatar
Kunshan Wang committed
698
* ``load`` performs a *load* operation with arguments (``ord``, *T*, ``loc``).
Kunshan Wang's avatar
Kunshan Wang committed
699

Kunshan Wang's avatar
Kunshan Wang committed
700 701
* ``store`` performs a *store* operation with arguments (``ord``, *T*, ``loc``,
  ``newval``).
Kunshan Wang's avatar
Kunshan Wang committed
702

Kunshan Wang's avatar
Kunshan Wang committed
703
* ``cmpxchg`` performs a *compare exchange* operation with arguments (``weak``,
704 705 706
  ``ord_sicc``, ``ord_fail``, *T*, ``loc``, ``expected``, ``desired``). ``weak``
  is Boolean encoded as int, where 1 means true and 0 means false.  ``*is_succ``
  is set to 1 if successful, or 0 if failed.
Kunshan Wang's avatar
Kunshan Wang committed
707

Kunshan Wang's avatar
Kunshan Wang committed
708 709
* ``atomicrmw`` performs an *atomic-x* operation with argument (``ord``, *T*,
  ``loc``, ``opnd``), where the *x* in *atomic-x* is ``op``.
Kunshan Wang's avatar
Kunshan Wang committed
710

Kunshan Wang's avatar
Kunshan Wang committed
711
* ``fence`` is a fence of memory order ``ord``.
Kunshan Wang's avatar
Kunshan Wang committed
712

Kunshan Wang's avatar
Kunshan Wang committed
713 714 715 716
In the above operations, *T* is the type of the referent type of internal
reference ``loc``. The type of ``newval``, ``expected``, ``desired``, ``opnd``
and the return values of ``store``, ``cmpxchg`` and ``atomicrmw`` is the strong
variant of *T* (``weakref<T>`` becomes ``ref<T>``).
Kunshan Wang's avatar
Kunshan Wang committed
717

Kunshan Wang's avatar
Kunshan Wang committed
718 719 720 721 722
In the case where *T* is a general reference type, ``newval``, ``expected``,
``desired``, ``opnd`` and the return values may be handles to the Mu ``NULL``
value.

The semantics of these instructions are defined by the Mu memory model.
Kunshan Wang's avatar
Kunshan Wang committed
723 724 725

..

726
    For C users: Functions in ``stdatomic.h`` may be implemented in a way
Kunshan Wang's avatar
Kunshan Wang committed
727
    incompatible with Mu. This is implementation-defined.
Kunshan Wang's avatar
Kunshan Wang committed
728

Kunshan Wang's avatar
Kunshan Wang committed
729 730
    For JNI users: ``load`` and ``store`` are similar to ``Get<type>Field`` and
    ``Set<type>Field``.
Kunshan Wang's avatar
Kunshan Wang committed
731

Kunshan Wang's avatar
Kunshan Wang committed
732 733
Stack and thread operations
===========================
Kunshan Wang's avatar
Kunshan Wang committed
734

735 736
.. _new-stack:

Kunshan Wang's avatar
Kunshan Wang committed
737
::
Kunshan Wang's avatar
Kunshan Wang committed
738

Kunshan Wang's avatar
Kunshan Wang committed
739
    // Thread and stack creation and stack destruction
740
    MuStackRefValue     (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
Kunshan Wang's avatar
Kunshan Wang committed
741 742
    MuThreadRefValue    (*new_thread_nor)(MuCtx *ctx, MuStackRefValue stack,
                            MuRefValue threadlocal,
743
                            MuValue *vals, MuArraySize nvals);
Kunshan Wang's avatar
Kunshan Wang committed
744
    MuThreadRefValue    (*new_thread_exc)(MuCtx *ctx, MuStackRefValue stack,
Kunshan Wang's avatar
Kunshan Wang committed
745 746
                            MuRefValue threadlocal,
                            MuRefValue exc);
Kunshan Wang's avatar
Kunshan Wang committed
747
    void                (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
Kunshan Wang's avatar
Kunshan Wang committed
748

Kunshan Wang's avatar
Kunshan Wang committed
749
    // Thread-local object reference
Kunshan Wang's avatar
Kunshan Wang committed
750 751 752 753
    void        (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
                    MuRefValue threadlocal);
    MuRefValue  (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);

Kunshan Wang's avatar
Kunshan Wang committed
754
``new_stack`` creates a new Mu stack with ``func`` as the bottom function.
755 756 757
Returns a stackref to the new stack. The stack-bottom frame will resume from the
very beginning of ``func`` when resumed, and its state is **READY<Ts>**, where
*Ts* is the parameter types of ``func``.
Kunshan Wang's avatar
Kunshan Wang committed
758

Kunshan Wang's avatar
Kunshan Wang committed
759 760 761
``new_thread_nor`` and ``new_thread_exc`` create a new Mu thread and binds it to
``stack``. Returns a threadref to the new thread. ``stack`` must be in the
**READY<Ts>** state for some types *Ts*.
762

Kunshan Wang's avatar
Kunshan Wang committed
763 764 765
- ``new_thread_nor`` passes values to the stack. ``vals`` points to the array of
  values, and ``nvals`` is the length of the array.  The types of the values
  must match the *Ts* types of the stack state.
766

Kunshan Wang's avatar
Kunshan Wang committed
767
- ``new_thread_exc`` throws the exception ``exc`` to the stack.
Kunshan Wang's avatar
Kunshan Wang committed
768

Kunshan Wang's avatar
Kunshan Wang committed
769 770 771 772
The ``threadlocal`` parameter is the initial thread-local reference of the new
thread. If it is a C ``NULL`` pointer, it is equivalent to a Mu ``NULL`` object
reference.

773 774
``kill_stack`` kills the ``stack``. The stack must be in the **READY<Ts>** state
for some *Ts*.  The stack enters the **DEAD** state.  If the stack contains
Kunshan Wang's avatar
Kunshan Wang committed
775
native frames, the behaviour is implementation-defined.
Kunshan Wang's avatar
Kunshan Wang committed
776

Kunshan Wang's avatar
Kunshan Wang committed
777 778 779 780 781
    For Lua users: ``new_stack`` is similar to ``coroutine.create``.
    ``new_thread`` is similar to ``coroutine.resume``, but actually creates a
    new thread. The real counterpart of ``lua_resume`` is the ``SWAPSTACK``
    instruction, which is in the Mu IR but not available in the API.
    ``kill_stack`` is similar to ``lua_close``.
782

Kunshan Wang's avatar
Kunshan Wang committed
783
    For JVM users: The JVM does not distinguish stacks and threads. The closest
Kunshan Wang's avatar
Kunshan Wang committed
784 785 786
    counterpart is the JVM TI function ``StopThread``, but the Mu ``kill_stack``
    message does not unwind the stack. It simply marks the whole stack for
    deletion.
Kunshan Wang's avatar
Kunshan Wang committed
787

Kunshan Wang's avatar
Kunshan Wang committed
788 789 790 791 792 793 794 795 796
``set_threadlocal`` sets the thread-local object reference of the ``thread``
argument to ``threadlocal``.

``get_threadlocal`` returns the current thread-local object reference of
``thread``.

Both ``get_threadlocal`` and ``set_threadlocal`` can only be used in the trap
handler and only on the thread that caused the trap.

Kunshan Wang's avatar
Kunshan Wang committed
797 798
Stack introspection
-------------------
Kunshan Wang's avatar
Kunshan Wang committed
799

Kunshan Wang's avatar
Kunshan Wang committed
800
::
Kunshan Wang's avatar
Kunshan Wang committed
801

802 803 804 805
    MuFCRefValue    (*new_cursor  )(MuCtx *ctx, MuStackRefValue stack);
    void            (*next_frame  )(MuCtx *ctx, MuFCRefValue cursor);
    MuFCRefValue    (*copy_cursor )(MuCtx *ctx, MuFCRefValue cursor);
    void            (*close_cursor)(MuCtx *ctx, MuFCRefValue cursor);
Kunshan Wang's avatar
Kunshan Wang committed
806

807 808
* ``new_cursor`` allocates a frame cursor, referring to the top frame of
  ``stack``. Returns the frame cursor reference.
809

810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
* ``next_frame`` moves the frame cursor so that it refers to the frame below its
  current frame.

* ``copy_cursor`` allocates a frame cursor which refers to the same frame as
  ``cursor``. Returns the frame cursor reference.

* ``close_cursor`` deallocates the cursor.

::

    MuID        (*cur_func       )(MuCtx *ctx, MuFCRefValue cursor);
    MuID        (*cur_func_ver   )(MuCtx *ctx, MuFCRefValue cursor);
    MuID        (*cur_inst       )(MuCtx *ctx, MuFCRefValue cursor);
    void        (*dump_keepalives)(MuCtx *ctx, MuFCRefValue cursor, MuValue *results);

Kunshan Wang's avatar
Kunshan Wang committed
825
These functions operate on the frame referred by ``cursor``. 
826 827 828 829 830 831 832 833 834

* ``cur_func`` returns the ID of the frame. Returns 0 if the frame is native.

* ``cur_func_ver`` returns the ID of the current function version of the frame.
  Returns 0 if the frame is native, or the function of the frame is undefined.

* ``cur_inst`` returns the ID of the current instruction of the frame. Returns 0
  if the frame is just created, its function is undefined, or the frame is
  native.
Kunshan Wang's avatar
Kunshan Wang committed
835

Kunshan Wang's avatar
Kunshan Wang committed
836
* ``dump_keepalives`` dumps the values of the keep-alive variables of the
837 838 839
  current instruction of the frame. If the function is undefined, the arguments
  are the keep-alive variables. Cannot be used on native frames.  As many
  handles as the keep-alive variables are written in the ``results`` array.
Kunshan Wang's avatar
Kunshan Wang committed
840 841
  Values returned in this array may be handles to ``NULL`` values if the
  respective local variable is ``NULL``.
Kunshan Wang's avatar
Kunshan Wang committed
842 843 844

..

Kunshan Wang's avatar
Kunshan Wang committed
845 846 847
    NOTE: The current instruction ID uniquely decides the list of keep-alive
    variables, so the client can always know how long the ``results`` array
    should be allocated.
848

Kunshan Wang's avatar
Kunshan Wang committed
849 850
..

Kunshan Wang's avatar
Kunshan Wang committed
851 852
    For Lua users: The debug interface provides many similar introspection
    functions.
Kunshan Wang's avatar
Kunshan Wang committed
853

Kunshan Wang's avatar
Kunshan Wang committed
854 855 856 857 858 859
    For JVM users: The JVM TI function ``GetFrameLocation`` gets both the method
    ID and the location of instruction. It is like a combination of
    ``cur_func_ver`` and ``cur_inst``. JVM TI has ``GetLocalVariable`` which
    gets any local variable, but Mu only preserves some user-specified local
    variables for introspection. The user, however, can write the ``KEEPALIVE``
    clause to request all local variables to be available.
Kunshan Wang's avatar
Kunshan Wang committed
860

Kunshan Wang's avatar
Kunshan Wang committed
861 862
On-stack replacement
--------------------
Kunshan Wang's avatar
Kunshan Wang committed
863

Kunshan Wang's avatar
Kunshan Wang committed
864
::
Kunshan Wang's avatar
Kunshan Wang committed
865

866 867
    void        (*pop_frames_to)(MuCtx *ctx, MuFCRefValue cursor);
    void        (*push_frame   )(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func);
868

869
* ``pop_frames_to`` pops all frames above ``cursor``.
870

871 872
* ``push_frame`` creates a new frame on the top of ``stack`` for the current
  version of function ``func``.
Kunshan Wang's avatar
Kunshan Wang committed
873 874 875

..

876 877 878
    For JVM users: ``pop_frames_to`` is similar to the ``PopFrame`` JVM TI
    function, but the resumption point is immediately after the call site, not
    immediately before.
Kunshan Wang's avatar
Kunshan Wang committed
879 880


Kunshan Wang's avatar
Kunshan Wang committed
881 882
Tagged reference operations
---------------------------
Kunshan Wang's avatar
Kunshan Wang committed
883

Kunshan Wang's avatar
Kunshan Wang committed
884
::
Kunshan Wang's avatar
Kunshan Wang committed
885

Kunshan Wang's avatar
Kunshan Wang committed
886 887 888
    int             (*tr64_is_fp   )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_int  )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_ref  )(MuCtx *ctx, MuTagRef64Value value);
889 890 891 892 893 894 895 896 897

- ``tr64_is_fp`` checks if ``value`` holds an FP number.
- ``tr64_is_int`` checks if ``value`` holds an integer.
- ``tr64_is_ref`` checks if ``value`` holds a reference.

Return 1 or 0 for true or false.

::

Kunshan Wang's avatar
Kunshan Wang committed
898 899 900 901
    MuDoubleValue   (*tr64_to_fp   )(MuCtx *ctx, MuTagRef64Value value);
    MuIntValue      (*tr64_to_int  )(MuCtx *ctx, MuTagRef64Value value);
    MuRefValue      (*tr64_to_ref  )(MuCtx *ctx, MuTagRef64Value value);
    MuIntValue      (*tr64_to_tag  )(MuCtx *ctx, MuTagRef64Value value);
902 903 904

- ``tr64_to_fp``  returns the FP number held by ``value``.
- ``tr64_to_int`` returns the integer held by ``value``.
Kunshan Wang's avatar
Kunshan Wang committed
905 906
- ``tr64_to_ref`` returns the reference held by ``value``, may be a handle to
  the ``NULL`` value.
907 908 909 910 911 912 913 914
- ``tr64_to_tag`` returns the integer tag held by ``value`` that accompanies the
  reference.

They have undefined behaviours if ``%tr`` does not hold the value of the
expected type.

::

Kunshan Wang's avatar
Kunshan Wang committed
915 916 917 918
    MuTagRef64Value (*tr64_from_fp )(MuCtx *ctx, MuDoubleValue value);
    MuTagRef64Value (*tr64_from_int)(MuCtx *ctx, MuIntValue value);
    MuTagRef64Value (*tr64_from_ref)(MuCtx *ctx, MuRefValue ref, MuIntValue tag);

919 920 921
- ``tr64_from_fp``  creates a ``tagref64`` value from an FP number ``value``.
- ``tr64_from_int`` creates a ``tagref64`` value from an integer ``value``.
- ``tr64_from_ref`` creates a ``tagref64`` value from a reference ``ref`` and
Kunshan Wang's avatar
Kunshan Wang committed
922
  the integer tag ``tag``. ``ref`` may be a handle to the ``NULL`` value.
Kunshan Wang's avatar
Kunshan Wang committed
923

924
Return the created ``tagref64`` value.
Kunshan Wang's avatar
Kunshan Wang committed
925 926 927

Watchpoint operations
---------------------
Kunshan Wang's avatar
Kunshan Wang committed
928

Kunshan Wang's avatar
Kunshan Wang committed
929
::
Kunshan Wang's avatar
Kunshan Wang committed
930

Kunshan Wang's avatar
Kunshan Wang committed
931 932 933 934
    typedef uint32_t MuWPID;

    void        (*enable_watchpoint )(MuCtx *ctx, MuWPID wpid);
    void        (*disable_watchpoint)(MuCtx *ctx, MuWPID wpid);
Kunshan Wang's avatar
Kunshan Wang committed
935

Kunshan Wang's avatar
Kunshan Wang committed
936 937
* ``enable_watchpoint`` enables all watchpoints of ID ``wpid``.
* ``disable_watchpoint`` disables all watchpoints of ID ``wpid``.
Kunshan Wang's avatar
Kunshan Wang committed
938

Kunshan Wang's avatar
Kunshan Wang committed
939
Enabling or disabling any non-existing ``wpid`` has undefined behaviour.
Kunshan Wang's avatar
Kunshan Wang committed
940

Kunshan Wang's avatar
Kunshan Wang committed
941 942
Object pinning
--------------
Kunshan Wang's avatar
Kunshan Wang committed
943

Kunshan Wang's avatar
Kunshan Wang committed
944
::
Kunshan Wang's avatar
Kunshan Wang committed
945

Kunshan Wang's avatar
Kunshan Wang committed
946 947
    MuUPtrValue (*pin  )(MuCtx *ctx, MuValue loc);      // loc is either MuRefValue or MuIRefValue
    void        (*unpin)(MuCtx *ctx, MuValue loc);      // loc is either MuRefValue or MuIRefValue
Kunshan Wang's avatar
Kunshan Wang committed
948

Kunshan Wang's avatar
Kunshan Wang committed
949 950 951
* ``pin`` adds one instance of memory location ``loc`` to the pinning set
  local to the current client context ``ctx``. Returns a pointer which has the
  resulting address. The pointer has the same referent type as loc.
Kunshan Wang's avatar
Kunshan Wang committed
952

Kunshan Wang's avatar
Kunshan Wang committed
953 954 955
* ``unpin`` removes one instance of memory location ``loc`` from the pinning set
  local to the current client context ``ctx``. Attempting to unpin locations
  that has not yet been added has undefined behaviour.
Kunshan Wang's avatar
Kunshan Wang committed
956

Kunshan Wang's avatar
Kunshan Wang committed
957 958 959
``loc`` can be either ``ref<T>`` or ``iref<T>``. If it is ``ref<T>``, it pins
the underlying memory location as obtained by ``get_iref``. In both cases, the
result is ``uptr<T>``.
Kunshan Wang's avatar
Kunshan Wang committed
960

Kunshan Wang's avatar
Kunshan Wang committed
961
..
Kunshan Wang's avatar
Kunshan Wang committed
962

Kunshan Wang's avatar
Kunshan Wang committed
963 964
    For Lua users: Lua userdata are always available as pointers. This assumes
    userdata are always pinned.
Kunshan Wang's avatar
Kunshan Wang committed
965

Kunshan Wang's avatar
Kunshan Wang committed
966 967 968 969
    For JNI users: The ``Get<PrimitiveType>ArrayElements`` and
    ``Release<PrimitiveType>ArrayElements>`` has similar semantics as pinning
    and unpinning. Also note that the argument of ``unpin`` is the same
    reference as what is pinned, not the resulting (untraced) pointer.
Kunshan Wang's avatar
Kunshan Wang committed
970

Kunshan Wang's avatar
Kunshan Wang committed
971 972
Exposing Mu functions for native callback
-----------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
973

Kunshan Wang's avatar
Kunshan Wang committed
974
::
Kunshan Wang's avatar
Kunshan Wang committed
975

Kunshan Wang's avatar
Kunshan Wang committed
976 977
    MuValue     (*expose  )(MuCtx *ctx, MuFuncRefValue func, MuCallConv call_conv, MuIntValue cookie);
    void        (*unexpose)(MuCtx *ctx, MuCallConv call_conv, MuValue value);
Kunshan Wang's avatar
Kunshan Wang committed
978

Kunshan Wang's avatar
Kunshan Wang committed
979
where::
Kunshan Wang's avatar
Kunshan Wang committed
980

Kunshan Wang's avatar
Kunshan Wang committed
981 982
    typedef MuFlag MuCallConv;
    #define MU_CC_DEFAULT   ((MuCallConv)0x00)
Kunshan Wang's avatar
Kunshan Wang committed
983

Kunshan Wang's avatar
Kunshan Wang committed
984 985 986
* ``expose`` exposes a Mu function ``func`` according to the calling convention
  ``call_conv``. ``cookie`` is the attached cookie. The return value is specific
  to the calling convention.
Kunshan Wang's avatar
Kunshan Wang committed
987

Kunshan Wang's avatar
Kunshan Wang committed
988 989 990
* ``unexpose`` invalidates an exposed value ``value`` created by the
  ``@uvm.native.expose`` instruction or the ``expose`` API function with calling
  convention ``call_conv``. 
Kunshan Wang's avatar
Kunshan Wang committed
991

992
See the `Native Interface <native-interface.rst>`__ chapter for details of expose
Kunshan Wang's avatar
Kunshan Wang committed
993 994
and unexpose. See the platform-specific native interface for the return value
type.
Kunshan Wang's avatar
Kunshan Wang committed
995

Kunshan Wang's avatar
Kunshan Wang committed
996
Implementations may define other calling conventions in addition to
Kunshan Wang's avatar
Kunshan Wang committed
997
``MU_CC_DEFAULT``.
Kunshan Wang's avatar
Kunshan Wang committed
998

999 1000
Trap Handling
=============
Kunshan Wang's avatar
Kunshan Wang committed
1001

Kunshan Wang's avatar
Kunshan Wang committed
1002
A trap handler is called when a ``TRAP`` or ``WATCHPOINT`` instruction is
1003
executed. It is also implicitly called when executing an undefined function.
1004

1005 1006
It is unspecified on which stack the trap handler is run.

Kunshan Wang's avatar
Kunshan Wang committed
1007
Mu is allowed to call these handlers concurrently. Mu does not guarantee the
1008
order in which these handlers are called, but guarantees the happen-before
1009
relation between the trap and the handler. See `Memory Model <memory-model.rst>`__.
1010

Kunshan Wang's avatar
Kunshan Wang committed
1011
The Mu thread that triggers the trap is temporarily unbound from the stack.
1012

Kunshan Wang's avatar
Kunshan Wang committed
1013 1014
    NOTE: This unbinding is only conceptual. It is a valid implementation to use
    the same Mu thread to execute the trap handler.
1015

Kunshan Wang's avatar
Kunshan Wang committed
1016
The signature of trap handlers is::
1017

Kunshan Wang's avatar
Kunshan Wang committed
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
    // Signature of the trap handler
    typedef void _MuTrapHandler_Func(
            // input parameters
            MuCtx *ctx,
            MuThreadRefValue thread,
            MuStackRefValue stack,
            MuWPID wpid,
            // output parameters
            MuTrapHandlerResult *result,
            MuStackRefValue *new_stack,
            MuValue **values,
            MuArraySize *nvalues,
            MuValuesFreer *freer,
            MuCPtr *freerdata,
            MuRefValue *exception,
            // input parameter (userdata)
Kunshan Wang's avatar
Kunshan Wang committed
1034
            MuCPtr userdata);
1035

Kunshan Wang's avatar
Kunshan Wang committed
1036
where::
1037

Kunshan Wang's avatar
Kunshan Wang committed
1038
    typedef MuFlag MuTrapHandlerResult;
1039

Kunshan Wang's avatar
Kunshan Wang committed
1040 1041 1042
    #define MU_THREAD_EXIT          ((MuTrapHandlerResult)0x00)
    #define MU_REBIND_PASS_VALUES   ((MuTrapHandlerResult)0x01)
    #define MU_REBIND_THROW_EXC     ((MuTrapHandlerResult)0x02)
1043

Kunshan Wang's avatar
Kunshan Wang committed
1044 1045
    typedef void _MuValuesFreer_Func(MuValue *values, MuCPtr freerdata);
    typedef _MuValuesFreer_Func* MuValuesFreer;
1046

Kunshan Wang's avatar
Kunshan Wang committed
1047 1048 1049
``ctx`` is a new client context created for this particular trap event.
``thread`` is a threadref to the thread that causes the trap. ``stack`` is
stackref to the stack the thread was bound to when trap happened. Both
Kunshan Wang's avatar
Kunshan Wang committed
1050
``thread`` and ``stack`` are held by ``ctx``. ``wpid`` is the watch point ID if
Kunshan Wang's avatar
Kunshan Wang committed
1051 1052
it is caused by a ``WATCHPOINT`` instruction, or 0 if by ``TRAP``. ``userdata``
is the pointer provided when registering the handler.
1053

Kunshan Wang's avatar
Kunshan Wang committed
1054 1055
``ctx`` will be closed when the trap handler returns, so the client must not
close it manually.
1056

Kunshan Wang's avatar
Kunshan Wang committed
1057
Before returning, the trap handler should set ``*result``:
1058

Kunshan Wang's avatar
Kunshan Wang committed
1059
* ``MU_THREAD_EXIT``: The thread ``thread`` terminates.
1060

Kunshan Wang's avatar
Kunshan Wang committed
1061
* ``Mu_REBIND_PASS_VALUES``: The thread ``thread`` will be rebound to a stack
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
  ``*new_stack``. ``*nvalues`` values at ``*values`` are passed to
  ``*new_stack``. The types of ``*values`` must match the type expected by
  ``*new_stack``. Mu will copy the values from the ``*values`` array. Then if
  ``*freer`` is not ``NULL``, Mu will call ``(*freer)(*values, *freerdata)``.

    NOTE: Effectively, the client is returning an array to Mu. Mu does not know
    what stack the client is going to rebind to before calling, therefore the
    client must allocate the array for the values. The client is also
    responsible for freeing the array, but it loses control after returning to
    Mu. So Mu will call the "freer" function on behalf of the client. Usually
    the client can use ``malloc``, and provide a thin wrapper over ``free`` as
    the ``freer``.

Kunshan Wang's avatar
Kunshan Wang committed
1075 1076
* ``Mu_REBIND_THROW_EXC``: The thread ``thread`` will be rebound to a stack
  ``*new_stack``. It throws exception ``*exception`` to the stack.
1077

1078 1079
In all cases, if ``*new_stack``, any value in ``*values``, and/or ``*exception``
are used, they must be set and must be held by ``ctx``.
1080

Kunshan Wang's avatar
Kunshan Wang committed
1081 1082 1083
Building Mu IR Bundles
======================

1084
See `IR Builder <irbuilder.rst>`__ for this part of the API.
Kunshan Wang's avatar
Kunshan Wang committed
1085

Kunshan Wang's avatar
Kunshan Wang committed
1086 1087 1088
Signal Handling
===============

Kunshan Wang's avatar
Kunshan Wang committed
1089
Signal handling is implementation-dependent. Mu may register signal handlers.
1090

Kunshan Wang's avatar
Kunshan Wang committed
1091
.. vim: tw=80