You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Aug 2, 2019. It is now read-only.
The current API is expressed in a language-neutral form, and it is the implementation that decides how to implement such an interface. Programmers still need to resort to implementation-specific interfaces to actually use a particular Mu implementation.
Since C is so widely used as a system programming language, the Mu client interface (a.k.a the API) should be expressed as data types and function calls in the C programming language. If the client is not in C, it usually still has a C FFI.
The API in C
Resources in Mu are exposed in opaque types which have reference semantics: they can be copied and still refers to the same resource.
mu_micro_vm_t: a reference to a Mu micro VM instance.
mu_client_agent_t: a reference to a client agent.
mu_handle_t: a handle to a value in the Mu type system exposed to the client.
Messages are C functions. Like JNI, they are contained in a struct: typedef struct mu_api_msgs {...} mu_api_msgs_t. In this way, the client in C does not need to link against any libraries when compiling. The reason is, for a Mu micro VM implemented in a higher-level language (like the reference implementation in Scala), the binding of the callable C function is generated very late, later than even the loading time, and has no access to the native loader.
For example, assume there is a mu_api_msgs_t* msgs defined:
mu_client_agent_tca= ...
charbuf[999999];
intsz;
// load file into bufmsgs->load_bundle(ca, buf, sz); // Load a bundle// Putting C values into Mumu_handle_th1=msgs->put_schar(ca, 127);
mu_handle_th2=msgs->put_sshort(ca, 32767);
mu_handle_th3=msgs->put_sint(ca, 42);
mu_handle_th4=msgs->put_slong(ca, 42);
mu_handle_th5=msgs->put_slonglong(ca, 999999999999999);
// Converting Mu values to Cintv3=msgs->to_sint(ca, h3);
unsigned longv4=msgs->to_ulong(ca, h4); // just treat the int as unsigned
Mu-level flags are C preprocessor macros. They have type int.
msgs->store(SEQ_CST, hLoc, hNewVal); // SEQ_CST is a macro
Callbacks, including the trap handler and undefined function handler, have defined signatures:
These functions are registered via the msgs->register_trap_handler and msgs->register_undefined_function_handler API messages. In their parameters, the user_data is an arbitrary pointer provided by the client in an implementation-specific manner (see below).
Implementation-defined behaviours
Some aspects of the C binding are implementation-specified. They include:
How to create a Mu micro VM? Options are:
The C executable creates the Mu instance.
Mu loads the C dynamic library.
Mu starts separately and C connects to the existing instance in the same process.
C connects to a Mu instance in a different process, or a different machine.
Options in creating Mu instances. Options are:
Heap size. Giving a heap size means the Client determines the heap size rather than Mu automatically decide its own storage.
Global data space size. Setting this value means the global data may have their own storage. Actual implementation could use the heap space, too.
Stack size. Similarly, this is too implementation-specific.
What happens during initialisation?
Mu calls a C function to initialise the client, and the client provides a void* to Mu for the client's own context. (note: in this case, it is Mu loading C rather than C creating Mu.)
C creates a Mu instance, and sets its void* user data in a proprietary API message.
Open questions
Should we allow each Mu implementation have its own "namespace"? The opaque types (mu_micro_vm_t and so on) are opaque, but different implementations may have different representations. The current C binding design forbids one C program working with more than one Mu implementations (though it is okay to work with more than one instances of the same implementation).
JNI does not solve this problem, either.
The text was updated successfully, but these errors were encountered:
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The current API is expressed in a language-neutral form, and it is the implementation that decides how to implement such an interface. Programmers still need to resort to implementation-specific interfaces to actually use a particular Mu implementation.
Since C is so widely used as a system programming language, the Mu client interface (a.k.a the API) should be expressed as data types and function calls in the C programming language. If the client is not in C, it usually still has a C FFI.
The API in C
Resources in Mu are exposed in opaque types which have reference semantics: they can be copied and still refers to the same resource.
mu_micro_vm_t
: a reference to a Mu micro VM instance.mu_client_agent_t
: a reference to a client agent.mu_handle_t
: a handle to a value in the Mu type system exposed to the client.Messages are C functions. Like JNI, they are contained in a struct:
typedef struct mu_api_msgs {...} mu_api_msgs_t
. In this way, the client in C does not need to link against any libraries when compiling. The reason is, for a Mu micro VM implemented in a higher-level language (like the reference implementation in Scala), the binding of the callable C function is generated very late, later than even the loading time, and has no access to the native loader.For example, assume there is a
mu_api_msgs_t* msgs
defined:Mu-level flags are C preprocessor macros. They have type int.
Callbacks, including the trap handler and undefined function handler, have defined signatures:
These functions are registered via the
msgs->register_trap_handler
andmsgs->register_undefined_function_handler
API messages. In their parameters, theuser_data
is an arbitrary pointer provided by the client in an implementation-specific manner (see below).Implementation-defined behaviours
Some aspects of the C binding are implementation-specified. They include:
void*
to Mu for the client's own context. (note: in this case, it is Mu loading C rather than C creating Mu.)void*
user data in a proprietary API message.Open questions
mu_micro_vm_t
and so on) are opaque, but different implementations may have different representations. The current C binding design forbids one C program working with more than one Mu implementations (though it is okay to work with more than one instances of the same implementation).The text was updated successfully, but these errors were encountered: