Skip to content

Commit eb6b219

Browse files
committed
second pass at 'precious_{preserve,remove}'
1 parent f4342ae commit eb6b219

File tree

9 files changed

+281
-91
lines changed

9 files changed

+281
-91
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: Rcpp
22
Title: Seamless R and C++ Integration
3-
Version: 1.0.6
4-
Date: 2021-01-14
3+
Version: 1.0.6.1
4+
Date: 2021-01-17
55
Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Qiang Kou,
66
Nathan Russell, Douglas Bates and John Chambers
77
Maintainer: Dirk Eddelbuettel <edd@debian.org>

inst/include/Rcpp/String.h

Lines changed: 170 additions & 45 deletions
Large diffs are not rendered by default.

inst/include/Rcpp/config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define RCPP_VERSION_STRING "1.0.6"
3131

3232
// the current source snapshot
33-
#define RCPP_DEV_VERSION RcppDevVersion(1,0,6,0)
34-
#define RCPP_DEV_VERSION_STRING "1.0.6.0"
33+
#define RCPP_DEV_VERSION RcppDevVersion(1,0,6,1)
34+
#define RCPP_DEV_VERSION_STRING "1.0.6.1"
3535

3636
#endif

inst/include/Rcpp/routines.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ namespace Rcpp{
3838
}
3939
double mktime00(struct tm &);
4040
struct tm * gmtime_(const time_t * const);
41+
42+
void Rcpp_precious_init();
43+
void Rcpp_precious_teardown();
44+
SEXP Rcpp_precious_preserve(SEXP object);
45+
void Rcpp_precious_remove(SEXP token);
4146
}
4247

4348
SEXP rcpp_get_stack_trace();
@@ -127,6 +132,27 @@ namespace Rcpp {
127132
return fun(x);
128133
}
129134

135+
inline attribute_hidden void Rcpp_precious_init() {
136+
typedef void (*Fun)(void);
137+
static Fun fun = GET_CALLABLE("Rcpp_precious_init");
138+
fun();
139+
}
140+
inline attribute_hidden void Rcpp_precious_teardown() {
141+
typedef void (*Fun)(void);
142+
static Fun fun = GET_CALLABLE("Rcpp_precious_teardown");
143+
fun();
144+
}
145+
inline attribute_hidden SEXP Rcpp_precious_preserve(SEXP object) {
146+
typedef SEXP (*Fun)(SEXP);
147+
static Fun fun = GET_CALLABLE("Rcpp_precious_preserve");
148+
return fun(object);
149+
}
150+
inline attribute_hidden void Rcpp_precious_remove(SEXP token) {
151+
typedef void (*Fun)(SEXP);
152+
static Fun fun = GET_CALLABLE("Rcpp_precious_remove");
153+
fun(token);
154+
}
155+
130156
}
131157

132158
// The 'attribute_hidden' used here is a simple precessor defined from

