api.rst 42 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 48 49 50 51 52 53 54 55
The Mu Micro VM and Client Contexts
===================================

Mu IDs and names are represented as::

    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
56 57 58 59 60 61
        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
62 63 64 65 66 67 68 69 70 71 72 73
    };

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

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
89

Kunshan Wang's avatar
Kunshan Wang committed
90 91
    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
92

Kunshan Wang's avatar
Kunshan Wang committed
93 94
    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
95

Kunshan Wang's avatar
Kunshan Wang committed
96 97 98 99 100 101
    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
102

Kunshan Wang's avatar
Kunshan Wang committed
103 104 105 106 107 108 109 110
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
111 112
    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
113 114 115 116

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
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    // Top value type.
    typedef void *MuValue;                // Any Mu value

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

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

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

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

Each handle can only hold a Mu value of the type shown in the comments above.
Kunshan Wang's avatar
Kunshan Wang committed
145 146 147 148
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
149
Handles have reference semantics: a handle refers to a value the client context
Kunshan Wang's avatar
Kunshan Wang committed
150
holds.  Handles can be copied as if they are pointers in C, and the resulting
Kunshan Wang's avatar
Kunshan Wang committed
151
handles refer to the same value held by a context.
Kunshan Wang's avatar
Kunshan Wang committed
152 153 154

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
155 156 157 158
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
159 160 161 162 163

..

    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
164
    
Kunshan Wang's avatar
Kunshan Wang committed
165 166 167 168 169 170
    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
171 172

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

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

Kunshan Wang's avatar
Kunshan Wang committed
181 182 183
    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
184
    (see the (unsafe) `Native Interface <native-interface.rst>`__ for a more
Kunshan Wang's avatar
Kunshan Wang committed
185
    efficient (and less safe) interface).
186 187 188

..

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

..

Kunshan Wang's avatar
Kunshan Wang committed
199
    For JNI users: The client context is the counterpart of the context of a JNI
200
    invocation or an "attached" native thread, where there is a registry of Java
Kunshan Wang's avatar
Kunshan Wang committed
201 202 203 204 205
    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
206 207 208 209 210 211 212 213 214 215 216 217
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
218 219 220
MuVM Functions
==============

Kunshan Wang's avatar
Kunshan Wang committed
221 222
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
223

Kunshan Wang's avatar
Kunshan Wang committed
224
::
Kunshan Wang's avatar
Kunshan Wang committed
225

Kunshan Wang's avatar
Kunshan Wang committed
226
    MuCtx* (*new_context)(MuVM *mvm);
Kunshan Wang's avatar
Kunshan Wang committed
227

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

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

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

