x-engine-c v0.2.31
The C engine for x-lang
Loading...
Searching...
No Matches
jit.c File Reference

Non-inline wrappers for JIT-compiled code. More...

#include "x-obj.h"
#include "x-prim.h"
#include "x-type.h"
#include "x-type/buffer.h"
#include "x-type/int.h"
#include "x-type/pair.h"
#include "x-type/prim.h"
#include "x-type/ptr.h"

Functions

x_obj_t * jit_mkint (x_obj_t *p_base, long value)
 
x_obj_t * jit_mkpair (x_obj_t *p_base, x_obj_t *a, x_obj_t *b)
 
x_obj_t * jit_firstobj (x_obj_t *p)
 
x_obj_t * jit_restobj (x_obj_t *p)
 
long jit_atomint (x_obj_t *p)
 
x_obj_t * jit_eval_arg (x_obj_t *p_base, x_obj_t *p_expr)
 
x_obj_t * jit_build_args (x_obj_t *p_base, long nargs, long a0, long a1, long a2, long a3)
 
x_obj_t * jit_score_set (x_obj_t *score, long sign, x_obj_t *buffer)
 
x_obj_t * jit_score_label (x_obj_t *score, long label)
 
x_obj_t * jit_buffer_unread (x_obj_t *buffer)
 
long jit_buffer_len (x_obj_t *buffer)
 
long jit_buffer_last_char (x_obj_t *buffer)
 
