api.rst 45 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
    // Top value type.
    typedef void *MuValue;                // Any Mu value

    // Abstract value type.
    typedef MuValue MuSeqValue;           // array or vector
130
    typedef MuValue MuGenRefValue;        // ref, iref, funcref, threadref, stackref, framecursorref, irbuilderref
Kunshan Wang's avatar
Kunshan Wang committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

    // 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
150
    typedef MuGenRefValue MuIBRefValue;         // irbuilderref
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 163 164 165 166 167 168 169 170 171 172 173 174 175
Handles and their values are **immutable**. This means, once MuCtx created a
handle to a value, the value cannot be changed. Every time an API function is
called, a **new** handle to a **new** value is generated. Some API functions
have confusing names (as a legacy from LLVM) such as ``insertvalue`` or
``insertelement``, but these functions (conceptually) make copies of the old
values, and update the copied values before giving the handle to the client.

Handles are not `constants <ir.rst#constant-definition>`__. Handles are
ephemeral **run-time** value holders, and can only be used through the API.
"Constants", on the other hand, are part of the Mu IR, are **compile-time** SSA
variables, are permanent in the bundle, and are usable by Mu IR instructions.
There is a `handle_from_const <#handle-from-const>`__ API function that creates a new value in the
MuCtx which has the same value of the `constant
<ir.rst#constant-definition>`__, and returns its handle to the client.

Kunshan Wang's avatar
Kunshan Wang committed
176 177
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
178 179 180 181
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
182 183 184 185 186

..

    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
187
    
Kunshan Wang's avatar
Kunshan Wang committed
188 189 190 191 192 193
    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
194 195

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

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

Kunshan Wang's avatar
Kunshan Wang committed
204 205 206
    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
207
    (see the (unsafe) `Native Interface <native-interface.rst>`__ for a more
Kunshan Wang's avatar
Kunshan Wang committed
208
    efficient (and less safe) interface).
209 210 211

..

Kunshan Wang's avatar
Kunshan Wang committed
212
    For Lua users: The client context is the counterpart of ``lua_State``. Both
Kunshan Wang's avatar
Kunshan Wang committed
213
    maintain a registry of values in order to segregate Lua or Mu types and
Kunshan Wang's avatar
Kunshan Wang committed
214
    garbage collection from the C or client world. However, Mu client context
Kunshan Wang's avatar
Kunshan Wang committed
215
    can also access the Mu memory (heap, stack or global) which is shared
Kunshan Wang's avatar
Kunshan Wang committed
216
    between multiple client context as well as multiple Mu Threads running
Kunshan Wang's avatar
Kunshan Wang committed
217
    concurrently in the same Mu instance. In Lua, ``lua_State`` instances are
218 219 220 221
    isolated.

..

Kunshan Wang's avatar
Kunshan Wang committed
222
    For JNI users: The client context is the counterpart of the context of a JNI
223
    invocation or an "attached" native thread, where there is a registry of Java
Kunshan Wang's avatar
Kunshan Wang committed
224 225 226 227 228
    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
229 230 231 232 233 234 235 236 237 238 239 240
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
241 242 243
MuVM Functions
==============

Kunshan Wang's avatar
Kunshan Wang committed
244 245
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
246

Kunshan Wang's avatar
Kunshan Wang committed
247
::
Kunshan Wang's avatar
Kunshan Wang committed
248

Kunshan Wang's avatar
Kunshan Wang committed
249
    MuCtx* (*new_context)(MuVM *mvm);
Kunshan Wang's avatar
Kunshan Wang committed
250

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

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

Kunshan Wang's avatar
Kunshan Wang committed
256
::
Kunshan Wang's avatar
Kunshan Wang committed
257