Kunshan Wang's avatar
Kunshan Wang committed
235 236
    MuID    (*id_of  )(MuVM *mvm, MuName name);
    MuName  (*name_of)(MuVM *mvm, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
237

Kunshan Wang's avatar
Kunshan Wang committed
238 239 240
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
241

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

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

246 247 248
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
249

Kunshan Wang's avatar
Kunshan Wang committed
250 251 252
``userdata`` will be passed to the handlers as the last element when they are
called.

Kunshan Wang's avatar
Kunshan Wang committed
253 254
MuCtx Functions
===============
Kunshan Wang's avatar
Kunshan Wang committed
255

Kunshan Wang's avatar
Kunshan Wang committed
256 257 258
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
259

Kunshan Wang's avatar
Kunshan Wang committed
260 261
Basic functions
---------------
Kunshan Wang's avatar
Kunshan Wang committed
262

Kunshan Wang's avatar
Kunshan Wang committed
263
::
Kunshan Wang's avatar
Kunshan Wang committed
264

Kunshan Wang's avatar
Kunshan Wang committed
265 266
    MuID        (*id_of  )(MuCtx *ctx, MuName name);
    MuName      (*name_of)(MuCtx *ctx, MuID id);
Kunshan Wang's avatar
Kunshan Wang committed
267

Kunshan Wang's avatar
Kunshan Wang committed
268 269 270
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
271

Kunshan Wang's avatar
Kunshan Wang committed
272
::
Kunshan Wang's avatar
Kunshan Wang committed
273

Kunshan Wang's avatar
Kunshan Wang committed
274
    void        (*close_context)(MuCtx *ctx);
Kunshan Wang's avatar
Kunshan Wang committed
275

Kunshan Wang's avatar
Kunshan Wang committed
276 277 278 279 280 281
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
282

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

Kunshan Wang's avatar
Kunshan Wang committed
286 287
Bundle and HAIL loading
-----------------------
Kunshan Wang's avatar
Kunshan Wang committed
288

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

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

Kunshan Wang's avatar
Kunshan Wang committed
296 297
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
298
``buf``, and ``sz`` is the length of the content in bytes.
Kunshan Wang's avatar
Kunshan Wang committed
299

Kunshan Wang's avatar
Kunshan Wang committed
300 301
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
302

303 304 305 306 307 308 309
..

    TODO: These two functions should be made optional or lifted to the
    higher-level API which should be beyond this spec. The text-form bundle
    needs a parser, and the HAIL script is also not the most efficient way to
    load data into Mu at run time.

Kunshan Wang's avatar
Kunshan Wang committed
310
..
Kunshan Wang's avatar
Kunshan Wang committed
311

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

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

Kunshan Wang's avatar
Kunshan Wang committed
320 321
Converting values to/from handles
---------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
322

Kunshan Wang's avatar
Kunshan Wang committed
323
::
324

Kunshan Wang's avatar
Kunshan Wang committed
325 326 327 328 329 330 331 332 333 334 335 336 337 338
    // 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);
339

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

Kunshan Wang's avatar
Kunshan Wang committed
342
    typedef void *MuCPtr;
Kunshan Wang's avatar
Kunshan Wang committed
343 344
    typedef void _MuCFP_Func();
    typedef _MuCFP_Func* MuCFP;     // it is void(*)()
Kunshan Wang's avatar
Kunshan Wang committed
345

Kunshan Wang's avatar
Kunshan Wang committed
346 347 348
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
349

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

Kunshan Wang's avatar
Kunshan Wang committed
355 356 357 358
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
359

Kunshan Wang's avatar
Kunshan Wang committed
360
Other functions are:
361

Kunshan Wang's avatar
Kunshan Wang committed
362
* ``handle_from_float``:    Convert a C ``float`` value to a Mu ``float`` value.
363 364 365

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

Kunshan Wang's avatar
Kunshan Wang committed
367 368
* ``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``.
369

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

374 375
..

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

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

Kunshan Wang's avatar
Kunshan Wang committed
384
::
385

Kunshan Wang's avatar
Kunshan Wang committed
386 387 388 389 390 391 392 393 394 395 396 397
    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);
398

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

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

Kunshan Wang's avatar
Kunshan Wang committed
407
Other functions are:
Kunshan Wang's avatar
Kunshan Wang committed
408

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

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

Kunshan Wang's avatar
Kunshan Wang committed
415 416
* ``handle_to_fp``: Convert a Mu ``ufuncptr<sig>`` value to a C ``void(*)()``
  value.
417 418 419

..

Kunshan Wang's avatar
Kunshan Wang committed
420 421 422
    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.
423

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

Kunshan Wang's avatar
Kunshan Wang committed
427 428
Create handles from Mu global variables
---------------------------------------
429

Kunshan Wang's avatar
Kunshan Wang committed
430
::
431

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

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

Kunshan Wang's avatar
Kunshan Wang committed
440 441 442 443
* ``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.
444

445
..
446

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

Kunshan Wang's avatar
Kunshan Wang committed
451 452 453 454 455
    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.
456

Kunshan Wang's avatar
Kunshan Wang committed
457 458
Deleting values held by the context
-----------------------------------
459

Kunshan Wang's avatar
Kunshan Wang committed
460
::
461

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