x_obj_t * jit_make_prim (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_t * jit_call_value (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_t * jit_heap_run_hooks (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_t * jit_type_heap_free (x_obj_t *p_base, x_obj_t *p_args)
 
x_obj_t * jit_obj_free (x_obj_t *p_base, x_obj_t *p_args)
 

Detailed Description

Non-inline wrappers for JIT-compiled code.

These thin wrappers expose macro/inline operations as real functions that JIT code can call via dlsym + BLR.

Function Documentation

◆ jit_atomint()

long jit_atomint ( x_obj_t *  p)

Unbox an integer atom to a raw long.

Parameters
px_obj_t* – Integer atom
Returns
Raw long value

◆ jit_buffer_last_char()

long jit_buffer_last_char ( x_obj_t *  buffer)

Return the buffer's most recently read character as a raw long.

The tokenizer's delimiter handlers test the last character consumed; exposing it here lets those handlers JIT-compile through the same lane the tower's numeric analysers use, instead of running interpreted per character. Peer of jit_buffer_len (a different buffer macro, built the same way).

Parameters
bufferx_obj_t* – Token buffer object
Returns
The last-read character, as a long

◆ jit_buffer_len()

long jit_buffer_len ( x_obj_t *  buffer)

Return the current buffer length as a raw long.

Parameters
bufferx_obj_t* – Token buffer object
Returns
Buffer length

◆ jit_buffer_unread()

x_obj_t * jit_buffer_unread ( x_obj_t *  buffer)

Decrement the buffer read pointer (unread one character).

Parameters
bufferx_obj_t* – Token buffer object
Returns
The buffer (for chaining)

◆ jit_build_args()

x_obj_t * jit_build_args ( x_obj_t *  p_base,
long  nargs,
long  a0,
long  a1,
long  a2,
long  a3 
)

Build an x-lang argument list from up to 4 raw integers.

Constructs a proper list with nil as self placeholder followed by boxed integer atoms for each argument.

Parameters
p_basex_obj_t* – Base (execution context)
nargslong – Number of arguments (0..4)
a0long – First raw argument
a1long – Second raw argument
a2long – Third raw argument
a3long – Fourth raw argument
Returns
(nil arg0-atom arg1-atom ...) list

◆ jit_call_value()

x_obj_t * jit_call_value ( x_obj_t *  p_base,
x_obj_t *  p_args 
)

Call a callable the compiled code CHOSE at run time.

The lane's other calls branch to an address fixed when the code was generated – the self-call trampoline, or an fvar's prim baked as an immediate. This one takes the callee out of the argument list it was handed, which is where a computed head lands: the emitter builds (callee arg0 arg1 ...) exactly as the prim ABI wants it, so the callee is simply the first element and no second register is needed to carry it across the list construction.

THE TYPE CHECK IS THE POINT. x_primval is the object's first word; on anything that is not a PRIMITIVE that word is a length, a character, a pair – and branching to it is a SIGSEGV with no relation to the call site, the same failure the emitter's "refuse loudly at generation" rule exists to prevent. A head is only known at run time, so the refusal has to happen here. It lives in C rather than in emitted instructions because the type name it consults is the type system's business, not a layout offset the emitter should be baking in.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (callee arg0 arg1 ...), the prim ABI layout
Returns
Whatever the callee returns

◆ jit_eval_arg()

x_obj_t * jit_eval_arg ( x_obj_t *  p_base,
x_obj_t *  p_expr 
)

Evaluate an expression for JIT code.

Parameters
p_basex_obj_t* – Base (execution context)
p_exprx_obj_t* – Expression to evaluate
Returns
Evaluation result

◆ jit_firstobj()

x_obj_t * jit_firstobj ( x_obj_t *  p)

Extract the first element of a pair.

Parameters
px_obj_t* – Pair object
Returns
First element

◆ jit_heap_run_hooks()

x_obj_t * jit_heap_run_hooks ( x_obj_t *  p_base,
x_obj_t *  p_args 
)

Fire each hook on a hook list: the free hooks ahead of a sweep, or the mark hooks ahead of a mark. Arguments: (hooks). Types: (object).

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – Argument run: (hooks), a hook list from the base's heap fields
Returns
NULL

◆ jit_make_prim()

x_obj_t * jit_make_prim ( x_obj_t *  p_base,
x_obj_t *  p_args 
)

Create a proper x-lang prim callable from a JIT function address.

Registered as an x-lang primitive so the return value flows through dispatch and is usable as a normal x-lang value.

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – (self fn-addr-ptr)
Returns
New prim object wrapping the JIT function

◆ jit_mkint()

x_obj_t * jit_mkint ( x_obj_t *  p_base,
long  value 
)

Allocate an integer atom for JIT code.

Parameters
p_basex_obj_t* – Base (execution context)
valuelong – Integer value
Returns
New integer object

◆ jit_mkpair()

x_obj_t * jit_mkpair ( x_obj_t *  p_base,
x_obj_t *  a,
x_obj_t *  b 
)

Allocate a pair for JIT code.

Parameters
p_basex_obj_t* – Base (execution context)
ax_obj_t* – First element
bx_obj_t* – Rest element
Returns
New pair object

◆ jit_obj_free()

x_obj_t * jit_obj_free ( x_obj_t *  p_base,
x_obj_t *  p_args 
)

Free an object the engine's allocator made: its owned payload, its allocation and the base's allocation count. Arguments: (object). Types: (object).

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – Argument run: (object), unlinked from the chain
Returns
NULL

◆ jit_restobj()

x_obj_t * jit_restobj ( x_obj_t *  p)

Extract the rest element of a pair.

Parameters
px_obj_t* – Pair object
Returns
Rest element

◆ jit_score_label()

x_obj_t * jit_score_label ( x_obj_t *  score,
long  label 
)

Declare the LABEL an analyser accepted – written into the label cell x_token_analyse hangs off the score's rest, and handed to the type's reader as its second argument (x-token.h). Peer of jit_score_set: the other half of the score cell, written in the same three lines.

Parameters
scorex_obj_t* – Score cell (its rest is the label cell)
labellong – The label, a non-zero integer of the type's choosing
Returns
The score cell

◆ jit_score_set()

x_obj_t * jit_score_set ( x_obj_t *  score,
long  sign,
x_obj_t *  buffer 
)

Set a tokenizer score to sign * buffer-length.

Parameters
scorex_obj_t* – Score integer atom (mutated in place)
signlong – Sign multiplier (+1 or -1)
bufferx_obj_t* – Token buffer object
Returns
The score atom

◆ jit_type_heap_free()

x_obj_t * jit_type_heap_free ( x_obj_t *  p_base,
x_obj_t *  p_args 
)

Run an object's type-specific free hook, if its type has one. Arguments: (object). Types: (object).

Parameters
p_basex_obj_t* – Base (execution context)
p_argsx_obj_t* – Argument run: (object), the object about to be freed
Returns
NULL