Skip to content

Commit 8b7f075

Browse files
Revert "avoid need for R_NilValue checks in protect code (#285)"
This reverts commit dae1b6a.
1 parent 1bb6e3e commit 8b7f075

File tree

1 file changed

+26
-30
lines changed

1 file changed

+26
-30
lines changed

inst/include/cpp11/protect.hpp

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -328,18 +328,16 @@ static struct {
328328

329329
static SEXP list_ = get_preserve_list();
330330

331-
// Get references to head, tail of the precious list.
332-
SEXP head = list_;
333-
SEXP tail = CDR(list_);
331+
// Add a new cell that points to the previous end.
332+
SEXP cell = PROTECT(Rf_cons(list_, CDR(list_)));
334333

335-
// Add a new cell that points to the current head + tail.
336-
SEXP cell = PROTECT(Rf_cons(head, tail));
337334
SET_TAG(cell, obj);
338335

339-
// Update the head + tail to point at the newly-created cell,
340-
// effectively inserting that cell between the current head + tail.
341-
SETCDR(head, cell);
342-
SETCAR(tail, cell);
336+
SETCDR(list_, cell);
337+
338+
if (CDR(cell) != R_NilValue) {
339+
SETCAR(CDR(cell), cell);
340+
}
343341

344342
UNPROTECT(2);
345343

@@ -367,25 +365,29 @@ static struct {
367365
#endif
368366
}
369367

370-
void release(SEXP cell) {
371-
if (cell == R_NilValue) {
368+
void release(SEXP token) {
369+
if (token == R_NilValue) {
372370
return;
373371
}
374372

375373
#ifdef CPP11_USE_PRESERVE_OBJECT
376-
R_ReleaseObject(cell);
374+
R_ReleaseObject(token);
377375
return;
378376
#endif
379377

380-
// Get a reference to the cells before and after the token.
381-
SEXP lhs = CAR(cell);
382-
SEXP rhs = CDR(cell);
378+
SEXP before = CAR(token);
379+
380+
SEXP after = CDR(token);
381+
382+
if (before == R_NilValue && after == R_NilValue) {
383+
Rf_error("should never happen");
384+
}
385+
386+
SETCDR(before, after);
383387

384-
// Remove the cell from the precious list -- effectively, we do this
385-
// by updating the 'lhs' and 'rhs' references to point at each-other,
386-
// effectively removing any references to the cell in the pairlist.
387-
SETCDR(lhs, rhs);
388-
SETCAR(rhs, lhs);
388+
if (after != R_NilValue) {
389+
SETCAR(after, before);
390+
}
389391
}
390392

391393
private:
@@ -425,24 +427,18 @@ static struct {
425427

426428
static SEXP get_preserve_list() {
427429
static SEXP preserve_list = R_NilValue;
430+
428431
if (TYPEOF(preserve_list) != LISTSXP) {
429432
preserve_list = get_preserve_xptr_addr();
430433
if (TYPEOF(preserve_list) != LISTSXP) {
431-
preserve_list = Rf_cons(R_NilValue, Rf_cons(R_NilValue, R_NilValue));
434+
preserve_list = Rf_cons(R_NilValue, R_NilValue);
432435
R_PreserveObject(preserve_list);
433436
set_preserve_xptr(preserve_list);
434437
}
435-
436-
// NOTE: Because older versions of cpp11 (<= 0.4.2) initialized the
437-
// precious_list with a single cell, we might need to detect and update
438-
// an existing empty precious list so that we have a second cell following.
439-
if (CDR(preserve_list) == R_NilValue)
440-
SETCDR(preserve_list, Rf_cons(R_NilValue, R_NilValue));
441438
}
442439

443440
return preserve_list;
444441
}
445-
446-
} preserved;
447-
442+
} // namespace cpp11
443+
preserved;
448444
} // namespace cpp11

0 commit comments

Comments
 (0)