Kunshan Wang's avatar
Kunshan Wang committed
464 465 466
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.
467

468 469 470 471 472 473
..

    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
474 475
Reference type comparison
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
476

Kunshan Wang's avatar
Kunshan Wang committed
477
::
Kunshan Wang's avatar
Kunshan Wang committed
478

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

Kunshan Wang's avatar
Kunshan Wang committed
484 485 486
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
487

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

Kunshan Wang's avatar
Kunshan Wang committed
492
The return value is 1 for true and 0 for false.
Kunshan Wang's avatar
Kunshan Wang committed
493 494 495

..

Kunshan Wang's avatar
Kunshan Wang committed
496 497
    For Lua users: ``ref_eq`` is equivalent to the ``lua_rawequal`` function for
    reference types.
498

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

Kunshan Wang's avatar
Kunshan Wang committed
501 502
Aggregate type operations
-------------------------
Kunshan Wang's avatar
Kunshan Wang committed
503

Kunshan Wang's avatar
Kunshan Wang committed
504
::
Kunshan Wang's avatar
Kunshan Wang committed
505

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

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

Kunshan Wang's avatar
Kunshan Wang committed
513 514
* ``extract_value`` returns the value of a field at ``index`` in a struct value
  ``str``.
Kunshan Wang's avatar
Kunshan Wang committed
515

Kunshan Wang's avatar
Kunshan Wang committed
516 517 518 519 520
* ``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
521

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

Kunshan Wang's avatar
Kunshan Wang committed
525 526 527
``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
528 529 530

..

Kunshan Wang's avatar
Kunshan Wang committed
531 532 533 534 535
    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
536

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

Kunshan Wang's avatar
Kunshan Wang committed
545 546
Heap memory allocation
======================
Kunshan Wang's avatar
Kunshan Wang committed
547

Kunshan Wang's avatar
Kunshan Wang committed
548
::
Kunshan Wang's avatar
Kunshan Wang committed
549

Kunshan Wang's avatar
Kunshan Wang committed
550 551
    MuRefValue  (*new_fixed )(MuCtx *ctx, MuID mu_type);
    MuRefValue  (*new_hybrid)(MuCtx *ctx, MuID mu_type, MuIntValue length);
552
    
Kunshan Wang's avatar
Kunshan Wang committed
553 554
``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
555

Kunshan Wang's avatar
Kunshan Wang committed
556 557
``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
558

Kunshan Wang's avatar
Kunshan Wang committed
559 560 561
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
562 563 564

..

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

Kunshan Wang's avatar
Kunshan Wang committed
571 572
    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
573

Kunshan Wang's avatar
Kunshan Wang committed
574 575
Cast between general reference types
------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
576

Kunshan Wang's avatar
Kunshan Wang committed
577
::
Kunshan Wang's avatar
Kunshan Wang committed
578

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

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

Kunshan Wang's avatar
Kunshan Wang committed
585 586
Memory addressing
-----------------
Kunshan Wang's avatar
Kunshan Wang committed
587

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

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

Kunshan Wang's avatar
Kunshan Wang committed
596 597
* ``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
598

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

Kunshan Wang's avatar
Kunshan Wang committed
602 603
* ``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
604

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

Kunshan Wang's avatar
Kunshan Wang committed
610 611
* ``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
612

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

Kunshan Wang's avatar
Kunshan Wang committed
615 616
Memory accessing
----------------
Kunshan Wang's avatar
Kunshan Wang committed
617

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

Kunshan Wang's avatar
Kunshan Wang committed
620 621 622
    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
623 624 625
                        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
626 627
                        MuIRefValue loc, MuValue opnd);
    void        (*fence    )(MuCtx *ctx, MuMemOrd ord);
Kunshan Wang's avatar
Kunshan Wang committed
628

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

Kunshan Wang's avatar
Kunshan Wang committed
631
    typedef uint32_t MuFlag;
Kunshan Wang's avatar
Kunshan Wang committed
632

