Rcpp Version 1.0.9
barrier.cpp
Go to the documentation of this file.
1 
2 // barrier.cpp: Rcpp R/C++ interface class library -- write barrier
3 //
4 // Copyright (C) 2010 - 2020 Dirk Eddelbuettel and Romain Francois
5 // Copyright (C) 2021 - 2022 Dirk Eddelbuettel, Romain Francois and IƱaki Ucar
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #define COMPILING_RCPP
23 
24 #define USE_RINTERNALS
25 #include <Rinternals.h>
26 #include <Rcpp/barrier.h>
27 #include "internal.h"
28 #include <algorithm>
29 #include <Rcpp/protection/Shield.h>
30 
31 // [[Rcpp::register]]
32 SEXP get_string_elt(SEXP x, R_xlen_t i) { // #nocov start
33  return STRING_ELT(x, i);
34 }
35 
36 // [[Rcpp::register]]
37 const char* char_get_string_elt(SEXP x, R_xlen_t i) {
38  return CHAR(STRING_ELT(x, i));
39 }
40 
41 // [[Rcpp::register]]
42 void set_string_elt(SEXP x, R_xlen_t i, SEXP value) {
43  SET_STRING_ELT(x, i, value);
44 }
45 
46 // [[Rcpp::register]]
47 void char_set_string_elt(SEXP x, R_xlen_t i, const char* value) {
48  SET_STRING_ELT(x, i, Rf_mkChar(value));
49 }
50 
51 // [[Rcpp::register]]
52 SEXP* get_string_ptr(SEXP x) {
53  return STRING_PTR(x);
54 }
55 
56 // [[Rcpp::register]]
57 SEXP get_vector_elt(SEXP x, R_xlen_t i) {
58  return VECTOR_ELT(x, i);
59 }
60 
61 // [[Rcpp::register]]
62 void set_vector_elt(SEXP x, R_xlen_t i, SEXP value) {
63  SET_VECTOR_ELT(x, i, value);
64 }
65 
66 // [[Rcpp::register]]
67 SEXP* get_vector_ptr(SEXP x) {
68  return VECTOR_PTR(x); // #nocov end
69 }
70 
71 // [[Rcpp::register]]
72 void* dataptr(SEXP x) {
73  return DATAPTR(x);
74 }
75 
76 // [[Rcpp::register]]
77 const char* char_nocheck(SEXP x) {
78  return CHAR(x);
79 }
80 
81 static bool Rcpp_cache_know = false;
82 static SEXP Rcpp_cache = R_NilValue;
83 
84 #define RCPP_HASH_CACHE_INDEX 4
85 #define RCPP_CACHE_SIZE 5
86 
87 #ifndef RCPP_HASH_CACHE_INITIAL_SIZE
88 #define RCPP_HASH_CACHE_INITIAL_SIZE 1024
89 #endif
90 
91 namespace Rcpp {
92 static SEXP Rcpp_precious = R_NilValue;
93 // [[Rcpp::register]]
94 void Rcpp_precious_init() {
95  Rcpp_precious = CONS(R_NilValue, R_NilValue); // set up
96  R_PreserveObject(Rcpp_precious); // and protect
97 }
98 // [[Rcpp::register]]
100  R_ReleaseObject(Rcpp_precious); // release resource
101 }
102 // [[Rcpp::register]]
103 SEXP Rcpp_precious_preserve(SEXP object) {
104  if (object == R_NilValue) {
105  return R_NilValue;
106  }
107  PROTECT(object);
108  SEXP cell = PROTECT(CONS(Rcpp_precious, CDR(Rcpp_precious)));
109  SET_TAG(cell, object);
110  SETCDR(Rcpp_precious, cell);
111  if (CDR(cell) != R_NilValue) {
112  SETCAR(CDR(cell), cell);
113  }
114  UNPROTECT(2);
115  return cell;
116 }
117 // [[Rcpp::register]]
118 void Rcpp_precious_remove(SEXP token) {
119  if (token == R_NilValue || TYPEOF(token) != LISTSXP) {
120  return;
121  }
122  SET_TAG(token, R_NilValue);
123  SEXP before = CAR(token);
124  SEXP after = CDR(token);
125  SETCDR(before, after);
126  if (after != R_NilValue) {
127  SETCAR(after, before);
128  }
129 }
130 }
131 
132 // only used for debugging
134  if (! Rcpp_cache_know) {
135 
136  SEXP getNamespaceSym = Rf_install("getNamespace"); // cannot be gc()'ed once in symbol table
137  Rcpp::Shield<SEXP> RcppString(Rf_mkString("Rcpp"));
138  Rcpp::Shield<SEXP> call(Rf_lang2(getNamespaceSym, RcppString));
139  Rcpp::Shield<SEXP> RCPP(Rf_eval(call, R_GlobalEnv));
140 
141  Rcpp_cache = Rf_findVarInFrame(RCPP, Rf_install(".rcpp_cache"));
142  Rcpp_cache_know = true;
143  }
144  return Rcpp_cache;
145 }
146 
147 namespace Rcpp {
148  namespace internal {
149  // [[Rcpp::register]]
150  SEXP get_Rcpp_namespace() {
151  return VECTOR_ELT(get_rcpp_cache() , 0);
152  }
153  }
154 }
155 
156 // [[Rcpp::register]]
158  return VECTOR_ELT(get_rcpp_cache(), 3);
159 }
160 
161 // [[Rcpp::register]]
162 SEXP rcpp_set_stack_trace(SEXP e) {
163  SET_VECTOR_ELT(get_rcpp_cache(), 3, e);
164  return R_NilValue;
165 }
166 
167 SEXP set_error_occured(SEXP cache, SEXP e) {
168  SET_VECTOR_ELT(cache, 1, e);
169  return R_NilValue;
170 }
171 
172 SEXP set_current_error(SEXP cache, SEXP e) {
173  SET_VECTOR_ELT(cache, 2, e);
174  return R_NilValue;
175 }
176 
178  SEXP getNamespaceSym = Rf_install("getNamespace"); // cannot be gc()'ed once in symbol table
179  Rcpp::Shield<SEXP> RcppString(Rf_mkString("Rcpp"));
180  Rcpp::Shield<SEXP> call(Rf_lang2(getNamespaceSym, RcppString));
181  Rcpp::Shield<SEXP> RCPP(Rf_eval(call, R_GlobalEnv));
182  Rcpp::Shield<SEXP> cache(Rf_allocVector(VECSXP, RCPP_CACHE_SIZE));
183 
184  // the Rcpp namespace
185  SET_VECTOR_ELT(cache, 0, RCPP);
186  set_error_occured(cache, Rf_ScalarLogical(FALSE)); // error occured
187  set_current_error(cache, R_NilValue); // current error
188  SET_VECTOR_ELT(cache, 3, R_NilValue); // stack trace
189  Rcpp::Shield<SEXP> tmp(Rf_allocVector(INTSXP, RCPP_HASH_CACHE_INITIAL_SIZE));
190  SET_VECTOR_ELT(cache, RCPP_HASH_CACHE_INDEX, tmp);
191  Rf_defineVar(Rf_install(".rcpp_cache"), cache, RCPP);
192 
193  return cache;
194 }
195 
196 // [[Rcpp::register]]
197 SEXP reset_current_error() { // #nocov start
198  SEXP cache = get_rcpp_cache();
199 
200  // error occured
201  set_error_occured(cache, Rf_ScalarLogical(FALSE));
202 
203  // current error
204  set_current_error(cache, R_NilValue);
205 
206  // stack trace
207  SET_VECTOR_ELT(cache, 3, R_NilValue);
208 
209  return R_NilValue;
210 }
211 
212 // [[Rcpp::register]]
214  SEXP err = VECTOR_ELT(get_rcpp_cache(), 1);
215  return LOGICAL(err)[0];
216 }
217 
218 // [[Rcpp::internal]]
219 SEXP rcpp_error_recorder(SEXP e) {
220  SEXP cache = get_rcpp_cache();
221 
222  // error occured
223  set_error_occured(cache, Rf_ScalarLogical(TRUE));
224 
225  // current error
226  set_current_error(cache, e);
227 
228  return R_NilValue;
229 }
230 
231 // [[Rcpp::register]]
233  return VECTOR_ELT(get_rcpp_cache(), 2); // #nocov end
234 }
235 
236 // [[Rcpp::register]]
237 int* get_cache(int m) {
238  SEXP cache = get_rcpp_cache();
239  SEXP hash_cache = VECTOR_ELT(cache, RCPP_HASH_CACHE_INDEX);
240  int n = Rf_length(hash_cache);
241  if (m > n) {
242  Rcpp::Shield<SEXP> new_hash_cache(Rf_allocVector(INTSXP, m));
243  hash_cache = new_hash_cache;
244  SET_VECTOR_ELT(cache,RCPP_HASH_CACHE_INDEX, hash_cache);
245  }
246  int *res = INTEGER(hash_cache);
247  std::fill(res, res+m, 0);
248  return res;
249 }
int error_occured()
Definition: barrier.cpp:213
SEXP * get_string_ptr(SEXP x)
Definition: barrier.cpp:52
void * dataptr(SEXP x)
Definition: barrier.cpp:72
SEXP init_Rcpp_cache()
Definition: barrier.cpp:177
#define RCPP_CACHE_SIZE
Definition: barrier.cpp:85
void char_set_string_elt(SEXP x, R_xlen_t i, const char *value)
Definition: barrier.cpp:47
const char * char_nocheck(SEXP x)
Definition: barrier.cpp:77
#define RCPP_HASH_CACHE_INDEX
Definition: barrier.cpp:84
SEXP set_current_error(SEXP cache, SEXP e)
Definition: barrier.cpp:172
const char * char_get_string_elt(SEXP x, R_xlen_t i)
Definition: barrier.cpp:37
SEXP * get_vector_ptr(SEXP x)
Definition: barrier.cpp:67
int * get_cache(int m)
Definition: barrier.cpp:237
SEXP get_rcpp_cache()
Definition: barrier.cpp:133
SEXP get_vector_elt(SEXP x, R_xlen_t i)
Definition: barrier.cpp:57
#define RCPP_HASH_CACHE_INITIAL_SIZE
Definition: barrier.cpp:88
SEXP reset_current_error()
Definition: barrier.cpp:197
SEXP rcpp_error_recorder(SEXP e)
Definition: barrier.cpp:219
static bool Rcpp_cache_know
Definition: barrier.cpp:81
SEXP get_string_elt(SEXP x, R_xlen_t i)
Definition: barrier.cpp:32
void set_vector_elt(SEXP x, R_xlen_t i, SEXP value)
Definition: barrier.cpp:62
SEXP rcpp_get_current_error()
Definition: barrier.cpp:232
static SEXP Rcpp_cache
Definition: barrier.cpp:82
SEXP set_error_occured(SEXP cache, SEXP e)
Definition: barrier.cpp:167
SEXP rcpp_get_stack_trace()
Definition: barrier.cpp:157
SEXP rcpp_set_stack_trace(SEXP e)
Definition: barrier.cpp:162
void set_string_elt(SEXP x, R_xlen_t i, SEXP value)
Definition: barrier.cpp:42
attribute_hidden SEXP get_Rcpp_namespace()
Definition: routines.h:121
Rcpp API.
Definition: algo.h:28
attribute_hidden void Rcpp_precious_init()
Definition: routines.h:142
attribute_hidden SEXP Rcpp_precious_preserve(SEXP object)
Definition: routines.h:152
attribute_hidden void Rcpp_precious_remove(SEXP token)
Definition: routines.h:157
attribute_hidden void Rcpp_precious_teardown()
Definition: routines.h:147
static SEXP Rcpp_precious
Definition: barrier.cpp:92