| Title: | Builds the 'TinyCC' Command-Line Interface and Library for 'C' Scripting in 'R' |
|---|---|
| Description: | Builds the 'TinyCC' (Tiny 'C' Compiler) command-line interface and library for package use in 'R'. The package compiles 'TinyCC' from source and provides R functions to interact with the compiler. 'TinyCC' can be used for header preprocessing, just-in-time compilation of 'C' code in 'R', and lightweight 'C' scripting workflows. |
| Authors: | Sounkou Mahamane Toure [aut, cre], Mike Cheng [cph] (Adapted parts of the vignette knitr engine from the callme package), Adam Dunkels [cph] (Author of the bundled protothreads library), Fabrice Bellard and tinycc Authors [ctb] (Tinycc Compiler (tinycc) authors and COPYRIGHT holders) |
| Maintainer: | Sounkou Mahamane Toure <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.11.9000 |
| Built: | 2026-06-03 21:53:10 UTC |
| Source: | https://github.com/sounkou-bioinfo/Rtinycc |
Overrides $ to detect dead pointers after deserialization
and recompile transparently from the stored recipe.
## S3 method for class 'tcc_compiled' x$name## S3 method for class 'tcc_compiled' x$name
x |
A tcc_compiled object |
name |
Symbol name to access |
The callable function or metadata field
tcc_cstring object to an R stringConvert a tcc_cstring object to an R string
## S3 method for class 'tcc_cstring' as.character(x, ...)## S3 method for class 'tcc_cstring' as.character(x, ...)
x |
A |
... |
Ignored. |
A character scalar containing the string value. Returns the
cached R copy when available; otherwise reads the current NUL-terminated
C string from x$ptr.
Returns the BLAS/LAPACK runtime details as reported by R itself, plus
convenience flags indicating whether Rblas and Rlapack appear available
in loaded DLLs/shared objects.
blas_lapack_info()blas_lapack_info()
A named list with fields:
blas_path, lapack_path, has_rblas, has_rlapack, loaded_dlls.
Generate trampoline code for a callback argument
generate_trampoline(trampoline_name, sig)generate_trampoline(trampoline_name, sig)
trampoline_name |
Name of the trampoline function |
sig |
Parsed signature |
C code string for the trampoline
Extract the memory address from an external pointer as a numeric value. This is primarily useful for debugging and inspection purposes.
get_external_ptr_addr(ptr)get_external_ptr_addr(ptr)
ptr |
An external pointer object (e.g., from |
The memory address as a numeric value.
Check if a type represents a callback
is_callback_type(type)is_callback_type(type)
type |
Type string to check |
Logical
Parse callback type specification
parse_callback_type(type)parse_callback_type(type)
type |
Type string like "callback:double(int,int)" |
Parsed signature list or NULL
Print tcc_callback object
## S3 method for class 'tcc_callback' print(x, ...)## S3 method for class 'tcc_callback' print(x, ...)
x |
A tcc_callback object |
... |
Ignored |
The input tcc_callback object, invisibly. Called for its
side effect of printing the callback signature, thread-safety flag,
and validity status.
Print tcc_compiled object
## S3 method for class 'tcc_compiled' print(x, ...)## S3 method for class 'tcc_compiled' print(x, ...)
x |
A tcc_compiled object |
... |
Ignored |
The input tcc_compiled object, invisibly. Called for its side
effect of printing the compilation output mode and the status of
compiled callable symbols.
tcc_cstring objectPrint a tcc_cstring object
## S3 method for class 'tcc_cstring' print(x, ...)## S3 method for class 'tcc_cstring' print(x, ...)
x |
A |
... |
Ignored. |
The input tcc_cstring object, invisibly. Called for its side
effect of printing the current string value.
Print tcc_ffi object
## S3 method for class 'tcc_ffi' print(x, ...)## S3 method for class 'tcc_ffi' print(x, ...)
x |
A tcc_ffi object |
... |
Ignored |
The input tcc_ffi object, invisibly. Called for its side
effect of printing the configured output mode, registered symbols,
and selected libraries/include paths.
Add a source file to a libtcc state
tcc_add_file(state, path)tcc_add_file(state, path)
state |
A |
path |
Path to a C source file. |
Integer status code (0 = success).
Add an include path to a libtcc state
tcc_add_include_path(state, path)tcc_add_include_path(state, path)
state |
A |
path |
Path to include directory. |
Integer status code (0 = success).
Add a library to a libtcc state
tcc_add_library(state, library)tcc_add_library(state, library)
state |
A |
library |
Library name (e.g., "m" for libm, "R" for libR). |
Integer status code (0 = success).
Add a library path to a libtcc state
tcc_add_library_path(state, path)tcc_add_library_path(state, path)
state |
A |
path |
Path to library directory. |
Integer status code (0 = success).
Add a symbol to a libtcc state
tcc_add_symbol(state, name, addr)tcc_add_symbol(state, name, addr)
state |
A |
name |
Symbol name. |
addr |
External pointer address or symbol value. |
Integer status code (0 = success).
Add a system include path to a libtcc state
tcc_add_sysinclude_path(state, path)tcc_add_sysinclude_path(state, path)
state |
A |
path |
Path to system include directory. |
Integer status code (0 = success).
Define symbols with Bun-style type specifications for API mode. This is the core of the declarative FFI API.
tcc_bind(ffi, ...)tcc_bind(ffi, ...)
ffi |
A tcc_ffi object |
... |
Named list of symbol definitions. Each definition is a list with:
Callback arguments should use the form |
Updated tcc_ffi object (for chaining)
ffi <- tcc_ffi() |> tcc_bind( add = list(args = list("i32", "i32"), returns = "i32"), greet = list(args = list("cstring"), returns = "cstring") )ffi <- tcc_ffi() |> tcc_bind( add = list(args = list("i32", "i32"), returns = "i32"), greet = list(args = list("cstring"), returns = "cstring") )
With no additional arguments, tcc_call_symbol() preserves its historical
quick-test behavior: call a zero-argument symbol and box an int, double,
or void return value.
tcc_call_symbol( .state, .NAME, ..., return = c("int", "double", "void"), NAOK = FALSE )tcc_call_symbol( .state, .NAME, ..., return = c("int", "double", "void"), NAOK = FALSE )
.state |
A |
.NAME |
Symbol name to call. Named |
... |
Optional arguments for |
return |
One of |
NAOK |
If |
With additional arguments, it uses an R .C()-style calling convention: the
target C function must be void, each atomic or character R argument is
copied to guarded mutable call storage and passed by pointer, and the result
is a list of the modified argument values. Supported argument mappings follow
R's .C() interface: raw as unsigned char *, integer/logical as int *,
numeric as double * or float * when attr(x, "Csingle") is true,
complex as Rcomplex *, character as char **, lists as read-only SEXP *,
and functions/environments/other R objects as read-only SEXP. Up to 65
arguments are supported. Guard bytes around copied buffers are checked after
the call to catch simple native underwrites and overwrites; character code may
edit string contents in place but must not replace char * elements in the
char ** array.
Non-atomic R objects are borrowed for the duration of the call only. C code
must not mutate them through this interface, and must call R_PreserveObject()
if it deliberately stores a SEXP beyond the call. This is a low-level
convenience interface; for typed scalar returns, explicit zero-copy arrays,
ownership metadata, and clearer signatures, prefer tcc_ffi().
For zero-argument scalar calls, the boxed return value (NULL for
void). For .C()-style calls, a list mirroring ... with any C-side
modifications copied back.
Wraps an R function so it can be passed as a C function pointer to compiled code. The callback will be invoked via a trampoline that marshals arguments between C and R.
tcc_callback(fun, signature, threadsafe = FALSE)tcc_callback(fun, signature, threadsafe = FALSE)
fun |
An R function to be called from C |
signature |
C function signature string (e.g., "double (*)(int, double)") |
threadsafe |
Whether to enable thread-safe invocation (experimental) |
Thread safety: callbacks are executed on the R main thread only. Invoking
a callback from a worker thread is unsupported and may crash R. The
threadsafe flag is currently informational only.
If a callback raises an error, a warning is emitted and a type-appropriate default value is returned.
When binding callbacks with tcc_bind(), use a callback:<signature>
argument type so a synchronous trampoline is generated. The trampoline
expects a void* user-data pointer as its first argument; pass
tcc_callback_ptr(cb) as the user-data argument to the C API. For
thread-safe usage from worker threads, use callback_async:<signature>
which schedules the call on the main thread and returns a default value.
Pointer arguments (e.g., double*, int*) are passed as
external pointers. Lengths must be supplied separately if needed.
The return type may be any scalar type supported by the FFI mappings
(e.g., i32, f64, bool, cstring), or
SEXP to return an R object directly.
Callback lifetime: callbacks are eventually released by finalizers and
package unload. Call tcc_callback_close() when you want deterministic
invalidation and earlier release of the preserved R function.
A tcc_callback object (externalptr wrapper)
Execute any pending async callbacks immediately on the main R thread. Normally callbacks fire automatically via R's event loop (input handler on POSIX, message pump on Windows), so explicit draining is only needed in test harnesses or tight batch loops that never yield to R's event loop.
tcc_callback_async_drain()tcc_callback_async_drain()
TCC-compiled C code that is known to be running on the main R thread can
call RC_callback_async_drain_c() directly instead of returning to R.
Functions bound with callback_async:* arguments are normally executed on a
worker by the generated wrapper while the main thread drains, so user code in
that target function should not assume it is itself on the main thread.
NULL (invisible)
Enqueue a callback for main-thread execution. Arguments must be basic scalars or external pointers.
tcc_callback_async_schedule(callback, args = list())tcc_callback_async_schedule(callback, args = list())
callback |
A tcc_callback object |
args |
List of arguments to pass to the callback |
NULL (invisible)
Invalidates a callback immediately, releases the preserved R function reference, and cleans up callback resources as early as possible. This is recommended for deterministic lifetime management, but callbacks are also eventually released by finalizers if you simply drop all references.
tcc_callback_close(callback)tcc_callback_close(callback)
callback |
A tcc_callback object returned by tcc_callback() |
NULL (invisible)
Returns an external pointer that can be passed to compiled C code
as user data for trampolines. Keep this handle (and the original
tcc_callback) alive for as long as C may call back.
The pointer handle keeps the underlying token storage alive until it is
garbage collected. Closing the original callback still invalidates the
callback registry entry, so C must not continue invoking it after
tcc_callback_close().
tcc_callback_ptr(callback)tcc_callback_ptr(callback)
callback |
A tcc_callback object |
Pointer arguments and return values are treated as external pointers.
Use tcc_read_bytes(), tcc_read_u8(), or tcc_read_f64()
to inspect pointed data when needed.
An external pointer (address of the callback token)
Check if callback is still valid
tcc_callback_valid(callback)tcc_callback_valid(callback)
callback |
A tcc_callback object |
Logical indicating if callback can be invoked
Compile the defined symbols into callable functions. This generates C wrapper code and compiles it with TinyCC.
tcc_compile(ffi, verbose = FALSE)tcc_compile(ffi, verbose = FALSE)
ffi |
A tcc_ffi object |
verbose |
Print compilation info |
A tcc_compiled object with callable functions
Compile C code from a character string
tcc_compile_string(state, code)tcc_compile_string(state, code)
state |
A |
code |
C source code string. |
Integer status code (0 = success).
Creates a function that recovers the parent struct pointer from a pointer to one of its members. This is the classic Linux kernel container_of macro made accessible from R.
tcc_container_of(ffi, struct_name, member_name)tcc_container_of(ffi, struct_name, member_name)
ffi |
A tcc_ffi object |
struct_name |
Struct name |
member_name |
Member field name to compute offset from |
Updated tcc_ffi object
## Not run: ffi <- tcc_ffi() |> tcc_struct("student", list(id = "i32", marks = "i32")) |> tcc_container_of("student", "marks") # Creates struct_student_from_marks() ## End(Not run)## Not run: ffi <- tcc_ffi() |> tcc_struct("student", list(id = "i32", marks = "i32")) |> tcc_container_of("student", "marks") # Creates struct_student_from_marks() ## End(Not run)
Convert R character strings to C-style null-terminated string pointers. This handles UTF-8 encoding and null termination automatically.
tcc_cstring(str)tcc_cstring(str)
str |
Character string |
An external pointer tagged "rtinycc_owned" pointing to a
malloc'd copy of the string. Freed on garbage collection or via
tcc_free().
Wrapper around a C string pointer with an optional cached R copy. Ownership follows the underlying external pointer; this wrapper does not add finalizer or freeing behavior on top of that pointer.
tcc_cstring_object(ptr, clone = TRUE, owned = FALSE)tcc_cstring_object(ptr, clone = TRUE, owned = FALSE)
ptr |
External pointer to C string |
clone |
Whether to clone the string immediately (safe for R use) |
owned |
Currently unused. Reserved for future finalizer support. |
A tcc_cstring object
Treats ptr_ref as a pointer to a pointer and returns the pointed address
as an external pointer. This is useful for fields like void** or T**.
tcc_data_ptr(ptr_ref)tcc_data_ptr(ptr_ref)
ptr_ref |
External pointer to a pointer value (e.g., address of a field). |
An external pointer tagged "rtinycc_borrowed". Not owned by
Rtinycc and never freed on garbage collection. Do not pass to
tcc_free().
Generate R-callable helpers for enum constants and type conversions. The enum must be defined in a header.
tcc_enum(ffi, name, constants = NULL, export_constants = FALSE)tcc_enum(ffi, name, constants = NULL, export_constants = FALSE)
ffi |
A tcc_ffi object |
name |
Enum name (as defined in C header) |
constants |
Character vector of constant names to export |
export_constants |
Whether to export enum constants as R functions |
Updated tcc_ffi object
## Not run: ffi <- tcc_ffi() |> tcc_header("#include <errors.h>") |> tcc_enum("error_code", constants = c("OK", "ERROR"), export_constants = TRUE) ## End(Not run)## Not run: ffi <- tcc_ffi() |> tcc_header("#include <errors.h>") |> tcc_enum("error_code", constants = c("OK", "ERROR"), export_constants = TRUE) ## End(Not run)
Initialize a Bun-style FFI context for API-mode compilation. This is the entry point for the modern FFI API.
tcc_ffi()tcc_ffi()
A tcc_ffi object with chaining support
ffi <- tcc_ffi()ffi <- tcc_ffi()
Creates functions that return pointers to specific struct fields. Useful for passing field pointers to C functions or for container_of.
tcc_field_addr(ffi, struct_name, fields)tcc_field_addr(ffi, struct_name, fields)
ffi |
A tcc_ffi object |
struct_name |
Struct name |
fields |
Character vector of field names |
Updated tcc_ffi object
## Not run: ffi <- tcc_ffi() |> tcc_struct("point", list(x = "f64", y = "f64")) |> tcc_field_addr("point", c("x", "y")) # point_x_addr(), point_y_addr() ## End(Not run)## Not run: ffi <- tcc_ffi() |> tcc_struct("point", list(x = "f64", y = "f64")) |> tcc_field_addr("point", c("x", "y")) # point_x_addr(), point_y_addr() ## End(Not run)
Free memory whose external pointer is tagged "rtinycc_owned" (e.g.
from tcc_malloc() or tcc_cstring()). Errors on struct pointers
(use the generated struct_<name>_free()) or borrowed pointers from
tcc_data_ptr().
tcc_free(ptr)tcc_free(ptr)
ptr |
External pointer to free |
NULL.
Generate bindings from header declarations
tcc_generate_bindings( ffi = NULL, header, mapper = tcc_map_c_type_to_ffi, functions = TRUE, structs = TRUE, unions = TRUE, enums = TRUE, globals = TRUE, bitfield_type = "u8", include_bitfields = TRUE )tcc_generate_bindings( ffi = NULL, header, mapper = tcc_map_c_type_to_ffi, functions = TRUE, structs = TRUE, unions = TRUE, enums = TRUE, globals = TRUE, bitfield_type = "u8", include_bitfields = TRUE )
ffi |
A tcc_ffi object. If NULL, a new one is created. |
header |
Character scalar containing C declarations. |
mapper |
Function to map C types to FFI types. |
functions |
Logical; generate |
structs |
Logical; generate |
unions |
Logical; generate |
enums |
Logical; generate |
globals |
Logical; generate |
bitfield_type |
FFI type to use for bitfields. |
include_bitfields |
Whether to include bitfields. |
Updated tcc_ffi object.
## Not run: header <- "double sqrt(double x); struct point { double x; double y; };" ffi <- tcc_generate_bindings(tcc_ffi(), header) ## End(Not run)## Not run: header <- "double sqrt(double x); struct point { double x; double y; };" ffi <- tcc_generate_bindings(tcc_ffi(), header) ## End(Not run)
Get a symbol pointer from a libtcc state
tcc_get_symbol(state, name)tcc_get_symbol(state, name)
state |
A |
name |
Symbol name to look up. |
External pointer of class tcc_symbol.
Register a global C symbol so the compiled object exposes getter/setter
functions global_<name>_get() and global_<name>_set().
tcc_global(ffi, name, type)tcc_global(ffi, name, type)
ffi |
A tcc_ffi object |
name |
Global symbol name |
type |
FFI type for the global (scalar types only) |
Globals are limited to scalar FFI types. Array types are rejected. Scalar conversions follow the same rules as wrapper arguments:
Integer inputs (i8, i16, i32, u8, u16) must be finite and
within range; NA values error.
Large integer types (i64, u32, u64) are mediated through R numeric
(double). Values must be integer-valued and within range; for i64/u64
only exact integers up to $2^53$ are accepted.
Getter wrappers for i64/u64 warn when the stored value exceeds R's
exact integer range for numeric vectors.
bool rejects NA logicals.
Ownership notes:
ptr globals store the raw address from an external pointer. If the
external pointer owns memory, keep it alive; otherwise the pointer may
be freed while the global still points to it.
cstring globals store a borrowed pointer to R's string data
(UTF-8 translation). Do not free it; for C-owned strings prefer a ptr
global and manage lifetime explicitly (e.g., with tcc_cstring()).
Updated tcc_ffi object (for chaining)
Global helpers are generated inside the compiled TCC unit. Recompiling creates a new instance of the global variable; existing compiled objects continue to refer to their own copy.
ffi <- tcc_ffi() |> tcc_source("int global_counter = 7;") |> tcc_global("global_counter", "i32") |> tcc_compile() ffi$global_global_counter_get()ffi <- tcc_ffi() |> tcc_source("int global_counter = 7;") |> tcc_global("global_counter", "i32") |> tcc_compile() ffi$global_global_counter_get()
Add C headers
tcc_header(ffi, header)tcc_header(ffi, header)
ffi |
A tcc_ffi object |
header |
Header string or include directive |
Updated tcc_ffi object (for chaining)
Add include path to FFI context
tcc_include(ffi, path)tcc_include(ffi, path)
ffi |
A tcc_ffi object |
path |
Include directory path |
Updated tcc_ffi object (for chaining)
Returns the include directories used by the bundled TinyCC (top-level include and lib/tcc/include).
tcc_include_paths() tcc_sysinclude_paths()tcc_include_paths() tcc_sysinclude_paths()
A character vector of include directories.
Generates sizeof, alignof, and offsetof helper functions for structs, unions, and enums. Useful for debugging or when you need to know C layout information from R.
tcc_introspect(ffi)tcc_introspect(ffi)
ffi |
A tcc_ffi object |
Updated tcc_ffi object
Add library to link against
tcc_library(ffi, library)tcc_library(ffi, library)
ffi |
A tcc_ffi object |
library |
Library name (e.g., "m", "sqlite3") or a path to a
shared library (e.g., "libm.so.6"). When a path or platform library file
name is provided, the library directory is added automatically and TinyCC
is asked to link that exact file name. This keeps versioned runtime
libraries such as |
Updated tcc_ffi object (for chaining)
Add library path to FFI context
tcc_library_path(ffi, path)tcc_library_path(ffi, path)
ffi |
A tcc_ffi object |
path |
Library directory path |
Updated tcc_ffi object (for chaining)
Link a system library (like libsqlite3) and generate type-safe wrappers automatically using TinyCC JIT compilation (API mode). Unlike dlopen(), this uses TinyCC to compile bindings that handle type conversion between R and C automatically.
tcc_link( path, symbols, headers = NULL, libs = character(0), lib_paths = character(0), include_paths = character(0), user_code = NULL, verbose = FALSE )tcc_link( path, symbols, headers = NULL, libs = character(0), lib_paths = character(0), include_paths = character(0), user_code = NULL, verbose = FALSE )
path |
Library short name (e.g., |
symbols |
Named list of symbol definitions with:
|
headers |
Optional C headers to include |
libs |
Library names to link (e.g., "sqlite3") |
lib_paths |
Additional library search paths |
include_paths |
Additional include search paths |
user_code |
Optional custom C code to include in the compilation |
verbose |
Print debug information |
A tcc_compiled object with callable functions
## Not run: # Link SQLite with type-safe bindings sqlite <- tcc_link( "libsqlite3.so", symbols = list( sqlite3_libversion = list(args = list(), returns = "cstring"), sqlite3_open = list(args = list("cstring", "ptr"), returns = "i32") ), libs = "sqlite3" ) # Call directly - type conversion happens automatically sqlite$sqlite3_libversion() # Example with custom user code for helper functions math_with_helpers <- tcc_link( "m", symbols = list( sqrt = list(args = list("f64"), returns = "f64"), safe_sqrt = list(args = list("f64"), returns = "f64") ), user_code = " #include <math.h> // Helper function that validates input before calling sqrt double safe_sqrt(double x) { if (x < 0) { return NAN; } return sqrt(x); } ", libs = "m" ) math_with_helpers$safe_sqrt(16.0) math_with_helpers$safe_sqrt(-4.0) # Returns NaN for negative input ## End(Not run)## Not run: # Link SQLite with type-safe bindings sqlite <- tcc_link( "libsqlite3.so", symbols = list( sqlite3_libversion = list(args = list(), returns = "cstring"), sqlite3_open = list(args = list("cstring", "ptr"), returns = "i32") ), libs = "sqlite3" ) # Call directly - type conversion happens automatically sqlite$sqlite3_libversion() # Example with custom user code for helper functions math_with_helpers <- tcc_link( "m", symbols = list( sqrt = list(args = list("f64"), returns = "f64"), safe_sqrt = list(args = list("f64"), returns = "f64") ), user_code = " #include <math.h> // Helper function that validates input before calling sqrt double safe_sqrt(double x) { if (x < 0) { return NAN; } return sqrt(x); } ", libs = "m" ) math_with_helpers$safe_sqrt(16.0) math_with_helpers$safe_sqrt(-4.0) # Returns NaN for negative input ## End(Not run)
Return the global symbols currently reported by libtcc for a state. This is
a best-effort symbol-table inspection helper for compiled/linked TCC states,
not a portable exhaustive symbol enumerator, not a DLL export scanner, and
not a C signature discovery API. Platform backends may omit symbols that are
still resolvable with tcc_get_symbol(). For meaningful runtime addresses,
call it after tcc_relocate().
tcc_list_symbols(state)tcc_list_symbols(state)
state |
A |
A data frame with columns name and address, where address is a
hexadecimal character string.
Allocate a memory buffer of specified size, equivalent to C malloc. Returns an external pointer that can be passed to FFI functions.
tcc_malloc(size)tcc_malloc(size)
size |
Number of bytes to allocate |
An external pointer tagged "rtinycc_owned" with an R finalizer.
Freed on garbage collection or explicitly via tcc_free().
Map a C type string to an Rtinycc FFI type
tcc_map_c_type_to_ffi(c_type)tcc_map_c_type_to_ffi(c_type)
c_type |
C type string (e.g., "int", "double", "char *"). |
This mapper is intentionally conservative for pointer types. char* is
treated as a raw pointer (ptr) because C does not guarantee NUL-terminated
strings. If you know the API expects a C string, map it explicitly to
cstring in your custom mapper.
A single FFI type string.
## Not run: tcc_map_c_type_to_ffi("int") tcc_map_c_type_to_ffi("const char *") ## End(Not run)## Not run: tcc_map_c_type_to_ffi("int") tcc_map_c_type_to_ffi("const char *") ## End(Not run)
Creates a NULL pointer equivalent for use with FFI functions that expect optional pointer arguments.
tcc_null_ptr()tcc_null_ptr()
An external pointer with NULL address
Append raw options that are passed to tcc_set_options() before compiling
generated wrappers (for example "-O2" or "-Wall").
tcc_options(ffi, options)tcc_options(ffi, options)
ffi |
A tcc_ffi object |
options |
Character vector of option fragments |
Updated tcc_ffi object (for chaining)
Set output type for FFI compilation
tcc_output(ffi, output = c("memory", "dll", "exe"))tcc_output(ffi, output = c("memory", "dll", "exe"))
ffi |
A tcc_ffi object |
output |
One of "memory", "dll", "exe" |
Updated tcc_ffi object (for chaining)
Returns the platform-specific tcc binary path (or tcc.exe on Windows), preferring the bundled installation.
tcc_path()tcc_path()
A character scalar path.
Helpers to locate the bundled tinycc installation after the package is installed.
tcc_prefix() tcc_lib_path() tcc_lib_paths() tcc_include_path() tcc_bin_path() tcc_cli()tcc_prefix() tcc_lib_path() tcc_lib_paths() tcc_include_path() tcc_bin_path() tcc_cli()
A character scalar path.
Get the numeric address of an external pointer, useful for debugging and when APIs require pointer addresses as integers. Optional hex mode available.
tcc_ptr_addr(ptr, hex = FALSE)tcc_ptr_addr(ptr, hex = FALSE)
ptr |
External pointer |
hex |
Whether to display in hexadecimal (default: FALSE) |
Character representation of pointer address (hex if requested, decimal otherwise)
Frees the memory pointed to by ptr_ref and sets the pointer to NULL.
Use this only when the pointed memory is not already owned by another
external pointer with its own finalizer.
tcc_ptr_free_set_null(ptr_ref)tcc_ptr_free_set_null(ptr_ref)
ptr_ref |
External pointer to a pointer value. |
The updated pointer reference (invisibly).
Returns TRUE if the external pointer address is NULL, FALSE otherwise.
tcc_ptr_is_null(ptr)tcc_ptr_is_null(ptr)
ptr |
External pointer |
Logical scalar
"rtinycc_owned" tagReturns TRUE only for pointers created by tcc_malloc() or
tcc_cstring(). Struct pointers (tagged "struct_<name>") and
borrowed pointers return FALSE.
tcc_ptr_is_owned(ptr)tcc_ptr_is_owned(ptr)
ptr |
External pointer |
Logical scalar
Assigns the address in ptr_value to the location pointed to by ptr_ref.
tcc_ptr_set(ptr_ref, ptr_value)tcc_ptr_set(ptr_ref, ptr_value)
ptr_ref |
External pointer to a pointer value (e.g., address of a field). |
ptr_value |
External pointer to store. |
The updated pointer reference (invisibly).
Generic helper functions for common FFI operations inspired by Bun's FFI. These utilities handle pointer creation, buffer management, and memory operations that are commonly needed when working with external libraries.
No return value. This is a documentation topic that groups the pointer and buffer utility functions described below.
Read a fixed number of bytes from an external pointer into a raw vector.
tcc_read_bytes(ptr, nbytes)tcc_read_bytes(ptr, nbytes)
ptr |
External pointer |
nbytes |
Number of bytes to read |
Raw vector
Convert a C-style null-terminated string pointer back to R character string. Handles UTF-8 decoding automatically.
tcc_read_cstring( ptr, max_bytes = NULL, null_action = c("na", "empty", "error") )tcc_read_cstring( ptr, max_bytes = NULL, null_action = c("na", "empty", "error") )
ptr |
External pointer to C string |
max_bytes |
Optional maximum number of bytes to read (fixed-length read). |
null_action |
Behavior when ptr is NULL: one of "na", "empty", "error".
Only effective when |
Character string, or NA/"" for NULL pointers depending on
null_action.
Read 32-bit float
tcc_read_f32(ptr, offset = 0L)tcc_read_f32(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Numeric scalar (promoted to double).
Read 64-bit doubles from a pointer
tcc_read_f64(ptr, n = NULL, offset = 0L)tcc_read_f64(ptr, n = NULL, offset = 0L)
ptr |
External pointer |
n |
Number of values to read (legacy vectorised interface).
If provided, reads |
offset |
Byte offset from |
Numeric scalar (offset form) or numeric vector (n form).
Read signed 16-bit integer
tcc_read_i16(ptr, offset = 0L)tcc_read_i16(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Integer scalar
Read signed 32-bit integers from a pointer
tcc_read_i32(ptr, n = NULL, offset = 0L)tcc_read_i32(ptr, n = NULL, offset = 0L)
ptr |
External pointer |
n |
Number of values to read (legacy vectorised interface).
If provided, reads |
offset |
Byte offset from |
Integer scalar (offset form) or integer vector (n form).
Read signed 64-bit integer
tcc_read_i64(ptr, offset = 0L)tcc_read_i64(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Numeric scalar (double, exact up to 2^53).
Read signed 8-bit integer
tcc_read_i8(ptr, offset = 0L)tcc_read_i8(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Integer scalar
Dereferences a void* at the given byte offset from ptr.
Equivalent to *(void**)(ptr + offset). The returned pointer
is tagged "rtinycc_borrowed" and will not be freed by the
garbage collector.
tcc_read_ptr(ptr, offset = 0L)tcc_read_ptr(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
External pointer
Read unsigned 16-bit integer
tcc_read_u16(ptr, offset = 0L)tcc_read_u16(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Integer scalar
Read unsigned 32-bit integer
tcc_read_u32(ptr, offset = 0L)tcc_read_u32(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Numeric scalar (double, exact up to 2^32-1).
Read unsigned 64-bit integer
tcc_read_u64(ptr, offset = 0L)tcc_read_u64(ptr, offset = 0L)
ptr |
External pointer |
offset |
Byte offset from |
Numeric scalar (double, exact up to 2^53).
Read unsigned 8-bit values from a pointer
tcc_read_u8(ptr, n = NULL, offset = 0L)tcc_read_u8(ptr, n = NULL, offset = 0L)
ptr |
External pointer |
n |
Number of values to read (legacy vectorised interface).
If provided, reads |
offset |
Byte offset from |
Integer scalar (offset form) or integer vector (n form).
Explicitly recompile from the stored FFI recipe.
Useful after deserialization (readRDS, unserialize)
or to force a fresh compilation.
tcc_recompile(compiled)tcc_recompile(compiled)
compiled |
A tcc_compiled object |
The recompiled tcc_compiled object (invisibly, same environment)
Relocate compiled code
tcc_relocate(state)tcc_relocate(state)
state |
A |
Integer status code (0 = success).
Run the tinycc CLI
tcc_run_cli(args = character(), tcc_path = check_cli_exists())tcc_run_cli(args = character(), tcc_path = check_cli_exists())
args |
Character vector of CLI arguments (e.g., |
tcc_path |
Optional path to the |
Integer status from system2().
Passes options directly to tcc_set_options() for the given state.
tcc_set_options(state, options)tcc_set_options(state, options)
state |
A |
options |
Character scalar of options (for example |
Integer status code (0 on success; negative on parse error).
Add C source code
tcc_source(ffi, code)tcc_source(ffi, code)
ffi |
A tcc_ffi object |
code |
C source code string |
Updated tcc_ffi object (for chaining)
Initialize a libtcc compilation state, optionally pointing at the bundled include/lib paths.
tcc_state( output = c("memory", "obj", "dll", "exe", "preprocess"), include_path = tcc_include_paths(), lib_path = tcc_lib_paths() )tcc_state( output = c("memory", "obj", "dll", "exe", "preprocess"), include_path = tcc_include_paths(), lib_path = tcc_lib_paths() )
output |
Output type: one of "memory", "obj", "dll", "exe", "preprocess". |
include_path |
Path(s) to headers; defaults to the bundled include dirs. |
lib_path |
Path(s) to libraries; defaults to the bundled lib dirs (lib and lib/tcc). |
An external pointer of class tcc_state.
Generate R-callable helpers for struct allocation, field access, and pointer management. The struct must be defined in a header.
tcc_struct(ffi, name, accessors)tcc_struct(ffi, name, accessors)
ffi |
A tcc_ffi object |
name |
Struct name (as defined in C header) |
accessors |
Named list of field accessors where
names are field names and values are FFI types (e.g., list(x="f64", y="f64")).
Named nested struct fields can use |
Updated tcc_ffi object
## Not run: ffi <- tcc_ffi() |> tcc_header("#include <point.h>") |> tcc_struct("point", list(x = "f64", y = "f64", id = "i32")) ## End(Not run)## Not run: ffi <- tcc_ffi() |> tcc_header("#include <point.h>") |> tcc_struct("point", list(x = "f64", y = "f64", id = "i32")) ## End(Not run)
Generates helper functions to read/write raw bytes from struct memory. Useful for bitwise operations, debugging, or manual serialization.
tcc_struct_raw_access(ffi, struct_name)tcc_struct_raw_access(ffi, struct_name)
ffi |
A tcc_ffi object |
struct_name |
Struct name |
Updated tcc_ffi object
Check if a tcc_symbol external pointer is valid
tcc_symbol_is_valid(ptr)tcc_symbol_is_valid(ptr)
ptr |
External pointer from |
TRUE if the pointer address is non-null, FALSE otherwise.
Generate bindings from a header
tcc_treesitter_bindings( header, mapper = tcc_map_c_type_to_ffi, ffi = NULL, functions = TRUE, structs = FALSE, unions = FALSE, enums = FALSE, globals = FALSE, bitfield_type = "u8", include_bitfields = TRUE )tcc_treesitter_bindings( header, mapper = tcc_map_c_type_to_ffi, ffi = NULL, functions = TRUE, structs = FALSE, unions = FALSE, enums = FALSE, globals = FALSE, bitfield_type = "u8", include_bitfields = TRUE )
header |
Character scalar containing C declarations. |
mapper |
Function to map C types to FFI types. |
ffi |
Optional |
functions |
Logical; generate |
structs |
Logical; generate |
unions |
Logical; generate |
enums |
Logical; generate |
globals |
Logical; generate |
bitfield_type |
FFI type to use for bitfields. |
include_bitfields |
Whether to include bitfields. |
Named list suitable for tcc_bind() when ffi is NULL, otherwise
an updated tcc_ffi object.
## Not run: header <- "double sqrt(double x);" symbols <- tcc_treesitter_bindings(header) ## End(Not run)## Not run: header <- "double sqrt(double x);" symbols <- tcc_treesitter_bindings(header) ## End(Not run)
Extract macro defines from a header file
tcc_treesitter_defines( file, use_cpp = TRUE, cc = treesitter.c::r_cc(), ccflags = NULL )tcc_treesitter_defines( file, use_cpp = TRUE, cc = treesitter.c::r_cc(), ccflags = NULL )
file |
Path to a header file. |
use_cpp |
Logical; use the C preprocessor if available. |
cc |
Compiler string; passed to |
ccflags |
Additional flags for the compiler. |
Character vector of macro names defined in file.
## Not run: tcc_treesitter_defines("/usr/include/math.h") ## End(Not run)## Not run: tcc_treesitter_defines("/usr/include/math.h") ## End(Not run)
Apply tcc_enum() bindings from a header
tcc_treesitter_enum_bindings(ffi, header, constants = NULL)tcc_treesitter_enum_bindings(ffi, header, constants = NULL)
ffi |
A tcc_ffi object. |
header |
Character scalar containing C declarations. |
constants |
Named list of enum constants. |
Updated tcc_ffi object.
## Not run: header <- "enum status { OK = 0, ERR = 1 };" ffi <- tcc_ffi() ffi <- tcc_treesitter_enum_bindings(ffi, header, constants = list(status = c("OK", "ERR"))) ## End(Not run)## Not run: header <- "enum status { OK = 0, ERR = 1 };" ffi <- tcc_ffi() ffi <- tcc_treesitter_enum_bindings(ffi, header, constants = list(status = c("OK", "ERR"))) ## End(Not run)
Parse enum members with treesitter.c
tcc_treesitter_enum_members(header, ...)tcc_treesitter_enum_members(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of enum members.
## Not run: header <- "enum status { OK = 0, ERR = 1 };" tcc_treesitter_enum_members(header) ## End(Not run)## Not run: header <- "enum status { OK = 0, ERR = 1 };" tcc_treesitter_enum_members(header) ## End(Not run)
Parse enum declarations with treesitter.c
tcc_treesitter_enums(header, ...)tcc_treesitter_enums(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of enum nodes.
## Not run: header <- "enum status { OK = 0, ERR = 1 };" tcc_treesitter_enums(header) ## End(Not run)## Not run: header <- "enum status { OK = 0, ERR = 1 };" tcc_treesitter_enums(header) ## End(Not run)
Parse function declarations with treesitter.c
tcc_treesitter_functions(header, ...)tcc_treesitter_functions(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of function nodes.
## Not run: header <- "double sqrt(double x);" tcc_treesitter_functions(header) ## End(Not run)## Not run: header <- "double sqrt(double x);" tcc_treesitter_functions(header) ## End(Not run)
Parse global declarations with types using treesitter.c
tcc_treesitter_global_types(header, ...)tcc_treesitter_global_types(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of global names and C types.
## Not run: header <- "int global_counter;" tcc_treesitter_global_types(header) ## End(Not run)## Not run: header <- "int global_counter;" tcc_treesitter_global_types(header) ## End(Not run)
Parse global declarations with treesitter.c
tcc_treesitter_globals(header, ...)tcc_treesitter_globals(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of global names.
## Not run: header <- "int global_counter;" tcc_treesitter_globals(header) ## End(Not run)## Not run: header <- "int global_counter;" tcc_treesitter_globals(header) ## End(Not run)
Generate tcc_struct() accessors from header structs
tcc_treesitter_struct_accessors( header, mapper = tcc_map_c_type_to_ffi, bitfield_type = "u8", include_bitfields = TRUE )tcc_treesitter_struct_accessors( header, mapper = tcc_map_c_type_to_ffi, bitfield_type = "u8", include_bitfields = TRUE )
header |
Character scalar containing C declarations. |
mapper |
Function to map C types to FFI types. |
bitfield_type |
FFI type to use for bitfields. |
include_bitfields |
Whether to include bitfields. |
Named list of accessors by struct name. Bitfields are returned as
lists with type, bitfield = TRUE, and width. Named nested struct
fields are returned as "struct:<name>"; ambiguous or anonymous nested
structs fall back to "ptr".
## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_struct_accessors(header) ## End(Not run)## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_struct_accessors(header) ## End(Not run)
Apply tcc_struct() bindings from a header
tcc_treesitter_struct_bindings(ffi, header, ...)tcc_treesitter_struct_bindings(ffi, header, ...)
ffi |
A tcc_ffi object. |
header |
Character scalar containing C declarations. |
... |
Passed to |
Updated tcc_ffi object.
## Not run: header <- "struct point { double x; double y; };" ffi <- tcc_ffi() ffi <- tcc_treesitter_struct_bindings(ffi, header) ## End(Not run)## Not run: header <- "struct point { double x; double y; };" ffi <- tcc_ffi() ffi <- tcc_treesitter_struct_bindings(ffi, header) ## End(Not run)
Parse struct members (including bitfields) with treesitter.c
tcc_treesitter_struct_members(header, ...)tcc_treesitter_struct_members(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of struct members.
## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_struct_members(header) ## End(Not run)## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_struct_members(header) ## End(Not run)
Parse struct declarations with treesitter.c
tcc_treesitter_structs(header, ...)tcc_treesitter_structs(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of struct nodes.
## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_structs(header) ## End(Not run)## Not run: header <- "struct point { double x; double y; };" tcc_treesitter_structs(header) ## End(Not run)
Generate tcc_union() accessors from header unions
tcc_treesitter_union_accessors( header, mapper = tcc_map_c_type_to_ffi, bitfield_type = "u8", include_bitfields = TRUE )tcc_treesitter_union_accessors( header, mapper = tcc_map_c_type_to_ffi, bitfield_type = "u8", include_bitfields = TRUE )
header |
Character scalar containing C declarations. |
mapper |
Function to map C types to FFI types. |
bitfield_type |
FFI type to use for bitfields. |
include_bitfields |
Whether to include bitfields. |
Named list of accessors by union name. Bitfields are returned as
lists with type, bitfield = TRUE, and width. Nested struct members
are returned as list(type = "struct", struct_name = <name>) when the
struct name is available, otherwise list(type = "struct").
## Not run: header <- "union data { int i; double d; };" tcc_treesitter_union_accessors(header) ## End(Not run)## Not run: header <- "union data { int i; double d; };" tcc_treesitter_union_accessors(header) ## End(Not run)
Apply tcc_union() bindings from a header
tcc_treesitter_union_bindings(ffi, header, ...)tcc_treesitter_union_bindings(ffi, header, ...)
ffi |
A tcc_ffi object. |
header |
Character scalar containing C declarations. |
... |
Passed to |
Updated tcc_ffi object.
## Not run: header <- "union data { int i; double d; };" ffi <- tcc_ffi() ffi <- tcc_treesitter_union_bindings(ffi, header) ## End(Not run)## Not run: header <- "union data { int i; double d; };" ffi <- tcc_ffi() ffi <- tcc_treesitter_union_bindings(ffi, header) ## End(Not run)
Parse union members with treesitter.c
tcc_treesitter_union_members(header, ...)tcc_treesitter_union_members(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of union members.
## Not run: header <- "union data { int i; double d; };" tcc_treesitter_union_members(header) ## End(Not run)## Not run: header <- "union data { int i; double d; };" tcc_treesitter_union_members(header) ## End(Not run)
Parse union declarations with treesitter.c
tcc_treesitter_unions(header, ...)tcc_treesitter_unions(header, ...)
header |
Character scalar containing C declarations. |
... |
Additional arguments passed to |
A data frame of union nodes.
## Not run: header <- "union data { int i; double d; };" tcc_treesitter_unions(header) ## End(Not run)## Not run: header <- "union data { int i; double d; };" tcc_treesitter_unions(header) ## End(Not run)
Generate R-callable helpers for union allocation and member access. The union must be defined in a header.
tcc_union(ffi, name, members, active = NULL)tcc_union(ffi, name, members, active = NULL)
ffi |
A tcc_ffi object |
name |
Union name (as defined in C header) |
members |
Named list of union members with FFI types |
active |
Default active member for accessors |
Updated tcc_ffi object
## Not run: ffi <- tcc_ffi() |> tcc_union("data_variant", members = list(as_int = "i32", as_float = "f32"), active = "as_int" ) ## End(Not run)## Not run: ffi <- tcc_ffi() |> tcc_union("data_variant", members = list(as_int = "i32", as_float = "f32"), active = "as_int" ) ## End(Not run)
Write a raw vector into memory pointed to by an external pointer.
tcc_write_bytes(ptr, raw)tcc_write_bytes(ptr, raw)
ptr |
External pointer |
raw |
Raw vector to write |
NULL.
Write a 32-bit float
tcc_write_f32(ptr, offset, value)tcc_write_f32(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
32-bit floating-point value into native memory at ptr + offset.
Write a 64-bit double
tcc_write_f64(ptr, offset, value)tcc_write_f64(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
64-bit floating-point value into native memory at ptr + offset.
Write a signed 16-bit integer
tcc_write_i16(ptr, offset, value)tcc_write_i16(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
signed 16-bit value into native memory at ptr + offset.
Write a signed 32-bit integer
tcc_write_i32(ptr, offset, value)tcc_write_i32(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
signed 32-bit value into native memory at ptr + offset.
Write a signed 64-bit integer
tcc_write_i64(ptr, offset, value)tcc_write_i64(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
signed 64-bit value into native memory at ptr + offset.
Write a signed 8-bit integer
tcc_write_i8(ptr, offset, value)tcc_write_i8(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly).
Write a pointer at byte offset
tcc_write_ptr(ptr, offset, value)tcc_write_ptr(ptr, offset, value)
ptr |
External pointer (destination buffer) |
offset |
Byte offset |
value |
External pointer to write |
NULL (invisibly).
Write an unsigned 16-bit integer
tcc_write_u16(ptr, offset, value)tcc_write_u16(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
unsigned 16-bit value into native memory at ptr + offset.
Write an unsigned 32-bit integer
tcc_write_u32(ptr, offset, value)tcc_write_u32(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
unsigned 32-bit value into native memory at ptr + offset.
Write an unsigned 64-bit integer
tcc_write_u64(ptr, offset, value)tcc_write_u64(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
unsigned 64-bit value into native memory at ptr + offset.
Write an unsigned 8-bit integer
tcc_write_u8(ptr, offset, value)tcc_write_u8(ptr, offset, value)
ptr |
External pointer |
offset |
Byte offset |
value |
Integer value to write |
NULL (invisibly). Called for its side effect of writing one
unsigned 8-bit value into native memory at ptr + offset.