Kunshan Wang's avatar
Kunshan Wang committed
633 634 635 636 637 638 639 640 641
    // 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
642

Kunshan Wang's avatar
Kunshan Wang committed
643
    // Operations for the atomicrmw API function
Kunshan Wang's avatar
Kunshan Wang committed
644 645 646 647 648 649 650 651 652 653 654 655
    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
656

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

Kunshan Wang's avatar
Kunshan Wang committed
659 660
* ``store`` performs a *store* operation with arguments (``ord``, *T*, ``loc``,
  ``newval``).
Kunshan Wang's avatar
Kunshan Wang committed
661

Kunshan Wang's avatar
Kunshan Wang committed
662
* ``cmpxchg`` performs a *compare exchange* operation with arguments (``weak``,
663 664 665
  ``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
666

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

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

Kunshan Wang's avatar
Kunshan Wang committed
672 673 674 675
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
676

Kunshan Wang's avatar
Kunshan Wang committed
677 678 679 680 681
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
682 683 684

..

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

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

Kunshan Wang's avatar
Kunshan Wang committed
691 692
Stack and thread operations
===========================
Kunshan Wang's avatar
Kunshan Wang committed
693

Kunshan Wang's avatar
Kunshan Wang committed
694
::
Kunshan Wang's avatar
Kunshan Wang committed
695

Kunshan Wang's avatar
Kunshan Wang committed
696
    // Thread and stack creation and stack destruction
697
    MuStackRefValue     (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
Kunshan Wang's avatar
Kunshan Wang committed
698 699 700 701
    MuThreadRefValue    (*new_thread_nor)(MuCtx *ctx, MuStackRefValue stack,
                            MuRefValue threadlocal,
                            MuValue *vals, MuBool nvals);
    MuThreadRefValue    (*new_thread_exc)(MuCtx *ctx, MuStackRefValue stack,
Kunshan Wang's avatar
Kunshan Wang committed
702 703
                            MuRefValue threadlocal,
                            MuRefValue exc);
Kunshan Wang's avatar
Kunshan Wang committed
704
    void                (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
Kunshan Wang's avatar
Kunshan Wang committed
705

Kunshan Wang's avatar
Kunshan Wang committed
706
    // Thread-local object reference
Kunshan Wang's avatar
Kunshan Wang committed
707 708 709 710
    void        (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
                    MuRefValue threadlocal);
    MuRefValue  (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);

Kunshan Wang's avatar
Kunshan Wang committed
711
``new_stack`` creates a new Mu stack with ``func`` as the bottom function.
712 713 714
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
715

Kunshan Wang's avatar
Kunshan Wang committed
716 717 718
``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*.
719

Kunshan Wang's avatar
Kunshan Wang committed
720 721 722
- ``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.
723

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

Kunshan Wang's avatar
Kunshan Wang committed
726 727 728 729
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.

730 731
``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
732
native frames, the behaviour is implementation-defined.
Kunshan Wang's avatar
Kunshan Wang committed
733

Kunshan Wang's avatar
Kunshan Wang committed
734 735 736 737 738
    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``.
739

Kunshan Wang's avatar
Kunshan Wang committed
740
    For JVM users: The JVM does not distinguish stacks and threads. The closest
Kunshan Wang's avatar
Kunshan Wang committed
741 742 743
    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
744

Kunshan Wang's avatar
Kunshan Wang committed
745 746 747 748 749 750 751 752 753
``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
754 755
Stack introspection
-------------------
Kunshan Wang's avatar
Kunshan Wang committed
756

Kunshan Wang's avatar
Kunshan Wang committed
757
::
Kunshan Wang's avatar
Kunshan Wang committed
758

759 760 761 762
    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
763

764 765
* ``new_cursor`` allocates a frame cursor, referring to the top frame of
  ``stack``. Returns the frame cursor reference.
766

767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
* ``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
782
These functions operate on the frame referred by ``cursor``. 
783 784 785 786 787 788 789 790 791

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

Kunshan Wang's avatar
Kunshan Wang committed
793
* ``dump_keepalives`` dumps the values of the keep-alive variables of the
794 795 796
  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
797 798
  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
799 800 801

..

Kunshan Wang's avatar
Kunshan Wang committed
802 803 804
    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.
805

Kunshan Wang's avatar
Kunshan Wang committed
806 807
..

Kunshan Wang's avatar
Kunshan Wang committed
808 809
    For Lua users: The debug interface provides many similar introspection
    functions.
Kunshan Wang's avatar
Kunshan Wang committed
810

Kunshan Wang's avatar
Kunshan Wang committed
811 812 813 814 815 816
    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
817

Kunshan Wang's avatar
Kunshan Wang committed
818 819
On-stack replacement
--------------------
Kunshan Wang's avatar
Kunshan Wang committed
820

Kunshan Wang's avatar
Kunshan Wang committed
821
::
Kunshan Wang's avatar
Kunshan Wang committed
822

823 824
    void        (*pop_frames_to)(MuCtx *ctx, MuFCRefValue cursor);
    void        (*push_frame   )(MuCtx *ctx, MuStackRefValue stack, MuFuncRefValue func);
825

826
* ``pop_frames_to`` pops all frames above ``cursor``.
827

828 829
* ``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
830 831 832

..

833 834 835
    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
836 837


Kunshan Wang's avatar
Kunshan Wang committed
838 839
Tagged reference operations
---------------------------
Kunshan Wang's avatar
Kunshan Wang committed
840

Kunshan Wang's avatar
Kunshan Wang committed
841
::
Kunshan Wang's avatar
Kunshan Wang committed
842

Kunshan Wang's avatar
Kunshan Wang committed
843 844 845
    int             (*tr64_is_fp   )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_int  )(MuCtx *ctx, MuTagRef64Value value);
    int             (*tr64_is_ref  )(MuCtx *ctx, MuTagRef64Value value);
846 847 848 849 850 851 852 853 854

- ``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
855 856 857 858
    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);
859 860 861

- ``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
862 863
- ``tr64_to_ref`` returns the reference held by ``value``, may be a handle to
  the ``NULL`` value.
864 865 866 867 868 869 870 871
- ``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
872 873 874 875
    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);