Kunshan Wang's avatar
Kunshan Wang committed
258 259
    MuID    (*id_of  )(MuVM *mvm, MuName name);
    MuName  (*name_of)(MuVM *mvm, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
260

Kunshan Wang's avatar
Kunshan Wang committed
261 262 263
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
264

Kunshan Wang's avatar
Kunshan Wang committed
265
::
266

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

269 270 271
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
272

Kunshan Wang's avatar
Kunshan Wang committed
273 274 275
``userdata`` will be passed to the handlers as the last element when they are
called.

276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
.. _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
311 312
MuCtx Functions
===============
Kunshan Wang's avatar
Kunshan Wang committed
313

Kunshan Wang's avatar
Kunshan Wang committed
314 315 316
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
317

Kunshan Wang's avatar
Kunshan Wang committed
318 319
Basic functions
---------------
Kunshan Wang's avatar
Kunshan Wang committed
320

Kunshan Wang's avatar
Kunshan Wang committed
321
::
Kunshan Wang's avatar
Kunshan Wang committed
322

Kunshan Wang's avatar
Kunshan Wang committed
323 324
    MuID        (*id_of  )(MuCtx *ctx, MuName name);
    MuName      (*name_of)(MuCtx *ctx, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
325

Kunshan Wang's avatar
Kunshan Wang committed
326 327 328
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
329

Kunshan Wang's avatar
Kunshan Wang committed
330
::
Kunshan Wang's avatar
Kunshan Wang committed
331

Kunshan Wang's avatar
Kunshan Wang committed
332
    void        (*close_context)(MuCtx *ctx);
Kunshan Wang's avatar
Kunshan Wang committed
333

Kunshan Wang's avatar
Kunshan Wang committed
334 335 336 337 338 339
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
340

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

Kunshan Wang's avatar
Kunshan Wang committed
344 345
Bundle and HAIL loading
-----------------------
Kunshan Wang's avatar
Kunshan Wang committed
346

Kunshan Wang's avatar
Kunshan Wang committed
347
::
Kunshan Wang's avatar
Kunshan Wang committed
348

Kunshan Wang's avatar
Kunshan Wang committed
349 350 351 352
    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
353

Kunshan Wang's avatar
Kunshan Wang committed
354 355
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
356
``buf``, and ``sz`` is the length of the content in bytes.
Kunshan Wang's avatar
Kunshan Wang committed
357

358 359 360 361 362
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
363 364
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
365

Kunshan Wang's avatar
Kunshan Wang committed
366
..
Kunshan Wang's avatar
Kunshan Wang committed
367

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

Kunshan Wang's avatar
Kunshan Wang committed
371 372 373 374
    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
375

Kunshan Wang's avatar
Kunshan Wang committed
376 377
Converting values to/from handles
---------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
378

Kunshan Wang's avatar
Kunshan Wang committed
379
::
380

Kunshan Wang's avatar
Kunshan Wang committed
381 382 383 384 385 386 387 388 389 390 391 392 393 394
    // 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);
395

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

Kunshan Wang's avatar
Kunshan Wang committed
398
    typedef void *MuCPtr;
Kunshan Wang's avatar
Kunshan Wang committed
399 400
    typedef void _MuCFP_Func();
    typedef _MuCFP_Func* MuCFP;     // it is void(*)()
Kunshan Wang's avatar
Kunshan Wang committed
401

Kunshan Wang's avatar
Kunshan Wang committed
402 403 404
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
405

Kunshan Wang's avatar
Kunshan Wang committed
406 407 408 409
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
410

Kunshan Wang's avatar
Kunshan Wang committed
411 412 413 414
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
415

Kunshan Wang's avatar
Kunshan Wang committed
416
Other functions are:
417

Kunshan Wang's avatar
Kunshan Wang committed
418
* ``handle_from_float``:    Convert a C ``float`` value to a Mu ``float`` value.
419 420 421

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

Kunshan Wang's avatar
Kunshan Wang committed
423 424
* ``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``.
425

Kunshan Wang's avatar
Kunshan Wang committed
426 427 428
* ``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``.
429

430 431
..

Kunshan Wang's avatar
Kunshan Wang committed
432 433 434 435
    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.
436

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

Kunshan Wang's avatar
Kunshan Wang committed
440
::
441

Kunshan Wang's avatar
Kunshan Wang committed
442 443 444 445 446 447 448 449 450 451 452 453
    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);
454

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

Kunshan Wang's avatar
Kunshan Wang committed
457 458 459 460 461
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.
462

Kunshan Wang's avatar
Kunshan Wang committed
463
Other functions are:
Kunshan Wang's avatar
Kunshan Wang committed
464

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

Kunshan Wang's avatar
Kunshan Wang committed
467 468 469
* ``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.
470

Kunshan Wang's avatar
Kunshan Wang committed
471 472
* ``handle_to_fp``: Convert a Mu ``ufuncptr<sig>`` value to a C ``void(*)()``
  value.
473 474 475

..

Kunshan Wang's avatar
Kunshan Wang committed
476 477 478
    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.
479

Kunshan Wang's avatar
Kunshan Wang committed
480 481
    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.
482

483 484
.. _handle-from-const:

Kunshan Wang's avatar
Kunshan Wang committed
485 486
Create handles from Mu global variables
---------------------------------------
487

Kunshan Wang's avatar
Kunshan Wang committed
488
::
489

Kunshan Wang's avatar
Kunshan Wang committed
490 491 492 493
    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);
