C API
Prerequisites
The C implementation is currently written for targets where int
is 4 bytes and short
is 2 bytes. This is true for the usual 32/64
bit targets but may not be true in embedded targets and modifications would
be needed.
The code also uses the indirect goto feature of GCC and Clang for increasing
the performance. However it contains a fallback that uses switches with some
performance degradation and noticeable increase in object size. This doesn't
apply when JIT is available for given platform and is not disabled.
Temporary roots
To avoid premature garbage collection of temporary values in C code all created
arrays, strings, etc. are added into list of temporary roots. This list is
cleared only on explicit garbage collection, when calling script function or
returning from the handler of a native function.
Types
typedef struct Heap Heap;
-
The heap contains all the data structures of the scripts as well as the
compiled scripts themselves.
typedef struct Script Script;
-
Reference to specific script. This is to allow to query functions defined
in that script. The scripts are owned by
Heap
and must not
be mixed up between heaps or freed manually.
typedef struct { int value; int is_array; } Value;
-
Value struct contains the integer value and an indication if it's an array
reference or a float value. It's preferred to use this type as an opaque value
and always use the functions for handling the simple values.
Internal details: The distinction between array reference and floats is
made based on the unsigned value, if it's outside the range 1..0x7FFFFF (meaning
the exponent is present or the number is negative or zero) then it's outside of
valid array references and it's a float value. Note that denormalized numbers are
flushed to zero and thus don't collide with array references (the exponent would
be stored as 0 in such case). The is_array
is either 0 or 1, this
allows to directly compare the struct for equivalence. This struct is always
passed by value. You can test validity of any reference by comparing value
to zero (all references are non-zero).
typedef struct SharedArrayHandle SharedArrayHandle;
-
Used for referencing shared arrays outside a heap.
typedef void (*HandleFreeFunc)(void *p);
-
Used for freeing the native handle. Called during garbage collection, it is advised
to not trigger garbage collection in the function (directly or indirectly), however
there is a safeguard preventing a recursive GC. Should GC occur again the heap will
get larger instead (and there is a possibility of getting spurious out of memory errors
if the heap was already big enough, also it can overinflate the heap without the ability
to shrink because of fragmentation).
typedef void *(*HandleFunc)(Heap *heap, int op, void *p1, void *p2);
-
Used for handling the native value handle. The operation can be one of the following:
HANDLE_OP_FREE
- free the value handle
p1
(called during garbage collection, see the note on HandleFreeFunc type)
HANDLE_OP_COPY
- create a copy of the value handle
p1
or return NULL
if copies are not supported (the destination heap pointer is in p2
), this operation must be thread-safe as the copying can occur in multiple threads concurrently
HANDLE_OP_COMPARE
- compare the value handles
p1
and p2
, result is negative (if less), zero (if equal) or positive (if greater), the result needs to be casted to intptr_t
and then to void *
note: the second pointer can be from a handle in a different heap
HANDLE_OP_HASH
- return hash of the value handle
p1
casted to void *
(only low 32 bits are used)
HANDLE_OP_TO_STRING
- return newly allocated string representation of the value handle
p1
(return NULL
for default string representation)
HANDLE_OP_MARK_REFS
- called during GC to mark references (using the
fixscript_mark_ref
function) held on the native side (p1
points to handle)
HANDLE_OP_COPY_REFS
- called during deep cloning to copy references (using the
fixscript_copy_ref
function) held on the native side (p1
points to handle and p2
to copy context), this operation must be thread-safe as the copying can occur in multiple threads concurrently
note: in some circumstances it won't be called for a deep copy (eg. in case of an error during cloning), handle such cases gracefully
typedef Script *(*LoadScriptFunc)(Heap *heap, const char *fname, Value *error, void *data);
-
Used for providing a callback to load other scripts when using the
import
or the use
statement.
typedef Value (*NativeFunc)(Heap *heap, Value *error, int num_params, Value *params, void *data);
-
Used for providing native functions. Use
error
to return second return value (usually used for errors, initialized to zero).
Error codes
Note: Error constants are negative values (success code is zero).
FIXSCRIPT_SUCCESS
-
No error occurred.
FIXSCRIPT_ERR_INVALID_ACCESS
-
The value is an invalid reference.
FIXSCRIPT_ERR_INVALID_BYTE_ARRAY
-
The value is invalid byte array (contains values outside the range of byte or contains non-integer values).
FIXSCRIPT_ERR_INVALID_SHORT_ARRAY
-
The value is invalid short array (contains values outside the range of short or contains non-integer values).
FIXSCRIPT_ERR_INVALID_NULL_STRING
-
The string contains zero character (reported only when the string is retrieved without getting the length and thus relying on the zero character termination).
FIXSCRIPT_ERR_CONST_WRITE
-
The value is a constant string and can't be modified.
FIXSCRIPT_ERR_OUT_OF_BOUNDS
-
The index or range is out of the bounds.
FIXSCRIPT_ERR_OUT_OF_MEMORY
-
Tried to allocate more memory than available or an integer overflow occurred during computation of how much to allocate.
FIXSCRIPT_ERR_INVALID_SHARED_ARRAY_OPERATION
-
Tried to change length or element size on a shared array, or put a reference or native handle to such array.
FIXSCRIPT_ERR_KEY_NOT_FOUND
-
The requested key isn't present in the hash table.
FIXSCRIPT_ERR_RECURSION_LIMIT
-
The recursion limit was exceeded.
FIXSCRIPT_ERR_UNSERIALIZABLE_REF
-
An unserializable reference occurred (for example native handle).
FIXSCRIPT_ERR_BAD_FORMAT
-
Bad format or data too short (when unserializing).
FIXSCRIPT_ERR_FUNC_REF_LOAD_ERROR
-
Script load error during resolving of function reference (typically native function not defined
or script wasn't loaded when resolving within already loaded code only).
FIXSCRIPT_ERR_NESTED_WEAKREF
-
Nested weak references are not allowed (referencing directly another weak reference or having
a key as a weak reference).
Functions
Simple values handling
Note: these functions are all inlined.
Value fixscript_int(int value);
-
Makes a 32-bit integer value.
Value fixscript_float(float value);
-
Makes a 32-bit float value. The denormals are flushed to zero.
int fixscript_is_int(Value value);
-
Returns whether the value is a 32-bit integer.
int fixscript_is_float(Value value);
-
Returns whether the value is a 32-bit float.
int fixscript_get_int(Value value);
-
Returns the integer representation of the value. If the value is a float
or an array reference it will return the bitwise representation.
float fixscript_get_float(Value value);
-
Returns the float representation of the value. Gives incorrect values
if the value wasn't a float.
Heap management
Heap *fixscript_create_heap();
-
Creates a new heap, this contains the whole context of script execution. You
can use only different heaps in different threads concurrently.
void fixscript_free_heap(Heap *heap);
-
Frees all the resources for given heap.
void fixscript_collect_heap(Heap *heap);
-
Runs garbage collection for given heap. It also clears the temporary roots,
you need to store references directly in the heap or increase their external
reference count to persist them.
long long fixscript_heap_size(Heap *heap);
-
Traverses the heap to obtain the overall size of the heap in bytes. This includes
overheads from reserved memory for array growths and struct paddings, but
doesn't include overhead of the underlying
malloc
implementation.
void fixscript_adjust_heap_size(Heap *heap, long long relative_change);
-
Adjusts tracked memory footprint of the heap. This is used for making sure the
garbage collection knows about externally allocated memory (eg. when using native
handles).
void fixscript_set_max_stack_size(Heap *heap, int size);
-
Sets the maximum stack size in number of stack entries (each taking 5 bytes and
currently each up to 32 bytes for native JIT stack).
int fixscript_get_max_stack_size(Heap *heap);
-
Returns the stack size limit.
int fixscript_get_stack_size(Heap *heap);
-
Returns the current stack size.
void fixscript_ref(Heap *heap, Value value);
-
Increases the number of external references, preventing the value from being garbage collected.
There is an internal limit that once reached will prevent decreasing of the counter to prevent
releasing the value while still potentially being held.
Note: Beware of reference cycles that will result into inability to reclaim memory. Often this is
when the native handle needs to hold into some heap data which contains reference back to the native
handle, creating a cycle. This is best solved by using a value handle and using the HANDLE_OP_MARK_REFS
operation to mark any such references. Alternativelly you can use weak references on the native
side (simply by not using fixscript_ref
) and wrapping the native handle into
an object (containing array of references that need to be retained) and referencing to that object
instead of the handle.
void fixscript_unref(Heap *heap, Value value);
-
Decreases the number of external references, once at zero the value can be garbage collected.
void fixscript_set_protected(Heap *heap, Value value, int is_protected);
-
Sets the protected status of given reference. This is used in native libraries that want to
protect internal data structures to not be directly exposed to the scripts by other native
libraries that create arbitrary references from just the integer portion and pass them to the
scripts.
int fixscript_is_protected(Heap *heap, Value value);
-
Returns whether the given reference is protected and shouldn't be exposed to the script.
void fixscript_register_cleanup(Heap *heap, HandleFreeFunc free_func, void *data);
-
Registers a cleanup function that will be called when the heap is freed.
void fixscript_register_heap_key(volatile int *key);
-
Registers a heap key if it's not registered already, this is done atomically. This is a global operation,
and should be used for static initialization only.
int fixscript_set_heap_data(Heap *heap, int key, void *data, HandleFreeFunc free_func);
-
Sets per-heap value with given key, freeing the previous value if present.
void *fixscript_get_heap_data(Heap *heap, int key);
-
Returns per-heap value for given key.
Execution time limit
void fixscript_set_time_limit(Heap *heap, int limit);
-
Sets a time limit in milliseconds for execution of the scripts. The time limit starts
counting after calling of this function. This function must be called before any
scripts are loaded as they need to be instrumented with the time checks. To disable
the time limit, pass -1 as a limit (avoid passing 0 as that would remove instrumentation
for newly compiled scripts).
int fixscript_get_remaining_time(Heap *heap);
-
Returns the remaining time in milliseconds (capped to 0) for execution of the scripts.
Returns -1 when the time limit is not set. The 0 is also returned when the heap is
stopped asynchronously from another thread.
void fixscript_stop_execution(Heap *heap);
-
Stops the running script asynchronously from another thread. The heap must be using
the time limit feature (use -1 for no actual time limit). To be able to run code again
the time limit must be set again (it will reset the stop execution flag).
Reference handling in value handles
void fixscript_mark_ref(Heap *heap, Value value);
-
Marks a reference held on the native side. Call this only during the
HANDLE_OP_MARK_REFS
operation of the value handles.
Value fixscript_copy_ref(void *ctx, Value value);
-
Creates a copy of the reference, using the copy context that is available during
HANDLE_OP_COPY_REFS
operation of the value handles.
Array access
Value fixscript_create_array(Heap *heap, int len);
-
Creates a new array of given length. The reference is added into temporary roots
to prevent it from premature deallocation.
Value fixscript_create_byte_array(Heap *heap, const char *buf, int len);
-
Creates a new byte array with given content. The reference is added into
temporary roots to prevent it from premature deallocation.
int fixscript_set_array_length(Heap *heap, Value arr_val, int len);
-
Sets length of given array, expanding the capacity when needed. If the
length is bigger than currently is the space is filled with zeros.
Does nothing in case the array reference is invalid. Returns error code.
int fixscript_get_array_length(Heap *heap, Value arr_val, int *len);
-
Returns length of the array or hash in the output parameter. Returns error code.
int fixscript_get_array_element_size(Heap *heap, Value arr_val, int *elem_size);
-
Returns the current element size (1, 2 or 4 bytes) of the array in the output parameter. Returns error code.
int fixscript_is_array(Heap *heap, Value arr_val);
-
Returns whether the given value is valid reference to an array.
int fixscript_set_array_elem(Heap *heap, Value arr_val, int idx, Value value);
-
Sets value in the array at given index. Returns error code.
int fixscript_get_array_elem(Heap *heap, Value arr_val, int idx, Value *value);
-
Retrieves value in the array at given index. Returns error code.
int fixscript_append_array_elem(Heap *heap, Value arr_val, Value value);
-
Appends value in to the array. Returns error code.
int fixscript_get_array_range(Heap *heap, Value arr_val, int off, int len, Value *values);
-
Retrieves values from the array in specified range. Returns error code.
int fixscript_set_array_range(Heap *heap, Value arr_val, int off, int len, Value *values);
-
Stores values to the array in specified range. Returns error code.
int fixscript_get_array_bytes(Heap *heap, Value arr_val, int off, int len, char *bytes);
-
Retrieves byte values from the array in specified range. Returns error code.
int fixscript_set_array_bytes(Heap *heap, Value arr_val, int off, int len, char *bytes);
-
Stores byte values to the array in specified range. Returns error code.
int fixscript_has_array_references(Heap *heap, Value arr_val, int off, int len, int float_as_ref, int *result);
-
Checks the array for contained references. You can specify if you want to treat floats as
references (faster) or not. The result is passed in an output parameter. Returns error code.
int fixscript_copy_array(Heap *heap, Value dest, int dest_off, Value src, int src_off, int count);
-
Copies given amount of values between different arrays or within the same array. Returns error code.
int fixscript_lock_array(Heap *heap, Value arr_val, int off, int len, void **data, int elem_size, int access);
-
Obtains direct pointer access to an array when possible or allocates a temporary buffer
and optionally copies the data to it from the array. You must unlock the array by calling
fixscript_unlock_array
with the same parameters (length can be made smaller).
There must be no other access to the array while being locked.
The reference is added into temporary roots to prevent it from premature deallocation.
The access can be one of ACCESS_READ_ONLY
, ACCESS_WRITE_ONLY
or
ACCESS_READ_WRITE
.
void fixscript_unlock_array(Heap *heap, Value arr_val, int off, int len, void **data, int elem_size, int access);
-
Finishes direct pointer access to an array or optionally copies the data from the temporary
buffer back into the array and frees the temporary buffer if used. All the parameters must
be the same as when called the
fixscript_lock_array
function. It is however
permitted to shorten the length to avoid unnecessary copying of data.
In write mode the values in the range are converted to integers only, making any references
invalid.
Shared arrays
Value fixscript_create_shared_array(Heap *heap, int len, int elem_size);
-
Creates a new shared array. The reference is added into temporary roots to prevent it
from premature deallocation.
Value fixscript_create_or_get_shared_array(Heap *heap, int type, void *ptr, int len, int elem_size, HandleFreeFunc free_func, void *data, int *created);
-
Creates a new shared array with user provided pointer or gets an existing instance.
The type allows to specify what kind of handle type it is (use a non-negative integer
or pass a negative number when not used). The pointer must be aligned to element size.
The reference is added into temporary roots to prevent it from premature deallocation.
Optionally you can retrieve whether the shared array was created or an existing instance
was returned instead.
Note: The shared arrays are matched based on type, pointer, length, element size
and data, therefore if any of these are unique (eg. resulting from a new allocation),
the array is always created as new and there is no need to check for creation status.
void fixscript_ref_shared_array(SharedArrayHandle *sah);
-
Increases the number of references, preventing the shared array from being freed prematurely.
There is an internal limit that once reached will prevent decreasing of the counter to prevent
freeing the array while still potentially being held.
void fixscript_unref_shared_array(SharedArrayHandle *sah);
-
Decreases the number of references, once at zero the shared array is freed.
int fixscript_get_shared_array_reference_count(SharedArrayHandle *sah);
-
Returns the value of reference counter for given shared array.
SharedArrayHandle *fixscript_get_shared_array_handle(Heap *heap, Value arr_val, int expected_type, int *actual_type);
-
Obtains direct reference to shared array for usage outside of the heap. You can restrict
obtaining for given handle type only (pass a negative value to allow any type of shared
array). Returns
NULL
on error (invalid value or different type).
void *fixscript_get_shared_array_handle_data(SharedArrayHandle *sah, int *len, int *elem_size, void **data, int expected_type, int *actual_type);
-
Returns information about a shared array. You can restrict checking for given handle type
(pass a negative value to disable the check). All output parameters are optional. Returns
NULL
on error (different type).
Value fixscript_get_shared_array_value(Heap *heap, SharedArrayHandle *sah);
-
Creates or returns an existing reference to given shared array.
Value fixscript_get_shared_array(Heap *heap, int type, void *ptr, int len, int elem_size, void *data);
-
Returns an existing reference to a shared array, returns
null
in case the reference
is not present.
void *fixscript_get_shared_array_data(Heap *heap, Value arr_val, int *len, int *elem_size, void **data, int expected_type, int *actual_type);
-
Returns information about a shared array. You can restrict checking for given handle type
(pass a negative value to disable the check). All output parameters are optional. Returns
NULL
on error (invalid value or different type).
int fixscript_is_shared_array(Heap *heap, Value arr_val);
-
Returns whether the given value is a valid reference to a shared array.
String access
Value fixscript_create_string(Heap *heap, const char *s, int len);
-
Creates a new string from UTF-8 encoded characters of given length. Any
incorrectly encoded character is replaced by the replacement character
(U+FFFD). If the length is negative the length is computed automatically.
The reference is added into temporary roots to prevent it from premature
deallocation.
Value fixscript_create_string_utf16(Heap *heap, const unsigned short *s, int len);
-
A variant of
fixscript_create_string
that uses UTF-16 encoded
characters. Any invalid surrogate pair encoding is replaced by the replacement
character (U+FFFD).
int fixscript_get_string(Heap *heap, Value str_val, int str_off, int str_len, char **str, int *len_out);
-
Returns the string contents as UTF-8 encoded characters (pass negative value for
length to use the whole string). Any invalid character (outside of the valid range
or within the surrogate pairs range) is replaced by the replacement character (U+FFFD).
The string is always zero-terminated and you can optionally obtain the string length.
The string must be deallocated by the caller using the
free
function.
If the output length is not obtained and the string contains zero character it returns
an error instead of returning shortened string. Returns error code.
int fixscript_get_string_utf16(Heap *heap, Value str_val, int str_off, int str_len, unsigned short **str, int *len_out);
-
A variant of
fixscript_get_string
that uses UTF-16 encoded
characters.
int fixscript_is_string(Heap *heap, Value str_val);
-
Returns whether the given value is a valid reference to a string.
int fixscript_get_const_string(Heap *heap, Value str_val, int off, int len, Value *ret);
-
Returns a constant string (can't be modified) for the given string. You can either specify
a portion of the original string or specify negative length to consider the whole string,
in such case the same string is returned if it is already a constant. Returns error code.
There is always only a single instance for each unique constant string.
int fixscript_get_const_string_between(Heap *dest, Heap *src, Value str_val, int off, int len, Value *ret);
-
A variant that allows to use a different heap for the source string.
int fixscript_is_const_string(Heap *heap, Value str_val);
-
Returns whether the given value is a valid reference to a constant string.
Hash access
Value fixscript_create_hash(Heap *heap);
-
Creates a new hash. The reference is added into temporary roots to
prevent it from premature deallocation.
int fixscript_is_hash(Heap *heap, Value hash_val);
-
Returns whether the given value is valid reference to a hash.
int fixscript_set_hash_elem(Heap *heap, Value hash_val, Value key_val, Value value_val);
-
Sets value in the hash for given key. Returns error code.
int fixscript_get_hash_elem(Heap *heap, Value hash_val, Value key_val, Value *value_val);
-
Retrieves value in the hash for given key. Returns error code.
int fixscript_get_hash_elem_between(Heap *heap, Value hash_val, Heap *key_heap, Value key_val, Value *value_val);
-
Retrieves value in the hash for given key (the key can be from a different heap). Returns error code.
int fixscript_remove_hash_elem(Heap *heap, Value hash_val, Value key_val, Value *value_val);
-
Removes entry for given key. Returns error code.
int fixscript_clear_hash(Heap *heap, Value hash_val);
-
Clears all entries in the hash. Returns error code.
int fixscript_iter_hash(Heap *heap, Value hash_val, Value *key_val, Value *value_val, int *pos);
-
Retrieves the next key and value from the hash. The iteration position must be initialized to zero before
retrieving first entry. Returns non-zero if entry was retrieved or zero when there are no more entries present.
Native handles
Value fixscript_create_handle(Heap *heap, int type, void *handle, HandleFreeFunc free_func);
-
Creates a new native handle. The
type
must not be negative. free_func
is optional.
Value fixscript_create_value_handle(Heap *heap, int type, void *handle, HandleFunc handle_func);
-
Creates a new native value handle (supports comparing by value and cloning). The
type
must not be negative.
void *fixscript_get_handle(Heap *heap, Value handle_val, int expected_type, int *actual_type);
-
Obtains native handle with given type (or negative value to disable the check), optionally you can get the type
(set to -1 in case the handle is invalid). Returns
NULL
on error (invalid value or different type).
void fixscript_register_handle_types(volatile int *offset, int count);
-
Registers given number of native handle types if it's not registered already, this is done atomically.
This is a global operation, and should be used for static initialization only. The counts are counted
from
INT_MAX
and allocated by decrementing.
int fixscript_is_handle(Heap *heap, Value handle_val);
-
Returns whether the given value is a valid reference to a handle.
Weak references
int fixscript_create_weak_ref(Heap *heap, Value value, Value *container, Value *key, Value *weak_ref);
-
Creates a new weak reference (or already existing instance). Optionally you can pass
a container (hash table or array) for automatic action to occur once the target object
is garbage collected. In case of hash tables either the weak reference or provided
key is removed. For arrays either the weak reference or provided key is appended to
it. Be sure to periodically empty the array to prevent memory leaks.
Note: weak references can't reference directly other weak references (including the key).
int fixscript_get_weak_ref(Heap *heap, Value weak_ref, Value *value);
-
Obtains the reference value for given weak reference.
int fixscript_is_weak_ref(Heap *heap, Value weak_ref);
-
Returns whether the given value is a weak reference.
Error handling
const char *fixscript_get_error_msg(int error_code);
-
Returns error message as a constant string, returns NULL for success or unknown error codes.
Value fixscript_create_error(Heap *heap, Value msg);
-
Creates error value (with the same format as the builtin
error
function) with given value for message.
Value fixscript_create_error_string(Heap *heap, const char *s);
-
Creates error value (with the same format as the builtin
error
function) with given error message.
Value fixscript_error(Heap *heap, Value *error, int code);
-
Creates error value (with the same format as the builtin
error
function) with error message that
corresponds to given error code. For convenience it returns zero and stores the error into the provided parameter.
const char *fixscript_get_compiler_error(Heap *heap, Value error);
-
Returns a string representation of a compiler error. It also handles simplifying of
syntax errors produced by token processors. The returned string is allocated internally
and the previous pointer is freed for each invocation of this function.
Value inspection
int fixscript_dump_value(Heap *heap, Value value, int newlines);
-
Pretty prints the given value to standard error stream (
stderr
).
int fixscript_to_string(Heap *heap, Value value, int newlines, char **str, int *len);
-
Pretty prints the given value to newly allocated UTF-8 string (zero-terminated if length is not obtained).
Returns error code.
Cloning & serialization
int fixscript_compare(Heap *heap, Value value1, Value value2);
-
Compares the values, returns a non-zero value when they are equal. There is currently
a maximum recursion limit of 50, more nested values will simply return as not equal.
int fixscript_compare_between(Heap *heap1, Value value1, Heap *heap2, Value value2);
-
A variant that allows to use a different heap for each value.
int fixscript_clone(Heap *heap, Value value, int deep, Value *clone);
-
Clones given value. Returns error code.
int fixscript_clone_between(Heap *dest, Heap *src, Value value, Value *clone, LoadScriptFunc load_func, void *load_data, Value *error);
-
Clones given value between different (or same) heaps. The optional load function is to load
the scripts for cloned function references, otherwise the references will be unresolved
until cloned again with the load function provided. You can pass the
fixscript_resolve_existing
function to allow references to be resolved in already loaded code without loading any other code.
Returns error code. You can optionally obtain more precise error value when script load fails (if
resolving is used). The error is stored in the destination heap, if no such detailed error is produced
use the standard error codes. It is permitted to clone to multiple threads concurrently as long as the
source heap is not used for anything else.
int fixscript_serialize(Heap *heap, Value *buf_val, Value value);
-
Serializes given value to byte array value (created when not provided).
int fixscript_unserialize(Heap *heap, Value buf_val, int *off, int len, Value *value);
-
Unserializes value from given byte array value. The provided offset is adjusted with the resulting position
after the operation. If the length is passed as negative it will allow extra data after the serialized
data (possibily another serialized data).
int fixscript_serialize_to_array(Heap *heap, char **buf, int *len_out, Value value);
-
Serializes given value to native byte array. If length is not obtained the serialized form is prepended by
the size of the serialized data.
int fixscript_unserialize_from_array(Heap *heap, const char *buf, int *off_out, int len, Value *value);
-
Unserializes value from given native byte array. If length is negative it is read from the beginning
of the serialized data (must be outputed in that form). Optionally you can retrieve offset after the
serialized data, in that case it will allow extra data after the serialized data (possibly another
serialized data).
Script loading & running
Script *fixscript_load(Heap *heap, const char *src, const char *fname, Value *error, LoadScriptFunc load_func, void *load_data);
-
Loads given script source under provided file name. On error it returns
NULL
and the error
value is outputed (optional). Passing of load_func
is optional (import
and
use
statements will not work in such case). You can use fixscript_resolve_existing
function to allow loading of already compiled scripts.
Script *fixscript_load_file(Heap *heap, const char *name, Value *error, const char *dirname);
-
A variant of
fixscript_load
that loads scripts from file system.
Script *fixscript_load_embed(Heap *heap, const char *name, Value *error, const char * const * const embed_files);
-
A variant of
fixscript_load
that loads scripts from embedded static array as produced by the fixembed
tool.
Script *fixscript_reload(Heap *heap, const char *src, const char *fname, Value *error, LoadScriptFunc load_func, void *load_data);
-
Reloads given script. The newly loaded version of the script replaces existing functions so new calls will
go to the updated script. On error it returns
NULL
and the error value is outputed (optional).
Passing of load_func
is optional (import
and use
statements will not
work in such case). You can use fixscript_resolve_existing
function to allow loading of already
compiled scripts.
Script *fixscript_resolve_existing(Heap *heap, const char *name, Value *error, void *data);
-
Script loading function that returns an error when trying to load a new script. Used for enabling function
reference resolving within already loaded scripts when cloning between heaps or just to allow to use
the previously compiled scripts only.
Script *fixscript_get(Heap *heap, const char *fname);
-
Returns script for given file name (or
NULL
if not found).
char *fixscript_get_script_name(Heap *heap, Script *script);
-
Returns newly allocated script name for given script (or
NULL
if no script is provided).
Value fixscript_get_function(Heap *heap, Script *script, const char *func_name);
-
Returns function handle for function with given name (must provide parameter count as part of the name).
Returns zero in case the script is not provided.
int fixscript_get_function_list(Heap *heap, Script *script, char ***functions_out, int *count_out);
-
Obtains a list of functions in given script as two output parameters. Returns an error code. The individual
strings and the list must be freed using the
free
function.
int fixscript_get_function_name(Heap *heap, Value func_val, char **script_name_out, char **func_name_out, int *num_params_out);
-
Obtains script name, function name and number of parameters for given function value (all obtained values are optional). Returns error code.
int fixscript_is_func_ref(Heap *heap, Value func_ref);
-
Returns whether the given value is a function reference.
Value fixscript_run(Heap *heap, Script *script, const char *func_name, Value *error, ...);
-
Runs function with given name (including parameter count in the name) and (optionally) obtains the error value.
Value fixscript_run_args(Heap *heap, Script *script, const char *func_name, Value *error, Value *args);
-
A variant of
fixscript_run
with arguments passed as an array.
Value fixscript_call(Heap *heap, Value func, int num_params, Value *error, ...);
-
Calls function using given function value and (optionally) obtains the error value.
Value fixscript_call_args(Heap *heap, Value func, int num_params, Value *error, Value *args);
-
A variant of
fixscript_call
with arguments passed as an array.
void fixscript_register_native_func(Heap *heap, const char *name, NativeFunc func, void *data);
-
Registers (or replaces) native function with given name.
NativeFunc fixscript_get_native_func(Heap *heap, const char *name, void **data);
-
Returns registered native function and the associated data (optional).
Bytecode & heap inspection
char *fixscript_dump_code(Heap *heap, Script *script, const char *func_name);
-
Returns newly allocated string representation of bytecode for given function (or all functions if not provided).
char *fixscript_dump_heap(Heap *heap);
-
Returns newly allocated string representation of heap values.
Optional asynchronous mode
There is an optional support for asynchronous mode that allows to have
suspendable native functions and automatic suspension after processing of a
number of instructions (for emulation of threads). The result is that the
FixScript code is synchronous and the asynchronicity needs to be dealt with
in native functions only.
This needs to be enabled by the FIXSCRIPT_ASYNC
define. When compiling
for the WebAssembly target it is automatically enabled. Use the FIXSCRIPT_NO_ASYNC
define to disable it.
Currently enabling this mode disables the JIT compiler. There is no plan to add
support for JIT in this mode except for platforms that require it for operation
(WebAssembly only). Any other native platform is always able to manipulate the
native stack therefore there is no need for this mode. However it might be
simpler in some cases (and to be platform independent) to use this mode instead.
Types
typedef void (*ContinuationFunc)(void *data);
-
A general continuation function.
typedef void (*ContinuationResultFunc)(Heap *heap, Value result, Value error, void *data);
-
A continuation function that receives result from an asynchronous call.
typedef void (*ContinuationSuspendFunc)(ContinuationFunc resume_func, void *resume_data, void *data);
-
A continuation function that receives another continuation function for
resuming the original processing.
Functions
void fixscript_set_auto_suspend_handler(Heap *heap, int num_instructions, ContinuationSuspendFunc func, void *data);
-
Sets the handler for automatic suspension after processing a number of instructions.
The handler can cancel the suspension by calling the resume function immediately.
It reuses the execution time limit feature which is automatically enabled for
all heaps in asynchronous mode. Pass
NULL
as function to disable it.
Note: automatic suspension is disabled in token processors.
void fixscript_get_auto_suspend_handler(Heap *heap, int *num_instructions, ContinuationSuspendFunc *func, void **data);
-
Returns the handler for automatic suspension. All output parameters are optional.
void fixscript_suspend(Heap *heap, ContinuationResultFunc *func, void **data);
-
Suspends the native function. Returns the continuation function that needs to be called with
the result. After calling this function the native function handler should just return.
It is a fatal non-recoverable error to call this function when the FixScript code isn't called
using the asynchronous variants of the call functions. Use the
fixscript_in_async_call
to check for this condition.
void fixscript_suspend_void(Heap *heap, ContinuationFunc *func, void **data);
-
An alternative variant of suspending for native functions that return no value. Uses a simpler
continuation function type.
void fixscript_run_async(Heap *heap, Script *script, const char *func_name, Value *args, ContinuationResultFunc cont_func, void *cont_data);
-
Runs asynchronously function with given name (including parameter count in the name). After
calling this function you should just return, leaving further processing to the provided
continuation function.
void fixscript_call_async(Heap *heap, Value func, int num_params, Value *args, ContinuationResultFunc cont_func, void *cont_data);
-
A variant for asynchronous calling using a function reference.
void fixscript_allow_sync_call(Heap *heap);
-
This function must be called right before the normal (synchronous) call functions
(
fixscript_run
and fixscript_call
) to allow to run in
synchronous mode from an asynchronous call. This is for special needs where you
can't support asynchronous mode (for example when calling functions from native
handles). The auto suspending is also automatically disabled in this mode.
int fixscript_in_async_call(Heap *heap);
-
Returns whether the heap is currently in asynchronous call.