GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

api.rst 49.1 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>`__

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.
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.

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.
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
38 39 40
implementation-specific. When boot images are used to initialise the micro VM,
the micro VM will contain the contents of the boot image, but may still contain
implementation-specific extra entities.
41

Kunshan Wang's avatar
Kunshan Wang committed
42 43
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.
44

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

Mu IDs and names are represented as::

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

    // Identifiers and names of Mu
Kunshan Wang's avatar
Kunshan Wang committed
54
    typedef uint32_t MuID;
55 56 57
    typedef MuCString MuName;

``MuCString`` is the 0-terminated C string type.
Kunshan Wang's avatar
Kunshan Wang committed
58 59 60 61 62 63

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
64 65 66 67 68 69
        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);
Kunshan Wang's avatar
Kunshan Wang committed
70 71
    };

72 73
.. _client-context:

Kunshan Wang's avatar
Kunshan Wang committed
74 75 76 77 78 79 80 81 82 83
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
84 85 86 87 88 89 90
        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
91 92
        ...
    };
Kunshan Wang's avatar
Kunshan Wang committed
93 94
    
The full list of member function pointers is listed in the header `<muapi.h>`__.
Kunshan Wang's avatar
Kunshan Wang committed
95 96 97 98

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
99

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

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

Kunshan Wang's avatar
Kunshan Wang committed
106 107 108 109 110 111
    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).
112

Kunshan Wang's avatar
Kunshan Wang committed
113 114 115 116 117 118 119 120
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
121 122
    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
123 124 125 126

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
127 128 129 130 131
    // Top value type.
    typedef void *MuValue;                // Any Mu value

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

    // 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
152
    typedef MuGenRefValue MuIBRefValue;         // irbuilderref
Kunshan Wang's avatar
Kunshan Wang committed
153 154

Each handle can only hold a Mu value of the type shown in the comments above.
Kunshan Wang's avatar
Kunshan Wang committed
155 156 157 158
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
159
Handles have reference semantics: a handle refers to a value the client context
Kunshan Wang's avatar
Kunshan Wang committed
160
holds.  Handles can be copied as if they are pointers in C, and the resulting
Kunshan Wang's avatar
Kunshan Wang committed
161
handles refer to the same value held by a context.
Kunshan Wang's avatar
Kunshan Wang committed
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
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
178 179
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
180 181 182 183
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
184 185 186 187 188

..

    NOTE: The decision of using opaque handles serves two purposes. Both
    purposes are inspired by the Lua C API and JNI.
189
    
Kunshan Wang's avatar
Kunshan Wang committed
190 191 192 193 194 195
    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.
196 197

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

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

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

..

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

..

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

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

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

Kunshan Wang's avatar
Kunshan Wang committed
251
    MuCtx* (*new_context)(MuVM *mvm);
252

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

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

Kunshan Wang's avatar
Kunshan Wang committed
258
::
259

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

Kunshan Wang's avatar
Kunshan Wang committed
263 264 265
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.
266

Kunshan Wang's avatar
Kunshan Wang committed
267
::
268

269
    void    (*set_trap_handler      )(MuVM *mvm, MuTrapHandler trap_handler, MuCPtr userdata);
270

271 272 273
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.
274

275 276 277
``userdata`` will be passed to the handlers as the last element when they are
called.

Kunshan Wang's avatar
Kunshan Wang committed
278 279
MuCtx Functions
===============
280

Kunshan Wang's avatar
Kunshan Wang committed
281 282 283
In the following functions, the first argument ``ctx`` must be the same
``MuCtx*`` pointer to the ``MuCtx`` structure that contains the function
pointer.
284

Kunshan Wang's avatar
Kunshan Wang committed
285 286
Basic functions
---------------
287

Kunshan Wang's avatar
Kunshan Wang committed
288
::
289

Kunshan Wang's avatar
Kunshan Wang committed
290 291
    MuID        (*id_of  )(MuCtx *ctx, MuName name);
    MuName      (*name_of)(MuCtx *ctx, MuID id);
292

Kunshan Wang's avatar
Kunshan Wang committed
293 294 295
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.
296

Kunshan Wang's avatar
Kunshan Wang committed
297
::
298

Kunshan Wang's avatar
Kunshan Wang committed
299
    void        (*close_context)(MuCtx *ctx);
300

Kunshan Wang's avatar
Kunshan Wang committed
301 302 303 304 305 306
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.
307

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

Kunshan Wang's avatar
Kunshan Wang committed
311 312
Bundle and HAIL loading
-----------------------
313

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

Kunshan Wang's avatar
Kunshan Wang committed
316 317 318 319
    typedef uintptr_t MuArraySize;

    void        (*load_bundle)(MuCtx *ctx, char *buf, MuArraySize sz);
    void        (*load_hail  )(MuCtx *ctx, char *buf, MuArraySize sz);
320

Kunshan Wang's avatar
Kunshan Wang committed
321 322
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
323
``buf``, and ``sz`` is the length of the content in bytes.
324

325 326 327 328 329
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
330 331
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.
332

Kunshan Wang's avatar
Kunshan Wang committed
333
..
334

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

Kunshan Wang's avatar
Kunshan Wang committed
338 339 340 341
    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.
342

Kunshan Wang's avatar
Kunshan Wang committed
343 344
Converting values to/from handles
---------------------------------
345

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

Kunshan Wang's avatar
Kunshan Wang committed
348 349 350 351 352 353 354 355 356 357 358 359 360 361
    // 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);
362

363
where ``MuCPtr`` and ``MuCFP`` are convenient definitions for C types::
364

Kunshan Wang's avatar
Kunshan Wang committed
365
    typedef void *MuCPtr;
Kunshan Wang's avatar
Kunshan Wang committed
366 367
    typedef void _MuCFP_Func();
    typedef _MuCFP_Func* MuCFP;     // it is void(*)()
368

Kunshan Wang's avatar
Kunshan Wang committed
369 370 371
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.
372

Kunshan Wang's avatar
Kunshan Wang committed
373 374 375 376
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).
377

Kunshan Wang's avatar
Kunshan Wang committed
378 379 380 381
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.
382

Kunshan Wang's avatar
Kunshan Wang committed
383
Other functions are:
384

Kunshan Wang's avatar
Kunshan Wang committed
385
* ``handle_from_float``:    Convert a C ``float`` value to a Mu ``float`` value.
386 387 388

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

Kunshan Wang's avatar
Kunshan Wang committed
390 391
* ``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``.
392

Kunshan Wang's avatar
Kunshan Wang committed
393 394 395
* ``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``.
396

397 398
..

Kunshan Wang's avatar
Kunshan Wang committed
399 400 401 402
    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.
403

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

Kunshan Wang's avatar
Kunshan Wang committed
407
::
408

Kunshan Wang's avatar
Kunshan Wang committed
409 410 411 412 413 414 415 416 417 418 419 420
    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);
421

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

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

Kunshan Wang's avatar
Kunshan Wang committed
430
Other functions are:
431

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

Kunshan Wang's avatar
Kunshan Wang committed
434 435 436
* ``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.
437

Kunshan Wang's avatar
Kunshan Wang committed
438 439
* ``handle_to_fp``: Convert a Mu ``ufuncptr<sig>`` value to a C ``void(*)()``
  value.
440 441 442

..

Kunshan Wang's avatar
Kunshan Wang committed
443 444 445
    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.
446

Kunshan Wang's avatar
Kunshan Wang committed
447 448
    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.
449

450 451
.. _handle-from-const:

Kunshan Wang's avatar
Kunshan Wang committed
452 453
Create handles from Mu global variables
---------------------------------------
454

Kunshan Wang's avatar
Kunshan Wang committed
455
::
456

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

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

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

470
..
471

Kunshan Wang's avatar
Kunshan Wang committed
472 473 474
    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.
475

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

Kunshan Wang's avatar
Kunshan Wang committed
482 483
Deleting values held by the context
-----------------------------------
484

Kunshan Wang's avatar
Kunshan Wang committed
485
::
486

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

Kunshan Wang's avatar
Kunshan Wang committed
489 490 491
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.
492

493 494 495 496 497 498
..

    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
499 500
Reference type comparison
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
501

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

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

509 510 511
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
512

513 514 515
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
516

517
The return value is 1 for true and 0 for false.
Kunshan Wang's avatar
Kunshan Wang committed
518 519 520

..

521 522
    For Lua users: ``ref_eq`` is equivalent to the ``lua_rawequal`` function for
    reference types.
523

524
    For JNI users: ``ref_eq`` is equivalent to the ``IsSameObject`` function.
525

526 527
Aggregate type operations
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
528

529
::
Kunshan Wang's avatar
Kunshan Wang committed
530

531 532
    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
533 534
    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
535

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

538 539
* ``extract_value`` returns the value of a field at ``index`` in a struct value
  ``str``.
Kunshan Wang's avatar
Kunshan Wang committed
540

541 542 543 544 545
* ``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
546

547 548
* ``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
549

550 551 552
``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
553 554 555

..

556 557 558 559 560
    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
561

562 563 564 565 566 567 568
    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
569

570 571
Heap memory allocation
======================
Kunshan Wang's avatar
Kunshan Wang committed
572

573
::
Kunshan Wang's avatar
Kunshan Wang committed
574

575 576
    MuRefValue  (*new_fixed )(MuCtx *ctx, MuID mu_type);
    MuRefValue  (*new_hybrid)(MuCtx *ctx, MuID mu_type, MuIntValue length);
577
    
578 579
``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
580

581 582
``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
583

584 585 586
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
587 588 589

..

590 591 592 593 594
    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
595

596 597
    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
598

599 600
Cast between general reference types
------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
601

602
::
Kunshan Wang's avatar
Kunshan Wang committed
603

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

606 607 608
``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
609

610 611
Memory addressing
-----------------
Kunshan Wang's avatar
Kunshan Wang committed
612

613
::
Kunshan Wang's avatar
Kunshan Wang committed
614

615 616 617 618 619
    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
620

621 622
* ``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
623

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

627 628
* ``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
629

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

635 636
* ``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
637

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

640 641
Memory accessing
----------------
Kunshan Wang's avatar
Kunshan Wang committed
642

643
::
Kunshan Wang's avatar
Kunshan Wang committed
644

645 646 647
    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
648 649 650
                        MuBool weak, MuIRefValue loc, MuValue expected, MuValue desired,
                        MuBool *is_succ);
    MuValue     (*atomicrmw)(MuCtx *ctx, MuMemOrd ord, MuAtomicRMWOptr op,
651 652
                        MuIRefValue loc, MuValue opnd);
    void        (*fence    )(MuCtx *ctx, MuMemOrd ord);
Kunshan Wang's avatar
Kunshan Wang committed
653

654
where::
Kunshan Wang's avatar
Kunshan Wang committed
655

Kunshan Wang's avatar
Kunshan Wang committed
656
    typedef uint32_t MuFlag;
Kunshan Wang's avatar
Kunshan Wang committed
657

Kunshan Wang's avatar
Kunshan Wang committed
658 659 660 661 662 663 664 665 666
    // 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
667

668
    // Operations for the atomicrmw API function
Kunshan Wang's avatar
Kunshan Wang committed
669 670 671 672 673 674 675 676 677 678 679 680
    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
681

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

684 685
* ``store`` performs a *store* operation with arguments (``ord``, *T*, ``loc``,
  ``newval``).
Kunshan Wang's avatar
Kunshan Wang committed
686

687
* ``cmpxchg`` performs a *compare exchange* operation with arguments (``weak``,
688 689 690
  ``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.
691

692 693
* ``atomicrmw`` performs an *atomic-x* operation with argument (``ord``, *T*,
  ``loc``, ``opnd``), where the *x* in *atomic-x* is ``op``.
694

695
* ``fence`` is a fence of memory order ``ord``.
696

697 698 699 700
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>``).
701

Kunshan Wang's avatar
Kunshan Wang committed
702 703 704 705 706
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.
707 708 709

..

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

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

716 717
Stack and thread operations
===========================
718

719 720
.. _new-stack:

721
::
722

Kunshan Wang's avatar
Kunshan Wang committed
723
    // Thread and stack creation and stack destruction
724
    MuStackRefValue     (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
Kunshan Wang's avatar
Kunshan Wang committed
725 726
    MuThreadRefValue    (*new_thread_nor)(MuCtx *ctx, MuStackRefValue stack,
                            MuRefValue threadlocal,
727
                            MuValue *vals, MuArraySize nvals);
Kunshan Wang's avatar
Kunshan Wang committed
728
    MuThreadRefValue    (*new_thread_exc)(MuCtx *ctx, MuStackRefValue stack,
Kunshan Wang's avatar
Kunshan Wang committed
729 730
                            MuRefValue threadlocal,
                            MuRefValue exc);
731
    void                (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
Kunshan Wang's avatar
Kunshan Wang committed
732

Kunshan Wang's avatar
Kunshan Wang committed
733
    // Thread-local object reference
Kunshan Wang's avatar
Kunshan Wang committed
734 735 736 737
    void        (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
                    MuRefValue threadlocal);
    MuRefValue  (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);

738
``new_stack`` creates a new Mu stack with ``func`` as the bottom function.
739 740 741
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``.
742

Kunshan Wang's avatar
Kunshan Wang committed
743 744 745
``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*.
746

Kunshan Wang's avatar
Kunshan Wang committed
747 748 749
- ``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.
750

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

Kunshan Wang's avatar
Kunshan Wang committed
753 754 755 756
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.

757 758
``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
759
native frames, the behaviour is implementation-defined.
760

Kunshan Wang's avatar
Kunshan Wang committed
761 762 763 764 765
    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``.
766

767
    For JVM users: The JVM does not distinguish stacks and threads. The closest
Kunshan Wang's avatar
Kunshan Wang committed
768 769 770
    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.
771

Kunshan Wang's avatar
Kunshan Wang committed
772 773 774 775 776 777 778 779 780
``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.

781 782
Stack introspection
-------------------
783

784
::
785

786 787 788 789
    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);
790

791 792
* ``new_cursor`` allocates a frame cursor, referring to the top frame of
  ``stack``. Returns the frame cursor reference.
793

794 795 796 797 798 799 800 801 802 803 804 805 806 807 808
* ``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
809
These functions operate on the frame referred by ``cursor``. 
810 811 812 813 814 815 816 817 818

* ``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.
819

820
* ``dump_keepalives`` dumps the values of the keep-alive variables of the
821 822 823
  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
824 825
  Values returned in this array may be handles to ``NULL`` values if the
  respective local variable is ``NULL``.
826 827 828

..

829 830 831
    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.
832

833 834
..

835 836
    For Lua users: The debug interface provides many similar introspection
    functions.
837

838 839 840 841 842 843
    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
844

845 846
On-stack replacement
--------------------
847

848
::
849

850 851
    void        (*pop_frames_to)(MuCtx *ctx, MuFCRefValue cursor);
    void        (*push_frame   )(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func);
852

853
* ``pop_frames_to`` pops all frames above ``cursor``.
854

855 856
* ``push_frame`` creates a new frame on the top of ``stack`` for the current
  version of function ``func``.
857 858 859

..

860 861 862
    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.
863 864


865 866
Tagged reference operations
---------------------------
867

868
::
869

870 871 872
    int             (*tr64_is_fp   )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_int  )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_ref  )(MuCtx *ctx, MuTagRef64Value value);
873 874 875 876 877 878 879 880 881

- ``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.

::

882 883 884 885
    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);
886 887 888

- ``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
889 890
- ``tr64_to_ref`` returns the reference held by ``value``, may be a handle to
  the ``NULL`` value.
891 892 893 894 895 896 897 898
- ``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.

::

899 900 901 902
    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);

903 904 905
- ``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
906
  the integer tag ``tag``. ``ref`` may be a handle to the ``NULL`` value.
907

908
Return the created ``tagref64`` value.
909 910 911

Watchpoint operations
---------------------
912

913
::
914

Kunshan Wang's avatar
Kunshan Wang committed
915 916 917 918
    typedef uint32_t MuWPID;

    void        (*enable_watchpoint )(MuCtx *ctx, MuWPID wpid);
    void        (*disable_watchpoint)(MuCtx *ctx, MuWPID wpid);
919

920 921
* ``enable_watchpoint`` enables all watchpoints of ID ``wpid``.
* ``disable_watchpoint`` disables all watchpoints of ID ``wpid``.
922

923
Enabling or disabling any non-existing ``wpid`` has undefined behaviour.
924

925 926
.. _get-addr:

927 928
Object pinning
--------------
929

930
::
931

932 933 934
    MuUPtrValue (*pin     )(MuCtx *ctx, MuValue loc);      // loc is either MuRefValue or MuIRefValue
    void        (*unpin   )(MuCtx *ctx, MuValue loc);      // loc is either MuRefValue or MuIRefValue
    MuUPtrValue (*get_addr)(MuCtx *ctx, MuValue loc);      // loc is either MuRefValue or MuIRefValue
935

936 937 938
* ``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.
939

940 941 942
* ``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.
943

944 945 946 947
* ``get_addr`` gets the address of a memory location ``loc`` which must already
  be pinned with respect to the current thread. This include all global cells
  and other memory locations in the pinning set of the current thread.

948 949
``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
950
results of ``pin`` and ``get_addr`` are ``uptr<T>``.
951

952
..
953

954 955
    For Lua users: Lua userdata are always available as pointers. This assumes
    userdata are always pinned.
956

957 958 959 960
    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.
961

962 963
Exposing Mu functions for native callback
-----------------------------------------
964

965
::
966

967 968
    MuValue     (*expose  )(MuCtx *ctx, MuFuncRefValue func, MuCallConv call_conv, MuIntValue cookie);
    void        (*unexpose)(MuCtx *ctx, MuCallConv call_conv, MuValue value);
969

970
where::
971

Kunshan Wang's avatar
Kunshan Wang committed
972 973
    typedef MuFlag MuCallConv;
    #define MU_CC_DEFAULT   ((MuCallConv)0x00)
974

975 976 977
* ``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.
978

979 980 981
* ``unexpose`` invalidates an exposed value ``value`` created by the
  ``@uvm.native.expose`` instruction or the ``expose`` API function with calling
  convention ``call_conv``. 
982

983
See the `Native Interface <native-interface.rst>`__ chapter for details of expose
984 985
and unexpose. See the platform-specific native interface for the return value
type.
986

987
Implementations may define other calling conventions in addition to
Kunshan Wang's avatar
Kunshan Wang committed
988
``MU_CC_DEFAULT``.
Kunshan Wang's avatar
Kunshan Wang committed
989

990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
Building Mu IR Bundles
----------------------

The ``new_ir_builder`` method creates a ``MuIRBuilder`` instance so that the
client can programmatically build and load Mu IR bundles.  See `IR Builder
<irbuilder.rst>`__ for this part of the API.

Making Boot Image
-----------------

.. _make-boot-image:

::

    void    (*make_boot_image)(MuVM *mvm,
                MuID* whitelist, MuArraySize whitelist_sz,
                MuFuncRefValue primordial_func, MuStackRefValue primordial_stack,
                MuRefValue primordial_threadlocal,
                MuIRefValue *sym_fields, MuCString *sym_strings, MuArraySize nsyms,
                MuIRefValue *reloc_fields, MuCString *reloc_strings, MuArraySize nrelocs,
                MuCString output_file);

The ``make_boot_image`` function creates a boot image.

``whitelist`` is an array of IDs, and its length is ``whitelist_sz``. It is a
**white-list** of top-level definitions which will be built into the boot image,
and will appear to be already loaded into the micro VM when a micro VM instance
is created using the boot image.

When creating micro VM from a boot image, it may optionally create a
**primordial thread** (i.e. a thread whose state is preserved at
boot-image-building time). In this API, that thread is represented as a stack
plus a thread-local object reference. The client use either ``primordial_func``
or ``primordial_stack`` (but not both; the other must be NULL) to specify the
stack of the primordial thread, and use the ``primordial_threadlocal``
(NULL-able) as the initial thread-local object reference of the primordial
thread. If ``primordial_func`` is used, the primordial stack contains exactly
one frame that pauses at the beginning of that function; if ``primordial_stack``
is used, it is the primordial stack. The primordial stack must be in the
``READY<int<32> uptr<uptr<int<8>>>>`` state (the same as the ``main(int argc,
char** argv)`` signature in C). The resumption point will continue normally and
receive the ``argc`` and ``argv`` arguments from the command line. If neither
``primordial_func`` nor ``primordial_stack`` is specified, the boot image does
not contain any primordial threads. There is at most one primordial thread in
the boot image.

    NOTE: The primordial thread may be used as the entry point of a pure Mu IR
    program. Having only one primordial thread allows the implementation to
    re-use the initial thread created by the operating system.

    But if the entry point is not supposed to be any Mu IR program (such as any
    non-metacircular clients that only uses the micro VM as a JIT compiler), the
    client can create a boot image without any primordial threads. The boot
    image still accelerates the loading of the initial bundle, but does not
    start any threads for the client.

The boot image will also contain the **transitive closure** of the white-listed
top-level definitions. That includes all heap objects, functions, exposed
functions, constants and other global cells transitively reachable from any
white-listed global cells.

The contents of the global cells and reachable heap objects are preserved. It is
an error if any threads, stacks (other than the primordial stack), 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.

``sym_fields`` and ``sym_strings`` are two arrays, and the lengths of both are
``nsyms``. The two arrays, zipped, form a list of IRef-string pairs. The IRef
must refer to a field of a global cell in the boot image. The string is a symbol
(in the native linker's sense) which is placed at the field. The linker/loader
will be able to resolve the symbol to the address of the field of the global
cell. (NOTE: global cells are always pinned and have constant addresses after
loaded.)

``reloc_fields``, ``reloc_strings`` are also two arrays, and the length of both
are ``nrelocs``. These two arrays form a list of IRef-string pairs, too. The
IRef must refer to a field of a global cell or a heap object in the boot image.
The string is a symbol. All fields referred in ``reloc_fields`` must have
pointer types (``uptr`` or ``ufuncptr``). At load time, the address of the
corresponding symbol will be stored into the field by the loader.

    NOTE: The system's native loader may have more features than this API, such
    as adding numbers to a field rather than simply assigning them. This API is
    simple, but should be just enough to solve the linkage problem of Mu objects
    having untraced pointers to other Mu memory locations or native modules.

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``. 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.

1096 1097
Trap Handling
=============
Kunshan Wang's avatar
Kunshan Wang committed
1098

1099
A trap handler is called when a ``TRAP`` or ``WATCHPOINT`` instruction is
1100
executed. It is also implicitly called when executing an undefined function.
1101

1102 1103
It is unspecified on which stack the trap handler is run.

1104
Mu is allowed to call these handlers concurrently. Mu does not guarantee the
1105
order in which these handlers are called, but guarantees the happen-before
1106
relation between the trap and the handler. See `Memory Model <memory-model.rst>`__.
1107

1108
The Mu thread that triggers the trap is temporarily unbound from the stack.
1109

1110 1111
    NOTE: This unbinding is only conceptual. It is a valid implementation to use
    the same Mu thread to execute the trap handler.
1112

1113
The signature of trap handlers is::
1114

Kunshan Wang's avatar
Kunshan Wang committed
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
    // 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)
1131
            MuCPtr userdata);
1132

1133
where::
1134

Kunshan Wang's avatar
Kunshan Wang committed
1135
    typedef MuFlag MuTrapHandlerResult;
1136

Kunshan Wang's avatar
Kunshan Wang committed
1137 1138 1139
    #define MU_THREAD_EXIT          ((MuTrapHandlerResult)0x00)
    #define MU_REBIND_PASS_VALUES   ((MuTrapHandlerResult)0x01)
    #define MU_REBIND_THROW_EXC     ((MuTrapHandlerResult)0x02)
1140

Kunshan Wang's avatar
Kunshan Wang committed
1141 1142
    typedef void _MuValuesFreer_Func(MuValue *values, MuCPtr freerdata);
    typedef _MuValuesFreer_Func* MuValuesFreer;
1143

1144 1145 1146
``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
1147
``thread`` and ``stack`` are held by ``ctx``. ``wpid`` is the watch point ID if
1148 1149
it is caused by a ``WATCHPOINT`` instruction, or 0 if by ``TRAP``. ``userdata``
is the pointer provided when registering the handler.
1150

1151 1152
``ctx`` will be closed when the trap handler returns, so the client must not
close it manually.
1153

1154
Before returning, the trap handler should set ``*result``:
1155

1156
* ``MU_THREAD_EXIT``: The thread ``thread`` terminates.
1157

Kunshan Wang's avatar
Kunshan Wang committed
1158
* ``Mu_REBIND_PASS_VALUES``: The thread ``thread`` will be rebound to a stack
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171
  ``*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``.

1172 1173
* ``Mu_REBIND_THROW_EXC``: The thread ``thread`` will be rebound to a stack
  ``*new_stack``. It throws exception ``*exception`` to the stack.
1174

1175 1176
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``.
1177

Kunshan Wang's avatar
Kunshan Wang committed
1178

Kunshan Wang's avatar
Kunshan Wang committed
1179 1180 1181
Signal Handling
===============

1182
Signal handling is implementation-dependent. Mu may register signal handlers.
1183

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