SEXP
pointers. These functions are listed in
the following table:
Attributes SET_ATTRIB(x,i,v)
Strings and Vectors SET_STRING_ELT(x,i,v)
,SET_VECTOR_ELT(x,i,v)
Lists SET_TAG(x,v)
,SETCAR(x,v)
,SETCDR(x,v)
SETCADR(x,v)
,SETCADDR(x,v)
,SETCADDDR(x,v)
SETCAD4R(x,v)
Closures SET_FORMALS(x,v)
,SET_BODY(x,v)
,SET_CLOENV(x,v)
Symbols SET_PRINTNAME(x,v)
,SET_SYMVALUE(x,v)
,SET_INTERNAL(x,v)
Environments SET_FRAME(x,v)
,SET_ENCLOS(x,v)
,SET_HASHTAB(x,v)
Promises SET_PREXPR(x,v)
,SET_PRENV(x,v)
,SET_PRVALUE(x,v)
Assignments must only be made through these functions.
Rinternals.h
will see SEXP
's as opaque
pointers and only be able to access SEXPREC
fields through
functions. (This can be circumvented by defining USE_RINTERNALS
before the include statement, but doing this should be strongly
discouraged.)
Ordinarily files that include Defn.h
will be able to access
internal fields of SEXPREC
's directly. This improves performance
(by about 10%I believe on the base tests) but it comes at the risk
of violating the write barrier. To check that the write barrier is
intact, define TESTING_WRITE_BARRIER
in Defn.h
. When
TESTING_WRITE_BARRIER
is defined, only files that explicitly
define USE_RINTERNALS
will be able to access SEXPREC
fields
directly (for the generational collector this should only be
memory.c
). All other files see SEXP
's as opaque pointers that
must be accessed by functions. Using old-style assignments of the
form
CAR(x) = vwill produce compiler errors.
STRSXP
's
and VECSXP
's. This is done using the macros/functions
STRING_PTR
and VECTOR_PTR
.
The VECTOR_PTR
function/macro is only used in one place, in
RObjToCPtr
in dotcode.c
. I'm not usre if this is needed; if
it is not it should be dropped. If it is, it has to be used with
extreme caution since changing the values referenced can damage the
integrity of the heap.
STRING_PTR
is currently used in around 20 places. Most look safe;
many have to do with sorting. It would be a good idea to replace all by
accesses via STRING_ELT
and SET_STRING_ELT
.
STRSXP
data consists of a vector of SEXP]'s. To change
this to a [[char **
, which would be more convenient for the C code
interface, two steps are needed:
STRING_PTR
STRING_ELT
and SET_STRING_ELT
to set the data
value to the CHAR
address for the CHARSXP
and to retrieve the
CHARSXP
by stepping back from theCHAR
pointer stored.