494

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

Kunshan Wang's avatar
Kunshan Wang committed
498 499 500 501
* ``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.
502

503
..
504

Kunshan Wang's avatar
Kunshan Wang committed
505 506 507
    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.
508

Kunshan Wang's avatar
Kunshan Wang committed
509 510 511 512 513
    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.
514

Kunshan Wang's avatar
Kunshan Wang committed
515 516
Deleting values held by the context
-----------------------------------
517

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

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

Kunshan Wang's avatar
Kunshan Wang committed
522 523 524
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.
525

526 527 528 529 530 531
..

    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
532 533
Reference type comparison
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
534

Kunshan Wang's avatar
Kunshan Wang committed
535
::
Kunshan Wang's avatar
Kunshan Wang committed
536

Kunshan Wang's avatar
Kunshan Wang committed
537 538 539 540
    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
541

Kunshan Wang's avatar
Kunshan Wang committed
542 543 544
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
545

Kunshan Wang's avatar
Kunshan Wang committed
546 547 548
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
549

Kunshan Wang's avatar
Kunshan Wang committed
550
The return value is 1 for true and 0 for false.
Kunshan Wang's avatar
Kunshan Wang committed
551 552 553

..

Kunshan Wang's avatar
Kunshan Wang committed
554 555
    For Lua users: ``ref_eq`` is equivalent to the ``lua_rawequal`` function for
    reference types.
556

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

Kunshan Wang's avatar
Kunshan Wang committed
559 560
Aggregate type operations
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
561

Kunshan Wang's avatar
Kunshan Wang committed
562
::
Kunshan Wang's avatar
Kunshan Wang committed
563

Kunshan Wang's avatar
Kunshan Wang committed
564 565
    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
566 567
    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
568

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

Kunshan Wang's avatar
Kunshan Wang committed
571 572
* ``extract_value`` returns the value of a field at ``index`` in a struct value
  ``str``.
Kunshan Wang's avatar
Kunshan Wang committed
573

Kunshan Wang's avatar
Kunshan Wang committed
574 575 576 577 578
* ``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
579

Kunshan Wang's avatar
Kunshan Wang committed
580 581
* ``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
582

Kunshan Wang's avatar
Kunshan Wang committed
583 584 585
``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
586 587 588

..

Kunshan Wang's avatar
Kunshan Wang committed
589 590 591 592 593
    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
594

Kunshan Wang's avatar
Kunshan Wang committed
595 596 597 598 599 600 601
    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
602

Kunshan Wang's avatar
Kunshan Wang committed
603 604
Heap memory allocation
======================
Kunshan Wang's avatar
Kunshan Wang committed
605

Kunshan Wang's avatar
Kunshan Wang committed
606
::
Kunshan Wang's avatar
Kunshan Wang committed
607

Kunshan Wang's avatar
Kunshan Wang committed
608 609
    MuRefValue  (*new_fixed )(MuCtx *ctx, MuID mu_type);
    MuRefValue  (*new_hybrid)(MuCtx *ctx, MuID mu_type, MuIntValue length);
610
    
Kunshan Wang's avatar
Kunshan Wang committed
611 612
``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
613

Kunshan Wang's avatar
Kunshan Wang committed
614 615
``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
616

Kunshan Wang's avatar
Kunshan Wang committed
617 618 619
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
620 621 622

..

Kunshan Wang's avatar
Kunshan Wang committed
623 624 625 626 627
    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
628

Kunshan Wang's avatar
Kunshan Wang committed
629 630
    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
631

Kunshan Wang's avatar
Kunshan Wang committed
632 633
Cast between general reference types
------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
634

Kunshan Wang's avatar
Kunshan Wang committed
635
::
Kunshan Wang's avatar
Kunshan Wang committed
636

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

Kunshan Wang's avatar
Kunshan Wang committed
639 640 641
``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
642

Kunshan Wang's avatar
Kunshan Wang committed
643 644
Memory addressing
-----------------
Kunshan Wang's avatar
Kunshan Wang committed
645

Kunshan Wang's avatar
Kunshan Wang committed
646
::
Kunshan Wang's avatar
Kunshan Wang committed
647

Kunshan Wang's avatar
Kunshan Wang committed
648 649 650 651 652
    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
