Next: objects ports, Previous: objects compnums, Up: objects [Index]
Cflonums are complex numbers having a flonum as real part and flonum as imaginary part. A cflonum is a fixed length memory block referenced by machine words tagged as vectors. The first machine word of a cflonum block is tagged has cflonum in its least significant bits and it has the most significant bits set to zero.
|------------------------|-------------| reference to cflonum heap pointer vector tag |------------------------|-------------| cflonum first word all set to zero cflonum tag
A cflonum memory block is 4 words wide; a reference to the real part is stored in the second word and a reference to the imaginary part is stored in the third word
1st word 2nd word 3rd word 4th word |------------|------------|------------|------------| tagged word real part imag part unused
Cflonums are allocated on the Scheme heap as follows:
ikpcb_t * pcb = ik_the_pcb(); ikptr_t s_cf; s_cf = ik_safe_alloc(pcb, cflonum_size) | vector_tag; IK_CFLONUM_TAG(s_cf) = cflonum_tag;
after allocation we must always initialise the real and imaginary parts to some correct value before running the next garbage collection; a full allocation and initialisation is as follows:
ikpcb_t * pcb = ik_the_pcb(); ikptr_t s_re = the_real; ikptr_t s_im = the_imag; ikptr_t s_cf; pcb->root9 = &s_re; pcb->root8 = &s_im; { s_rn = ik_safe_alloc(pcb, cflonum_size) | vector_tag; } pcb->root8 = NULL; pcb->root9 = NULL; IK_CFLONUM_TAG(s_cf) = cflonum_tag; IK_CFLONUM_REP(s_cf) = s_re; IK_CFLONUM_IMP(s_cf) = s_im;
notice that, as in this example, when a new cflonum object is allocated
after the allocation of the real and imaginary objects: we do not need
to call ik_signal_dirt_in_page_of_pointer()
for s_cf because
the cflonum is on the Scheme heap’s nursery, so it will for sure be
scanned at the next garbage collection.
If we allocate the cflonum object first, then the real and imaginary objects, we want to follow this pattern:
ikpcb_t * pcb = ik_the_pcb(); double rep = the_real_part; double imp = the_imag_part; ikptr_t s_cf = ik_safe_alloc(pcb, cflonum_size) | vector_tag; IK_CFLONUM_TAG(s_cf) = cflonum_tag; pcb->root9 = &s_cf; { IK_ASS(IK_CFLONUM_REAL(s_cf), \ ika_flonum_from_double(pcb, rep)); IK_SIGNAL_DIRT(pcb, IK_CFLONUM_REAL_PTR(s_cf)); IK_ASS(IK_CFLONUM_IMAG(s_cf), \ ika_flonum_from_double(pcb, imp)); IK_SIGNAL_DIRT(pcb, IK_CFLONUM_IMAG_PTR(s_cf)); } pcb->root9 = NULL;
or:
ikpcb_t * pcb = ik_the_pcb(); double rep = the_real_part; double imp = the_imag_part; ikptr_t s_cf = ika_cflonum_from_doubles(pcb, rep, imp);
To set or retrieve the real and imaginary parts we do:
ikptr_t s_cf = the_cflonum; ikptr_t s_re; ikptr_t s_im; s_re = IK_CFLONUM_REAL(s_cf); s_im = IK_CFLONUM_IMAG(s_cf); IK_CFLONUM_REAL(s_cf) = s_re; IK_SIGNAL_DIRT(pcb, IK_CFLONUM_REAL_PTR(s_cf)); IK_CFLONUM_IMAG(s_cf) = s_im; IK_SIGNAL_DIRT(pcb, IK_CFLONUM_IMAG_PTR(s_cf));
The number of bytes to allocate to hold a cflonum memory block.
The tag of ikptr_t
values used as first words in cflonum memory blocks.
Displacement of secondary tag word. The number of bytes to add to an untagged pointer to cflonum to get the pointer to the first byte in the word holding the cflonum tag.
Displacements of real and imaginary parts. The number of bytes to add to an untagged pointer to cflonum to get the pointer to the first byte of the reference to the real or imaginary part.
An integer to add to add to a tagged ikptr_t
pointer to cflonum to get
the pointer to the first byte in the word holding the cflonum tag.
An integer to add to a tagged ikptr_t
pointer to cflonum to get the
pointer to the first byte of the words referencing the real or
imaginary part.
Return true if obj is a cflonum object; otherwise return false.
Evaluate to the location of the real and imaginary parts in the cflonum memory block; X must be a tagged pointer to cflonum object. A use of these macros can appear both as operand and as left–side of an assignment:
ikptr_t s_cf = the_cflonum; ikptr_t s_re; s_re = IK_CFLONUM_REAL(s_cf); IK_CFLONUM_REAL(s_cf) = s_re; IK_SIGNAL_DIRT(pcb, s_cf);
Evaluate to a pointer to the real and imaginary parts in the cflonum
memory block; X must be a tagged pointer to cflonum object. These
macros are useful to build the second argument to calls to
ik_signal_dirt_in_page_of_pointer()
.
Return true if obj is a cflonum object.
Allocate a cflonum and its flonum components using
ik_unsafe_alloc()
and return a tagged reference to it. No garbage
collection is run while this function is evaluating.
Allocate a cflonum and its flonum components using ik_safe_alloc()
and return a tagged reference to it. This function makes use of
pcb->root9
.
This function takes care of calling
ik_signal_dirt_in_page_of_pointer()
when appropriate.
Next: objects ports, Previous: objects compnums, Up: objects [Index]