inst/include/Rcpp/storage/PreserveStorage.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@ namespace Rcpp{
77
class PreserveStorage {
88
public:
99

10-
PreserveStorage() : data(R_NilValue){}
10+
PreserveStorage() : data(R_NilValue), token(R_NilValue){}
1111

1212
~PreserveStorage(){
13-
Rcpp_ReleaseObject(data) ;
13+
Rcpp_ReleaseObject(token) ;
1414
data = R_NilValue;
15+
token = R_NilValue;
1516
}
1617

1718
inline void set__(SEXP x){
18-
data = Rcpp_ReplaceObject(data, x) ;
19+
if (data != x) {
20+
data = x;
21+
Rcpp_ReleaseObject(token);
22+
token = Rcpp_PreserveObject(data);
23+
}
1924

2025
// calls the update method of CLASS
2126
// this is where to react to changes in the underlying SEXP
@@ -28,7 +33,9 @@ namespace Rcpp{
2833

2934
inline SEXP invalidate__(){
3035
SEXP out = data ;
36+
Rcpp_ReleaseObject(token);
3137
data = R_NilValue ;
38+
token = R_NilValue ;
3239
return out ;
3340
}
3441

@@ -48,6 +55,7 @@ namespace Rcpp{
4855

4956
private:
5057
SEXP data ;
58+
SEXP token ;
5159
} ;
5260

5361
}

inst/include/Rcpp/traits/named_object.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,22 @@ template <typename T> class named_object {
4141
template <> class named_object<SEXP> {
4242
public: // #nocov start
4343
named_object( const std::string& name_, const SEXP& o_):
44-
name(name_), object(o_) {
45-
R_PreserveObject(object);
44+
name(name_), object(o_), token(R_NilValue) {
45+
token = Rcpp_precious_preserve(object);
4646
}
4747

4848
named_object( const named_object<SEXP>& other ) :
49-
name(other.name), object(other.object) {
50-
R_PreserveObject(object);
49+
name(other.name), object(other.object), token(other.token) {
50+
token = Rcpp_precious_preserve(object);
5151
}
5252
~named_object() {
53-
R_ReleaseObject(object);
53+
Rcpp_precious_remove(token);
54+
5455
} // #nocov end
5556
const std::string& name;
5657
SEXP object;
58+
private:
59+
SEXP token;
5760
};
5861

5962

inst/include/RcppCommon.h

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ namespace Rcpp {
7777
SEXP Rcpp_fast_eval(SEXP expr_, SEXP env);
7878
SEXP Rcpp_eval(SEXP expr_, SEXP env = R_GlobalEnv);
7979

80+
SEXP Rcpp_precious_preserve(SEXP object);
81+
void Rcpp_precious_remove(SEXP token);
82+
8083
namespace internal {
8184
SEXP Rcpp_eval_impl(SEXP expr, SEXP env);
8285
}
@@ -87,28 +90,12 @@ namespace Rcpp {
8790
template <typename T> class named_object;
8891
}
8992

90-
inline SEXP Rcpp_PreserveObject(SEXP x) {
91-
if (x != R_NilValue) {
92-
R_PreserveObject(x);
93-
}
94-
return x;
95-
}
96-
97-
inline void Rcpp_ReleaseObject(SEXP x) {
98-
if (x != R_NilValue) {
99-
R_ReleaseObject(x);
100-
}
93+
inline SEXP Rcpp_PreserveObject(SEXP object) {
94+
return Rcpp_precious_preserve(object);
10195
}
10296

103-
inline SEXP Rcpp_ReplaceObject(SEXP x, SEXP y) {
104-
105-
// if we are setting to the same SEXP as we already have, do nothing
106-
if (x != y) {
107-
Rcpp_ReleaseObject(x);
108-
Rcpp_PreserveObject(y);
109-
}
110-
111-
return y;
97+
inline void Rcpp_ReleaseObject(SEXP token) {
98+
Rcpp_precious_remove(token);
11299
}
113100

114101
}

src/barrier.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*-
2-
//
31
// barrier.cpp: Rcpp R/C++ interface class library -- write barrier
42
//
5-
// Copyright (C) 2010 - 2019 Dirk Eddelbuettel and Romain Francois
3+
// Copyright (C) 2010 - 2020 Dirk Eddelbuettel and Romain Francois
64
//
75
// This file is part of Rcpp.
86
//
@@ -88,6 +86,46 @@ static SEXP Rcpp_cache = R_NilValue;
8886
#define RCPP_HASH_CACHE_INITIAL_SIZE 1024
8987
#endif
9088

89+
namespace Rcpp {
90+
static SEXP Rcpp_precious = R_NilValue;
91+
// [[Rcpp::register]]
92+
void Rcpp_precious_init() {
93+
Rcpp_precious = CONS(R_NilValue, R_NilValue); // set up
94+
R_PreserveObject(Rcpp_precious); // and protect
95+
}
96+
// [[Rcpp::register]]
97+
void Rcpp_precious_teardown() {
98+
R_ReleaseObject(Rcpp_precious); // release resource
99+
}
100+
// [[Rcpp::register]]
101+
SEXP Rcpp_precious_preserve(SEXP object) {
102+
if (object == R_NilValue) {
103+
return R_NilValue;
104+
}
105+
PROTECT(object);
106+
SEXP cell = PROTECT(CONS(Rcpp_precious, CDR(Rcpp_precious)));
107+
SET_TAG(cell, object);
108+
SETCDR(Rcpp_precious, cell);
109+
if (CDR(cell) != R_NilValue) {
110+
SETCAR(CDR(cell), cell);
111+
}
112+
UNPROTECT(2);
113+
return cell;
114+
}
115+
// [[Rcpp::register]]
116+
void Rcpp_precious_remove(SEXP token) {
117+
if (token == R_NilValue) {
118+
return;
119+
}
120+
SEXP before = CAR(token);
121+
SEXP after = CDR(token);
122+
SETCDR(before, after);
123+
if (after != R_NilValue) {
124+
SETCAR(after, before);
125+
}
126+
}
127+
}
128+
91129
// only used for debugging
92130
SEXP get_rcpp_cache() {
93131
if (! Rcpp_cache_know) {

src/rcpp_init.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2-
//
31
// Rcpp_init.cpp : Rcpp R/C++ interface class library -- Initialize and register
42
//
5-
// Copyright (C) 2010 - 2017 John Chambers, Dirk Eddelbuettel and Romain Francois
3+
// Copyright (C) 2010 - 2020 John Chambers, Dirk Eddelbuettel and Romain Francois
64
//
75
// This file is part of Rcpp.
86
//
@@ -121,22 +119,27 @@ void registerFunctions(){
121119
RCPP_REGISTER(error_occured)
122120
RCPP_REGISTER(rcpp_get_current_error)
123121
// RCPP_REGISTER(print)
122+
RCPP_REGISTER(Rcpp_precious_init)
123+
RCPP_REGISTER(Rcpp_precious_teardown)
124+
RCPP_REGISTER(Rcpp_precious_preserve)
125+
RCPP_REGISTER(Rcpp_precious_remove)
124126
#undef RCPP_REGISTER
125127
}
126128

127-
128-
extern "C" void R_unload_Rcpp(DllInfo *) { // #nocov start
129-
// Release resources
130-
} // #nocov end
129+
extern "C" void R_unload_Rcpp(DllInfo *) { // #nocov start
130+
Rcpp::Rcpp_precious_teardown(); // release resource
131+
} // #nocov end
131132

132133
extern "C" void R_init_Rcpp(DllInfo* dllinfo) {
133134
setCurrentScope(0);
134135

135-
registerFunctions(); // call wrapper to register export symbols
136+
registerFunctions(); // call wrapper to register export symbols
137+
138+
R_useDynamicSymbols(dllinfo, FALSE); // set up symbol symbol lookup (cf R 3.4.0)
136139

137-
R_useDynamicSymbols(dllinfo, FALSE); // set up symbol symbol lookup (cf R 3.4.0)
140+
init_Rcpp_cache(); // init the cache
138141

139-
init_Rcpp_cache(); // init the cache
142+
Rcpp::Rcpp_precious_init();
140143

141-
init_Rcpp_routines(dllinfo); // init routines
144+
init_Rcpp_routines(dllinfo); // init routines
142145
}

0 commit comments

Comments
 (0)