653

Kunshan Wang's avatar
Kunshan Wang committed
654 655
* ``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
656

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

Kunshan Wang's avatar
Kunshan Wang committed
660 661
* ``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
662

663 664
* ``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
665
  `Mu and the Memory <memory.rst>`__). It returns the iref of ``opnd`` moved by
666
  ``offset`` (forward if positive, backward if negative).
Kunshan Wang's avatar
Kunshan Wang committed
667

Kunshan Wang's avatar
Kunshan Wang committed
668 669
* ``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
670

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

Kunshan Wang's avatar
Kunshan Wang committed
673 674
Memory accessing
----------------
Kunshan Wang's avatar
Kunshan Wang committed
675

Kunshan Wang's avatar
Kunshan Wang committed
676
::
Kunshan Wang's avatar
Kunshan Wang committed
677

Kunshan Wang's avatar
Kunshan Wang committed
678 679 680
    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
681 682 683
                        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
684 685
                        MuIRefValue loc, MuValue opnd);
    void        (*fence    )(MuCtx *ctx, MuMemOrd ord);
Kunshan Wang's avatar
Kunshan Wang committed
686

Kunshan Wang's avatar
Kunshan Wang committed
687
where::
Kunshan Wang's avatar
Kunshan Wang committed
688

Kunshan Wang's avatar
Kunshan Wang committed
689
    typedef uint32_t MuFlag;
Kunshan Wang's avatar
Kunshan Wang committed
690

Kunshan Wang's avatar
Kunshan Wang committed
691 692 693 694 695 696 697 698 699
    // 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
700

Kunshan Wang's avatar
Kunshan Wang committed
701
    // Operations for the atomicrmw API function
Kunshan Wang's avatar
Kunshan Wang committed
702 703 704 705 706 707 708 709 710 711 712 713
    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
714

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

Kunshan Wang's avatar
Kunshan Wang committed
717 718
* ``store`` performs a *store* operation with arguments (``ord``, *T*, ``loc``,
  ``newval``).
Kunshan Wang's avatar
Kunshan Wang committed
719

