Skip to content

Commit cb8c52a

Browse files
authored
Avoid c++ in unwind protect (#81)
1 parent b938247 commit cb8c52a

File tree

7 files changed

+30
-14
lines changed

7 files changed

+30
-14
lines changed

inst/include/cpp11/doubles.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,23 @@ inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
8080
: cpp11::r_vector<double>(safe[Rf_allocVector](REALSXP, il.size())),
8181
capacity_(il.size()) {
8282
protect_ = protect_sexp(data_);
83+
int n_protected = 0;
8384

8485
try {
8586
unwind_protect([&] {
8687
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
8788
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
89+
++n_protected;
8890
auto it = il.begin();
8991
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
9092
data_p_[i] = REAL_ELT(it->value(), 0);
9193
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
9294
}
93-
UNPROTECT(1);
95+
UNPROTECT(n_protected);
9496
});
9597
} catch (const unwind_exception& e) {
9698
release_protect(protect_);
97-
UNPROTECT(1);
99+
UNPROTECT(n_protected);
98100
throw e;
99101
}
100102
}

inst/include/cpp11/environment.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class environment {
3131

3232
template <typename T>
3333
proxy& operator=(T value) {
34-
unwind_protect([&] { Rf_defineVar(name_, as_sexp(value), parent_); });
34+
safe[Rf_defineVar](name_, as_sexp(value), parent_);
3535
return *this;
3636
}
3737
operator SEXP() const { return safe[Rf_findVarInFrame3](parent_, name_, TRUE); };

inst/include/cpp11/integers.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,23 @@ inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
9797
: cpp11::r_vector<int>(safe[Rf_allocVector](INTSXP, il.size())),
9898
capacity_(il.size()) {
9999
protect_ = protect_sexp(data_);
100+
int n_protected = 0;
100101

101102
try {
102103
unwind_protect([&] {
103104
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
104105
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
106+
++n_protected;
105107
auto it = il.begin();
106108
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
107109
data_p_[i] = INTEGER_ELT(it->value(), 0);
108110
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
109111
}
110-
UNPROTECT(1);
112+
UNPROTECT(n_protected);
111113
});
112114
} catch (const unwind_exception& e) {
113115
release_protect(protect_);
114-
UNPROTECT(1);
116+
UNPROTECT(n_protected);
115117
throw e;
116118
}
117119
}

inst/include/cpp11/list.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,24 @@ template <>
8686
inline r_vector<SEXP>::r_vector(std::initializer_list<named_arg> il)
8787
: cpp11::r_vector<SEXP>(safe[Rf_allocVector](VECSXP, il.size())),
8888
capacity_(il.size()) {
89+
protect_ = protect_sexp(data_);
90+
int n_protected = 0;
91+
8992
try {
9093
unwind_protect([&] {
91-
protect_ = protect_sexp(data_);
9294
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
93-
sexp nms(names());
95+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
96+
++n_protected;
9497
auto it = il.begin();
9598
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
9699
SET_VECTOR_ELT(data_, i, it->value());
97-
SET_STRING_ELT(nms, i, Rf_mkCharCE(it->name(), CE_UTF8));
100+
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
98101
}
102+
UNPROTECT(n_protected);
99103
});
100104
} catch (const unwind_exception& e) {
101105
release_protect(protect_);
106+
UNPROTECT(n_protected);
102107
throw e;
103108
}
104109
}

inst/include/cpp11/logicals.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,23 @@ inline r_vector<Rboolean>::r_vector(std::initializer_list<named_arg> il)
8383
: cpp11::r_vector<Rboolean>(safe[Rf_allocVector](LGLSXP, il.size())),
8484
capacity_(il.size()) {
8585
protect_ = protect_sexp(data_);
86+
int n_protected = 0;
8687

8788
try {
8889
unwind_protect([&] {
8990
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
9091
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
92+
++n_protected;
9193
auto it = il.begin();
9294
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
9395
data_p_[i] = static_cast<Rboolean>(LOGICAL_ELT(it->value(), 0));
9496
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
9597
}
96-
UNPROTECT(1);
98+
UNPROTECT(n_protected);
9799
});
98100
} catch (const unwind_exception& e) {
99101
release_protect(protect_);
100-
UNPROTECT(1);
102+
UNPROTECT(n_protected);
101103
throw e;
102104
}
103105
}

inst/include/cpp11/raws.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,24 @@ inline r_vector<uint8_t>::r_vector(std::initializer_list<named_arg> il)
9090
: cpp11::r_vector<uint8_t>(safe[Rf_allocVector](RAWSXP, il.size())),
9191
capacity_(il.size()) {
9292
protect_ = protect_sexp(data_);
93+
int n_protected = 0;
9394

9495
try {
9596
unwind_protect([&] {
9697
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
9798
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
99+
++n_protected;
100+
98101
auto it = il.begin();
99102
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
100103
data_p_[i] = RAW_ELT(it->value(), 0);
101104
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
102105
}
103-
UNPROTECT(1);
106+
UNPROTECT(n_protected);
104107
});
105108
} catch (const unwind_exception& e) {
106109
release_protect(protect_);
107-
UNPROTECT(1);
110+
UNPROTECT(n_protected);
108111
throw e;
109112
}
110113
}

inst/include/cpp11/strings.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,23 @@ inline r_vector<r_string>::r_vector(std::initializer_list<named_arg> il)
125125
: cpp11::r_vector<r_string>(safe[Rf_allocVector](STRSXP, il.size())),
126126
capacity_(il.size()) {
127127
protect_ = protect_sexp(data_);
128+
int n_protected = 0;
128129

129130
try {
130131
unwind_protect([&] {
131132
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
132133
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
134+
++n_protected;
133135
auto it = il.begin();
134136
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
135137
SET_STRING_ELT(data_, i, STRING_ELT(it->value(), 0));
136138
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
137139
}
138-
UNPROTECT(1);
140+
UNPROTECT(n_protected);
139141
});
140142
} catch (const unwind_exception& e) {
141143
release_protect(protect_);
142-
UNPROTECT(1);
144+
UNPROTECT(n_protected);
143145
throw e;
144146
}
145147
}

0 commit comments

Comments
 (0)