876 877 878
- ``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
879
  the integer tag ``tag``. ``ref`` may be a handle to the ``NULL`` value.
Kunshan Wang's avatar
Kunshan Wang committed
880

881
Return the created ``tagref64`` value.
Kunshan Wang's avatar
Kunshan Wang committed
882 883 884

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

Kunshan Wang's avatar
Kunshan Wang committed
886
::
Kunshan Wang's avatar
Kunshan Wang committed
887

Kunshan Wang's avatar
Kunshan Wang committed
888 889 890 891
    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
892

Kunshan Wang's avatar
Kunshan Wang committed
893 894
* ``enable_watchpoint`` enables all watchpoints of ID ``wpid``.
* ``disable_watchpoint`` disables all watchpoints of ID ``wpid``.
Kunshan Wang's avatar
Kunshan Wang committed
895

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

Kunshan Wang's avatar
Kunshan Wang committed
898 899
Object pinning
--------------
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
    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
905

Kunshan Wang's avatar
Kunshan Wang committed
906 907 908
* ``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
909

Kunshan Wang's avatar
Kunshan Wang committed
910 911 912
* ``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
913

Kunshan Wang's avatar
Kunshan Wang committed
914 915 916
``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
917

Kunshan Wang's avatar
Kunshan Wang committed
918
..
Kunshan Wang's avatar
Kunshan Wang committed
919

Kunshan Wang's avatar
Kunshan Wang committed
920 921
    For Lua users: Lua userdata are always available as pointers. This assumes
    userdata are always pinned.
Kunshan Wang's avatar
Kunshan Wang committed
922

Kunshan Wang's avatar
Kunshan Wang committed
923 924 925 926
    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
927