Kunshan Wang's avatar
Kunshan Wang committed
720
* ``cmpxchg`` performs a *compare exchange* operation with arguments (``weak``,
721 722 723
  ``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
724

Kunshan Wang's avatar
Kunshan Wang committed
725 726
* ``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
727

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

Kunshan Wang's avatar
Kunshan Wang committed
730 731 732 733
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
734

Kunshan Wang's avatar
Kunshan Wang committed
735 736 737 738 739
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
740 741 742

..

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

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

Kunshan Wang's avatar
Kunshan Wang committed
749 750
Stack and thread operations
===========================
Kunshan Wang's avatar
Kunshan Wang committed
751

752 753
.. _new-stack:

Kunshan Wang's avatar
Kunshan Wang committed
754
::
Kunshan Wang's avatar
Kunshan Wang committed
755

Kunshan Wang's avatar
Kunshan Wang committed
756
    // Thread and stack creation and stack destruction
757
    MuStackRefValue     (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
Kunshan Wang's avatar
Kunshan Wang committed
758 759
    MuThreadRefValue    (*new_thread_nor)(MuCtx *ctx, MuStackRefValue stack,
                            MuRefValue threadlocal,
760
                            MuValue *vals, MuArraySize nvals);
Kunshan Wang's avatar
Kunshan Wang committed
761
    MuThreadRefValue    (*new_thread_exc)(MuCtx *ctx, MuStackRefValue stack,
Kunshan Wang's avatar
Kunshan Wang committed
762 763
                            MuRefValue threadlocal,
                            MuRefValue exc);
Kunshan Wang's avatar
Kunshan Wang committed
764
    void                (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
Kunshan Wang's avatar
Kunshan Wang committed
765

Kunshan Wang's avatar
Kunshan Wang committed
766
    // Thread-local object reference
Kunshan Wang's avatar
Kunshan Wang committed
767 768 769 770
    void        (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
                    MuRefValue threadlocal);
    MuRefValue  (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);

Kunshan Wang's avatar
Kunshan Wang committed
771
``new_stack`` creates a new Mu stack with ``func`` as the bottom function.
772 773 774
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
775

Kunshan Wang's avatar
Kunshan Wang committed
776 777 778
``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*.
779

Kunshan Wang's avatar
Kunshan Wang committed
780 781 782
- ``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.
783

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

Kunshan Wang's avatar
Kunshan Wang committed
786 787 788 789
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.

790 791
``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
792
native frames, the behaviour is implementation-defined.
Kunshan Wang's avatar
Kunshan Wang committed
793

Kunshan Wang's avatar
Kunshan Wang committed
794 795 796 797 798
    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``.
799

Kunshan Wang's avatar
Kunshan Wang committed
800
    For JVM users: The JVM does not distinguish stacks and threads. The closest
Kunshan Wang's avatar
Kunshan Wang committed
801 802 803
    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
804

Kunshan Wang's avatar
Kunshan Wang committed
805 806 807 808 809 810 811 812 813
``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
814 815
Stack introspection
-------------------
Kunshan Wang's avatar
Kunshan Wang committed
816

Kunshan Wang's avatar
Kunshan Wang committed
817
::
Kunshan Wang's avatar
Kunshan Wang committed
818

819 820 821 822
    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
823

824 825
* ``new_cursor`` allocates a frame cursor, referring to the top frame of
  ``stack``. Returns the frame cursor reference.
826

827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
* ``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
842
These functions operate on the frame referred by ``cursor``. 
843 844 845 846 847 848 849 850 851

* ``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
852

Kunshan Wang's avatar
Kunshan Wang committed
853
* ``dump_keepalives`` dumps the values of the keep-alive variables of the
854 855 856
  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
857 858
  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
859 860 861

..

Kunshan Wang's avatar
Kunshan Wang committed
862 863 864
    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.
865

Kunshan Wang's avatar
Kunshan Wang committed
866 867
..

Kunshan Wang's avatar
Kunshan Wang committed
868 869
    For Lua users: The debug interface provides many similar introspection
    functions.
Kunshan Wang's avatar
Kunshan Wang committed
870

Kunshan Wang's avatar
Kunshan Wang committed
871 872 873 874 875 876
    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
877

Kunshan Wang's avatar
Kunshan Wang committed
878 879
On-stack replacement
--------------------
Kunshan Wang's avatar
Kunshan Wang committed
880

Kunshan Wang's avatar
Kunshan Wang committed
881
::
Kunshan Wang's avatar
Kunshan Wang committed
882

883 884
    void        (*pop_frames_to)(MuCtx *ctx, MuFCRefValue cursor);
    void        (*push_frame   )(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func);
885

886
* ``pop_frames_to`` pops all frames above ``cursor``.
887

888 889
* ``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
890 891 892

..

893 894 895
    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
896 897


Kunshan Wang's avatar
Kunshan Wang committed
898 899
Tagged reference operations
---------------------------
Kunshan Wang's avatar
Kunshan Wang committed
900

Kunshan Wang's avatar
Kunshan Wang committed
901
::
Kunshan Wang's avatar
Kunshan Wang committed
902

Kunshan Wang's avatar
Kunshan Wang committed
903 904 905
    int             (*tr64_is_fp   )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_int  )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_ref  )(MuCtx *ctx, MuTagRef64Value value);
906 907 908 909 910 911 912 913 914

- ``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
915 916 917 918
    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);
919 920 921

- ``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
922 923
- ``tr64_to_ref`` returns the reference held by ``value``, may be a handle to
  the ``NULL`` value.
924 925 926 927 928 929 930 931
- ``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
932 933 934 935
    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);

936 937 938
- ``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
939
  the integer tag ``tag``. ``ref`` may be a handle to the ``NULL`` value.
Kunshan Wang's avatar
Kunshan Wang committed
940

941
Return the created ``tagref64`` value.
Kunshan Wang's avatar
Kunshan Wang committed
942 943 944

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

Kunshan Wang's avatar
Kunshan Wang committed
946
::
Kunshan Wang's avatar
Kunshan Wang committed
947

Kunshan Wang's avatar
Kunshan Wang committed
948 949 950 951
    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
952

Kunshan Wang's avatar
Kunshan Wang committed
953 954
* ``enable_watchpoint`` enables all watchpoints of ID ``wpid``.
* ``disable_watchpoint`` disables all watchpoints of ID ``wpid``.
Kunshan Wang's avatar
Kunshan Wang committed
955

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

Kunshan Wang's avatar
Kunshan Wang committed
958 959
Object pinning
--------------
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
    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
965

Kunshan Wang's avatar
Kunshan Wang committed
966 967 968
* ``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
969

Kunshan Wang's avatar
Kunshan Wang committed
970 971 972
* ``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
973

Kunshan Wang's avatar
Kunshan Wang committed
974 975 976
``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
977

