What exactly needs to be PROTECTed when writing C functions for use in R -
i thought pretty straightforward, basically, sexp
type objects create in c code must protected, starts getting little murkier (to me) when using linked lists , car
/ cdr
, etc. started off comment in writing r extensions:
protecting r object automatically protects r objects pointed in corresponding sexprec, illustration elements of protected list automatically protected.
and r internals:
a sexprec c construction containing 32-bit header described above, 3 pointers (to attributes, previous , next node) , node info ...
listsxp: pointers car, cdr (usually listsxp or null) , tag (a symsxp or null).
so interpret mean that, if like:
sexp s, t, u; protect(s = alloclist(2)); setcar(s, scalarlogical(1)); setcadr(s, scalarlogical(0)); t = car(s); u = cadr(s);
then t
, u
protected virtue of beingness pointers objects within protected list s
(corollary question: there way protected status of object? couldn't see in rinternals.h fit bill). yet see stuff (from src/main/unique.c
):
// starting on line 1274 (r 3.0.2), note `args` protected virtue of beingness // function argument sexp attribute_hidden do_matchcall(sexp call, sexp op, sexp args, sexp env) { // ommitting bunch of lines, , then, on line 1347: protect(b = car(args)); // ... }
this suggests objects within args
not protected, seems odd since of args
objects have gotten gced @ point. since car
returns pointer presumably protected object, why need protect here?
think way: protect
doesn't object. rather, adds temporary gc root object considered live collector. objects contains alive, not because of protection applied c, because pointed-to object already considered live - same other normal live object. setting auto of protected list not keeps object alive, potentially releases whatever in auto gc, removing particular live tree (protecting list didn't recursively impact elements).
so in general aren't going have easy way of telling whether object "protected" or not in wider sense, because it's next same rules gc elsewhere , there's nil special object. potentially trace through entire protect
list , see if find it, be... inefficient, to the lowest degree (there's nil ownership tree leading object in question 1 on protect
list 1 maintain live longest).
the line in do_matchcall
there unrelated reason: protecting car(args)
happens in 1 branch of conditional - in other branch, it's newly-created object gets protected. redundantly protecting value branch means there's guaranteed same number of objects on protect
stack regardless of branch taken, simplifies corresponding unprotect
@ end of function operation on constant number of slots (no need replicate check downwards there vary it).
c r garbage-collection
No comments:
Post a Comment