Kunshan Wang's avatar
Kunshan Wang committed
928 929
Exposing Mu functions for native callback
-----------------------------------------
Kunshan Wang's avatar
Kunshan Wang committed
930

Kunshan Wang's avatar
Kunshan Wang committed
931
::
Kunshan Wang's avatar
Kunshan Wang committed
932

Kunshan Wang's avatar
Kunshan Wang committed
933 934
    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
935

Kunshan Wang's avatar
Kunshan Wang committed
936
where::
Kunshan Wang's avatar
Kunshan Wang committed
937

Kunshan Wang's avatar
Kunshan Wang committed
938 939
    typedef MuFlag MuCallConv;
    #define MU_CC_DEFAULT   ((MuCallConv)0x00)
Kunshan Wang's avatar
Kunshan Wang committed
940

Kunshan Wang's avatar
Kunshan Wang committed
941 942 943
* ``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
944

Kunshan Wang's avatar
Kunshan Wang committed
945 946 947
* ``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
948

949
See the `Native Interface <native-interface.rst>`__ chapter for details of expose
Kunshan Wang's avatar
Kunshan Wang committed
950 951
and unexpose. See the platform-specific native interface for the return value
type.
Kunshan Wang's avatar
Kunshan Wang committed
952

Kunshan Wang's avatar
Kunshan Wang committed
953
Implementations may define other calling conventions in addition to
Kunshan Wang's avatar
Kunshan Wang committed
954
``MU_CC_DEFAULT``.
Kunshan Wang's avatar
Kunshan Wang committed
955

956 957
Trap Handling
=============
Kunshan Wang's avatar
Kunshan Wang committed
958

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

962 963
It is unspecified on which stack the trap handler is run.

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

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

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

Kunshan Wang's avatar
Kunshan Wang committed
973
The signature of trap handlers is::
974

Kunshan Wang's avatar
Kunshan Wang committed
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
    // 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
991
            MuCPtr userdata);
992

Kunshan Wang's avatar
Kunshan Wang committed
993
where::
994

Kunshan Wang's avatar
Kunshan Wang committed
995
    typedef MuFlag MuTrapHandlerResult;
996

Kunshan Wang's avatar
Kunshan Wang committed
997 998 999
    #define MU_THREAD_EXIT          ((MuTrapHandlerResult)0x00)
    #define MU_REBIND_PASS_VALUES   ((MuTrapHandlerResult)0x01)
    #define MU_REBIND_THROW_EXC     ((MuTrapHandlerResult)0x02)
1000

Kunshan Wang's avatar
Kunshan Wang committed
1001 1002
    typedef void _MuValuesFreer_Func(MuValue *values, MuCPtr freerdata);
    typedef _MuValuesFreer_Func* MuValuesFreer;
1003

Kunshan Wang's avatar
Kunshan Wang committed
1004 1005 1006
``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
1007
``thread`` and ``stack`` are held by ``ctx``. ``wpid`` is the watch point ID if
Kunshan Wang's avatar
Kunshan Wang committed
1008 1009
it is caused by a ``WATCHPOINT`` instruction, or 0 if by ``TRAP``. ``userdata``
is the pointer provided when registering the handler.
1010

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

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

Kunshan Wang's avatar
Kunshan Wang committed
1016
* ``MU_THREAD_EXIT``: The thread ``thread`` terminates.
1017

Kunshan Wang's avatar
Kunshan Wang committed
1018
* ``Mu_REBIND_PASS_VALUES``: The thread ``thread`` will be rebound to a stack
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
  ``*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
1032 1033
* ``Mu_REBIND_THROW_EXC``: The thread ``thread`` will be rebound to a stack
  ``*new_stack``. It throws exception ``*exception`` to the stack.
1034

1035 1036
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``.
1037

Kunshan Wang's avatar
Kunshan Wang committed
1038 1039 1040
Building Mu IR Bundles
======================

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

Kunshan Wang's avatar
Kunshan Wang committed
1043 1044 1045
Signal Handling
===============

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

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