Kunshan Wang's avatar
Kunshan Wang committed
978
..
Kunshan Wang's avatar
Kunshan Wang committed
979

Kunshan Wang's avatar
Kunshan Wang committed
980 981
    For Lua users: Lua userdata are always available as pointers. This assumes
    userdata are always pinned.
Kunshan Wang's avatar
Kunshan Wang committed
982

Kunshan Wang's avatar
Kunshan Wang committed
983 984 985 986
    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
987

Kunshan Wang's avatar
Kunshan Wang committed
988 989
Exposing Mu functions for native callback
-----------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
990

Kunshan Wang's avatar
Kunshan Wang committed
991
::
Kunshan Wang's avatar
Kunshan Wang committed
992

Kunshan Wang's avatar
Kunshan Wang committed
993 994
    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
995

Kunshan Wang's avatar
Kunshan Wang committed
996
where::
Kunshan Wang's avatar
Kunshan Wang committed
997

Kunshan Wang's avatar
Kunshan Wang committed
998 999
    typedef MuFlag MuCallConv;
    #define MU_CC_DEFAULT   ((MuCallConv)0x00)
Kunshan Wang's avatar
Kunshan Wang committed
1000

Kunshan Wang's avatar
Kunshan Wang committed
1001 1002 1003
* ``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
1004

Kunshan Wang's avatar
Kunshan Wang committed
1005 1006 1007
* ``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
1008

1009
See the `Native Interface <native-interface.rst>`__ chapter for details of expose
Kunshan Wang's avatar
Kunshan Wang committed
1010 1011
and unexpose. See the platform-specific native interface for the return value
type.
Kunshan Wang's avatar
Kunshan Wang committed
1012

Kunshan Wang's avatar
Kunshan Wang committed
1013
Implementations may define other calling conventions in addition to
Kunshan Wang's avatar
Kunshan Wang committed
1014
``MU_CC_DEFAULT``.
Kunshan Wang's avatar
Kunshan Wang committed
1015

1016 1017
Trap Handling
=============
Kunshan Wang's avatar
Kunshan Wang committed
1018

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

1022 1023
It is unspecified on which stack the trap handler is run.

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

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

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

Kunshan Wang's avatar
Kunshan Wang committed
1033
The signature of trap handlers is::
1034

Kunshan Wang's avatar
Kunshan Wang committed
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
    // 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
1051
            MuCPtr userdata);
1052

Kunshan Wang's avatar
Kunshan Wang committed
1053
where::
1054

Kunshan Wang's avatar
Kunshan Wang committed
1055
    typedef MuFlag MuTrapHandlerResult;
1056

Kunshan Wang's avatar
Kunshan Wang committed
1057 1058 1059
    #define MU_THREAD_EXIT          ((MuTrapHandlerResult)0x00)
    #define MU_REBIND_PASS_VALUES   ((MuTrapHandlerResult)0x01)
    #define MU_REBIND_THROW_EXC     ((MuTrapHandlerResult)0x02)
1060

Kunshan Wang's avatar
Kunshan Wang committed
1061 1062
    typedef void _MuValuesFreer_Func(MuValue *values, MuCPtr freerdata);
    typedef _MuValuesFreer_Func* MuValuesFreer;
1063

Kunshan Wang's avatar
Kunshan Wang committed
1064 1065 1066
``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
1067
``thread`` and ``stack`` are held by ``ctx``. ``wpid`` is the watch point ID if
Kunshan Wang's avatar
Kunshan Wang committed
1068 1069
it is caused by a ``WATCHPOINT`` instruction, or 0 if by ``TRAP``. ``userdata``
is the pointer provided when registering the handler.
1070

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

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

Kunshan Wang's avatar
Kunshan Wang committed
1076
* ``MU_THREAD_EXIT``: The thread ``thread`` terminates.
1077

Kunshan Wang's avatar
Kunshan Wang committed
1078
* ``Mu_REBIND_PASS_VALUES``: The thread ``thread`` will be rebound to a stack
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
  ``*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
1092 1093
* ``Mu_REBIND_THROW_EXC``: The thread ``thread`` will be rebound to a stack
  ``*new_stack``. It throws exception ``*exception`` to the stack.
1094

1095 1096
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``.
1097

Kunshan Wang's avatar
Kunshan Wang committed
1098 1099 1100
Building Mu IR Bundles
======================

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

Kunshan Wang's avatar
Kunshan Wang committed
1103 1104 1105
Signal Handling
===============

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

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